You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by iv...@apache.org on 2010/08/31 23:35:32 UTC
svn commit: r991339 - in /wicket/trunk/wicket/src:
main/java/org/apache/wicket/ main/java/org/apache/wicket/mock/
main/java/org/apache/wicket/request/mapper/
main/java/org/apache/wicket/request/resource/
main/java/org/apache/wicket/settings/ test/java/...
Author: ivaynberg
Date: Tue Aug 31 21:35:31 2010
New Revision: 991339
URL: http://svn.apache.org/viewvc?rev=991339&view=rev
Log:
applied 3021 patch
Issue: WICKET-3021
Modified:
wicket/trunk/wicket/src/main/java/org/apache/wicket/SystemMapper.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/mock/MockApplication.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/BasicResourceReferenceMapper.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/ResourceReferenceMapper.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResourceReference.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceReference.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/IResourceSettings.java
wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/Settings.java
wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/BasicResourceReferenceMapperTest.java
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/SystemMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/SystemMapper.java?rev=991339&r1=991338&r2=991339&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/SystemMapper.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/SystemMapper.java Tue Aug 31 21:35:31 2010
@@ -24,7 +24,7 @@ import org.apache.wicket.request.mapper.
import org.apache.wicket.request.mapper.ResourceReferenceMapper;
import org.apache.wicket.request.mapper.parameter.PageParametersEncoder;
import org.apache.wicket.util.IProvider;
-
+import org.apache.wicket.util.ValueProvider;
/**
* Mapper that encapsulates mappers that are necessary for Wicket to function.
@@ -34,20 +34,35 @@ import org.apache.wicket.util.IProvider;
*/
public class SystemMapper extends CompoundRequestMapper
{
+ private final Application application;
+
/**
* Constructor
*/
public SystemMapper(Application application)
{
+ this.application = application;
add(RestartResponseAtInterceptPageException.MAPPER);
add(new HomePageMapper());
add(new PageInstanceMapper());
add(new BookmarkableMapper());
add(new ResourceReferenceMapper(new PageParametersEncoder(),
- new ParentFolderPlaceholderProvider(application)));
+ new ParentFolderPlaceholderProvider(application),
+ useTimestampsProvider()));
add(new BufferedResponseMapper());
}
+ private IProvider<Boolean> useTimestampsProvider()
+ {
+ return new IProvider<Boolean>()
+ {
+ public Boolean get()
+ {
+ return application.getResourceSettings().getUseTimestampOnResources();
+ }
+ };
+ }
+
private static class ParentFolderPlaceholderProvider implements IProvider<String>
{
private final Application application;
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/mock/MockApplication.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/mock/MockApplication.java?rev=991339&r1=991338&r2=991339&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/mock/MockApplication.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/mock/MockApplication.java Tue Aug 31 21:35:31 2010
@@ -62,6 +62,7 @@ public class MockApplication extends Web
super.internalInit();
setSessionStoreProvider(new MockSessionStoreProvider());
setPageManagerProvider(new MockPageManagerProvider());
+ getResourceSettings().setUseTimestampOnResources(false);
}
private static class MockSessionStoreProvider implements IProvider<ISessionStore>
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/BasicResourceReferenceMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/BasicResourceReferenceMapper.java?rev=991339&r1=991338&r2=991339&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/BasicResourceReferenceMapper.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/BasicResourceReferenceMapper.java Tue Aug 31 21:35:31 2010
@@ -22,47 +22,48 @@ import org.apache.wicket.request.Url;
import org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler;
import org.apache.wicket.request.mapper.parameter.IPageParametersEncoder;
import org.apache.wicket.request.mapper.parameter.PageParameters;
-import org.apache.wicket.request.mapper.parameter.PageParametersEncoder;
import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.util.IProvider;
import org.apache.wicket.util.lang.WicketObjects;
+import org.apache.wicket.util.time.Time;
+
+import java.util.List;
+import java.util.StringTokenizer;
/**
* Generic {@link ResourceReference} encoder that encodes and decodes non-mounted
* {@link ResourceReference}s.
* <p>
* Decodes and encodes the following URLs:
- *
+ *
* <pre>
* /wicket/resource/org.apache.wicket.ResourceScope/name
* /wicket/resource/org.apache.wicket.ResourceScope/name?en
* /wicket/resource/org.apache.wicket.ResourceScope/name?-style
* /wicket/resource/org.apache.wicket.ResourceScope/resource/name.xyz?en_EN-style
* </pre>
- *
+ *
* @author Matej Knopp
* @author igor.vaynberg
*/
class BasicResourceReferenceMapper extends AbstractResourceReferenceMapper
{
+ private static final String TIMESTAMP_PREFIX = "-ts";
private final IPageParametersEncoder pageParametersEncoder;
+ // if true, timestamps should be added to resource names
+ private final IProvider<Boolean> timestamps;
+
/**
* Construct.
- *
+ *
* @param pageParametersEncoder
* @param relativePathPartEscapeSequence
*/
- public BasicResourceReferenceMapper(IPageParametersEncoder pageParametersEncoder)
+ public BasicResourceReferenceMapper(IPageParametersEncoder pageParametersEncoder, IProvider<Boolean> timestamps)
{
this.pageParametersEncoder = pageParametersEncoder;
- }
-
- /**
- * Construct.
- */
- public BasicResourceReferenceMapper()
- {
- this(new PageParametersEncoder());
+ this.timestamps = timestamps;
}
/**
@@ -73,17 +74,30 @@ class BasicResourceReferenceMapper exten
Url url = request.getUrl();
if (url.getSegments().size() >= 4 &&
- urlStartsWith(url, getContext().getNamespace(), getContext().getResourceIdentifier()))
+ urlStartsWith(url, getContext().getNamespace(), getContext().getResourceIdentifier()))
{
String className = url.getSegments().get(2);
StringBuilder name = new StringBuilder();
- for (int i = 3; i < url.getSegments().size(); ++i)
+ int segmentsSize = url.getSegments().size();
+ for (int i = 3; i < segmentsSize; ++i)
{
+ String segment = url.getSegments().get(i);
+
+ // if timestamps are enabled the last segment (=resource name)
+ // should be stripped of timestamps
+ if (isTimestampsEnabled() && i + 1 == segmentsSize)
+ {
+ // The last segment eventually contains a timestamp which we have to remove
+ // resource lookup will not care about timestamp but always deliver the
+ // most current version of the resource. After all this whole timestamp
+ // thing is about caching on proxies and browsers but does not affect wicket.
+ segment = stripTimestampFromResourceName(segment);
+ }
if (name.length() > 0)
{
name.append("/");
}
- name.append(url.getSegments().get(i));
+ name.append(segment);
}
ResourceReference.UrlAttributes attributes = getResourceReferenceAttributes(url);
@@ -108,6 +122,50 @@ class BasicResourceReferenceMapper exten
return null;
}
+ private boolean isTimestampsEnabled()
+ {
+ return timestamps.get();
+ }
+
+ /**
+ * strip timestamp information from resource name
+ *
+ * @param resourceName
+ * @return
+ */
+
+ private String stripTimestampFromResourceName(final String resourceName)
+ {
+ int pos = resourceName.lastIndexOf('.');
+
+ final String fullname = pos == -1 ? resourceName : resourceName.substring(0, pos);
+ final String extension = pos == -1 ? null : resourceName.substring(pos);
+
+ pos = fullname.lastIndexOf(TIMESTAMP_PREFIX);
+
+ if (pos != -1)
+ {
+ final String timestamp = fullname.substring(pos + TIMESTAMP_PREFIX.length());
+ final String basename = fullname.substring(0, pos);
+
+ try
+ {
+ Long.parseLong(timestamp); // just check the timestamp is numeric
+
+ // create filename without timestamp for resource lookup
+ return extension == null ? basename : basename + extension;
+ }
+ catch (NumberFormatException e)
+ {
+ // some strange case of coincidence where the filename contains the timestamp prefix
+ // but the timestamp itself is non-numeric - we interpret this situation as
+ // "file has no timestamp"
+
+ }
+ }
+ return resourceName;
+ }
+
protected Class<?> resolveClass(String name)
{
return WicketObjects.resolveClass(name);
@@ -128,14 +186,48 @@ class BasicResourceReferenceMapper exten
ResourceReferenceRequestHandler referenceRequestHandler = (ResourceReferenceRequestHandler)requestHandler;
ResourceReference reference = referenceRequestHandler.getResourceReference();
Url url = new Url();
- url.getSegments().add(getContext().getNamespace());
- url.getSegments().add(getContext().getResourceIdentifier());
- url.getSegments().add(getClassName(reference.getScope()));
- String nameParts[] = reference.getName().split("/");
- for (String name : nameParts)
+
+ List<String> segments = url.getSegments();
+ segments.add(getContext().getNamespace());
+ segments.add(getContext().getResourceIdentifier());
+ segments.add(getClassName(reference.getScope()));
+
+ StringTokenizer tokens = new StringTokenizer(reference.getName(), "/");
+
+ while (tokens.hasMoreTokens())
{
- url.getSegments().add(name);
+ String token = tokens.nextToken();
+
+ // on the last component of the resource path add the timestamp
+ if (isTimestampsEnabled() && tokens.hasMoreTokens() == false)
+ {
+ // get last modification of resource
+ Time lastModified = reference.getLastModified();
+
+ // if resource provides a timestamp we include it in resource name
+ if (lastModified != null)
+ {
+ // check if resource name has extension
+ int extensionAt = token.lastIndexOf('.');
+
+ // create timestamped version of filename:
+ //
+ // filename := [basename][timestamp-prefix][last-modified-milliseconds](.extension)
+ //
+ StringBuilder filename = new StringBuilder();
+ filename.append(extensionAt == -1 ? token : token.substring(0, extensionAt));
+ filename.append(TIMESTAMP_PREFIX);
+ filename.append(lastModified.getMilliseconds());
+
+ if (extensionAt != -1)
+ filename.append(token.substring(extensionAt));
+
+ token = filename.toString();
+ }
+ }
+ segments.add(token);
}
+
encodeResourceReferenceAttributes(url, reference);
PageParameters parameters = referenceRequestHandler.getPageParameters();
if (parameters != null)
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/ResourceReferenceMapper.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/ResourceReferenceMapper.java?rev=991339&r1=991338&r2=991339&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/ResourceReferenceMapper.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/mapper/ResourceReferenceMapper.java Tue Aug 31 21:35:31 2010
@@ -44,18 +44,12 @@ public class ResourceReferenceMapper ext
*
* @param pageParametersEncoder
* @param parentPathPartEscapeSequence
+ * @param timestamps
*/
public ResourceReferenceMapper(IPageParametersEncoder pageParametersEncoder,
- IProvider<String> parentPathPartEscapeSequence)
+ IProvider<String> parentPathPartEscapeSequence,
+ IProvider<Boolean> useTimestamps)
{
- super(new BasicResourceReferenceMapper(pageParametersEncoder), parentPathPartEscapeSequence);
- }
-
- /**
- * Construct.
- */
- public ResourceReferenceMapper()
- {
- this(new PageParametersEncoder(), new NullProvider<String>());
+ super(new BasicResourceReferenceMapper(pageParametersEncoder, useTimestamps), parentPathPartEscapeSequence);
}
}
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResourceReference.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResourceReference.java?rev=991339&r1=991338&r2=991339&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResourceReference.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/PackageResourceReference.java Tue Aug 31 21:35:31 2010
@@ -19,11 +19,13 @@ package org.apache.wicket.request.resour
import java.util.Locale;
import java.util.concurrent.ConcurrentMap;
+import org.apache.wicket.Application;
import org.apache.wicket.Session;
-import org.apache.wicket.ThreadContext;
import org.apache.wicket.util.lang.Generics;
import org.apache.wicket.util.lang.Packages;
+import org.apache.wicket.util.resource.IResourceStream;
import org.apache.wicket.util.resource.locator.IResourceStreamLocator;
+import org.apache.wicket.util.time.Time;
public class PackageResourceReference extends ResourceReference
{
@@ -33,7 +35,7 @@ public class PackageResourceReference ex
/**
* Construct.
- *
+ *
* @param key
*/
public PackageResourceReference(final Key key)
@@ -43,7 +45,7 @@ public class PackageResourceReference ex
/**
* Construct.
- *
+ *
* @param scope
* @param name
* @param locale
@@ -58,7 +60,7 @@ public class PackageResourceReference ex
/**
* Construct.
- *
+ *
* @param scope
* @param name
*/
@@ -69,7 +71,7 @@ public class PackageResourceReference ex
/**
* Construct.
- *
+ *
* @param name
*/
public PackageResourceReference(final String name)
@@ -86,78 +88,85 @@ public class PackageResourceReference ex
return new PackageResource(getScope(), getName(), getLocale(), getStyle(), getVariation());
}
- /**
- *
- * @param locator
- * @param locale
- * @param style
- * @param variation
- * @return
- */
- private UrlAttributes testResource(final IResourceStreamLocator locator, final Locale locale,
- final String style, final String variation)
+ private StreamInfo lookupStream(IResourceStreamLocator locator,
+ Locale locale, String style, String variation)
{
String absolutePath = Packages.absolutePath(getScope(), getName());
+ IResourceStream stream = locator.locate(getScope(), absolutePath, style, variation, locale, null, true);
- if (locator.locate(getScope(), absolutePath, style, variation, locale, null, true) != null)
- {
- return new UrlAttributes(locale, style, variation);
- }
- else
- {
+ if (stream == null)
return null;
- }
+
+ return new StreamInfo(stream, locale, style, variation);
}
- /**
- *
- * @param locale
- * @param style
- * @param variation
- * @return
- */
- private UrlAttributes getUrlAttributes(final Locale locale, final String style,
- final String variation)
+ private StreamInfo lookupStream(Locale locale, String style, String variation)
{
- IResourceStreamLocator locator = ThreadContext.getApplication()
- .getResourceSettings()
- .getResourceStreamLocator();
+ IResourceStreamLocator locator = Application.get()
+ .getResourceSettings()
+ .getResourceStreamLocator();
- UrlAttributes res = testResource(locator, locale, style, variation);
- if (res == null)
- {
- res = testResource(locator, locale, style, null);
- }
- if (res == null)
+ StreamInfo info;
+
+ info = lookupStream(locator, locale, style, variation);
+ if (info == null)
{
- res = testResource(locator, locale, null, variation);
+ info = lookupStream(locator, locale, style, null);
}
- if (res == null)
+ if (info == null)
{
- res = testResource(locator, null, style, variation);
+ info = lookupStream(locator, locale, null, variation);
}
- if (res == null)
+ if (info == null)
{
- res = testResource(locator, locale, null, null);
+ info = lookupStream(locator, null, style, variation);
}
- if (res == null)
+ if (info == null)
{
- res = testResource(locator, null, style, null);
+ info = lookupStream(locator, locale, null, null);
}
- if (res == null)
+ if (info == null)
{
- res = testResource(locator, null, null, variation);
+ info = lookupStream(locator, null, style, null);
}
- if (res == null)
+ if (info == null)
{
- res = new UrlAttributes(null, null, null);
+ info = lookupStream(locator, null, null, variation);
}
- return res;
+ return info;
+ }
+
+ private UrlAttributes getUrlAttributes(Locale locale, String style, String variation)
+ {
+ StreamInfo info = lookupStream(locale, style, variation);
+
+ if (info != null)
+ return new UrlAttributes(info.locale, info.style, info.variation);
+
+ return new UrlAttributes(null, null, null);
+ }
+
+ private Locale getCurrentLocale()
+ {
+ return getLocale() != null ? getLocale() : Session.get().getLocale();
+ }
+
+ private String getCurrentStyle()
+ {
+ return getStyle() != null ? getStyle() : Session.get().getStyle();
+ }
+
+ @Override
+ public Time getLastModified()
+ {
+ StreamInfo info = lookupStream(getCurrentLocale(), getCurrentStyle(), getVariation());
+
+ if (info == null)
+ return null;
+
+ return info.stream.lastModifiedTime();
}
- /**
- * @see org.apache.wicket.request.resource.ResourceReference#getUrlAttributes()
- */
@Override
public UrlAttributes getUrlAttributes()
{
@@ -165,12 +174,12 @@ public class PackageResourceReference ex
String style = getStyle() != null ? getStyle() : Session.get().getStyle();
String variation = getVariation();
+ UrlAttributes key = new UrlAttributes(locale, style, variation);
+
if (urlAttributesCacheMap == null)
{
urlAttributesCacheMap = Generics.newConcurrentHashMap();
}
-
- UrlAttributes key = new UrlAttributes(locale, style, variation);
UrlAttributes value = urlAttributesCacheMap.get(key);
if (value == null)
{
@@ -180,4 +189,20 @@ public class PackageResourceReference ex
return value;
}
+
+ private static class StreamInfo
+ {
+ public final IResourceStream stream;
+ public final Locale locale;
+ public final String style;
+ public final String variation;
+
+ public StreamInfo(IResourceStream stream, Locale locale, String style, String variation)
+ {
+ this.stream = stream;
+ this.locale = locale;
+ this.style = style;
+ this.variation = variation;
+ }
+ }
}
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceReference.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceReference.java?rev=991339&r1=991338&r2=991339&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceReference.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/request/resource/ResourceReference.java Tue Aug 31 21:35:31 2010
@@ -23,6 +23,7 @@ import org.apache.wicket.Application;
import org.apache.wicket.util.lang.Args;
import org.apache.wicket.util.lang.Objects;
import org.apache.wicket.util.lang.WicketObjects;
+import org.apache.wicket.util.time.Time;
/**
* Reference to a resource. Can be used to reference global resources.
@@ -57,7 +58,7 @@ public abstract class ResourceReference
/**
* Creates new {@link ResourceReference} instance.
- *
+ *
* @param scope
* mandatory parameter
* @param name
@@ -154,7 +155,7 @@ public abstract class ResourceReference
/**
* Can be used to disable registering certain resource references in
* {@link ResourceReferenceRegistry}.
- *
+ *
* @return <code>true</code> if this reference can be registered, <code>false</code> otherwise.
*/
public boolean canBeRegistered()
@@ -163,6 +164,17 @@ public abstract class ResourceReference
}
/**
+ * return the last modification date of the referred resource
+ * <p/>
+ *
+ * @return last modification time or <code>null</code> if not supported
+ */
+ public Time getLastModified()
+ {
+ return null;
+ }
+
+ /**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -299,18 +311,18 @@ public abstract class ResourceReference
/**
* Construct.
- *
+ *
* @param reference
- */
+ */
public Key(final ResourceReference reference)
- {
+ {
this(reference.getScope().getName(), reference.getName(), reference.getLocale(),
reference.getStyle(), reference.getVariation());
}
/**
* Construct.
- *
+ *
* @param scope
* @param name
* @param locale
@@ -338,8 +350,8 @@ public abstract class ResourceReference
{
if (this == obj)
{
- return true;
- }
+ return true;
+ }
if (obj instanceof Key == false)
{
return false;
@@ -352,7 +364,7 @@ public abstract class ResourceReference
Objects.equal(variation, that.variation);
}
- /**
+ /**
* @see java.lang.Object#hashCode()
*/
@Override
@@ -363,13 +375,13 @@ public abstract class ResourceReference
/**
* Gets scope.
- *
+ *
* @return scope
- */
+ */
public final String getScope()
- {
+ {
return scope;
- }
+ }
/**
* @return Assuming scope ist a fully qualified class name, than get the associated class
@@ -377,11 +389,11 @@ public abstract class ResourceReference
public final Class<?> getScopeClass()
{
return WicketObjects.resolveClass(scope);
- }
+}
/**
* Gets name.
- *
+ *
* @return name
*/
public final String getName()
@@ -391,7 +403,7 @@ public abstract class ResourceReference
/**
* Gets locale.
- *
+ *
* @return locale
*/
public final Locale getLocale()
@@ -401,7 +413,7 @@ public abstract class ResourceReference
/**
* Gets style.
- *
+ *
* @return style
*/
public final String getStyle()
@@ -411,7 +423,7 @@ public abstract class ResourceReference
/**
* Gets variation.
- *
+ *
* @return variation
*/
public final String getVariation()
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/IResourceSettings.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/IResourceSettings.java?rev=991339&r1=991338&r2=991339&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/IResourceSettings.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/IResourceSettings.java Tue Aug 31 21:35:31 2010
@@ -365,4 +365,53 @@ public interface IResourceSettings
* character sequence which must not be ambiguous within urls
*/
void setParentFolderPlaceholder(String sequence);
+
+ /**
+ * Control the usage of timestamps on resources
+ * <p/>
+ * Normally the resource names won't change when the resource ifself changes, for example when you add a new
+ * style to your CSS sheet. This can be very annoying as browsers (and proxies) usally cache resources
+ * in their cache based on the filename and therefore won't update. Unless you change the file name of the
+ * resource, force a reload or clear the browser's cache the page will still render with your old CSS.
+ * <p/>
+ * Depending on HTTP response headers like 'Last-Modified' and 'Cache' automatic cache
+ * invalidation can take very, very long or neven happen at all.
+ * <p/>
+ * Enabling timestamps on resources will inject the last modification time of the resource into
+ * the filename (the name will look something like 'style-ts1282915831000.css' where the large number is
+ * the last modified date in milliseconds and '-ts' is a prefix to avoid conflicts with
+ * filenames that already contain a number before their extension.
+ * *
+ * <p/>
+ * Since browsers and proxies use the filename of the resource as a cache key the changed filename will
+ * not hit the cache and the page gets rendered with the changed file.
+ * <p/>
+ * @return <code>true</code> if timestamps are enabled
+ */
+ boolean getUseTimestampOnResources();
+
+ /**
+ * Control the usage of timestamps on resources
+ * <p/>
+ * Normally the resource names won't change when the resource ifself changes, for example when you add a new
+ * style to your CSS sheet. This can be very annoying as browsers (and proxies) usally cache resources
+ * in their cache based on the filename and therefore won't update. Unless you change the file name of the
+ * resource, force a reload or clear the browser's cache the page will still render with your old CSS.
+ * <p/>
+ * Depending on HTTP response headers like 'Last-Modified' and 'Cache' automatic cache
+ * invalidation can take very, very long or neven happen at all.
+ * <p/>
+ * Enabling timestamps on resources will inject the last modification time of the resource into
+ * the filename (the name will look something like 'style-ts1282915831000.css' where the large number is
+ * the last modified date in milliseconds and '-ts' is a prefix to avoid conflicts with
+ * filenames that already contain a number before their extension.
+ * *
+ * <p/>
+ * Since browsers and proxies use the filename of the resource as a cache key the changed filename will
+ * not hit the cache and the page gets rendered with the changed file.
+ * <p/>
+ *
+ * @param enable <code>true</code> for using timestamps on resource names
+ */
+ void setUseTimestampOnResources(boolean enable);
}
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/Settings.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/Settings.java?rev=991339&r1=991338&r2=991339&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/Settings.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/settings/Settings.java Tue Aug 31 21:35:31 2010
@@ -316,6 +316,9 @@ public final class Settings
/** escape string for '..' within resource keys */
private String parentFolderPlaceholder = null;
+ // use timestamps on resource file names
+ private boolean useTimestampOnResourcesName = true;
+
/** Default cache duration */
private int defaultCacheDuration = 3600;
@@ -1452,4 +1455,20 @@ public final class Settings
{
markupFactory = factory;
}
+
+ /**
+ * @see IResourceSettings#getUseTimestampOnResources()
+ */
+ public boolean getUseTimestampOnResources()
+ {
+ return useTimestampOnResourcesName;
+ }
+
+ /**
+ * @see org.apache.wicket.settings.IResourceSettings#setUseTimestampOnResources(boolean)
+ */
+ public void setUseTimestampOnResources(boolean useTimestampOnResourcesName)
+ {
+ this.useTimestampOnResourcesName = useTimestampOnResourcesName;
+ }
}
Modified: wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/BasicResourceReferenceMapperTest.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/BasicResourceReferenceMapperTest.java?rev=991339&r1=991338&r2=991339&view=diff
==============================================================================
--- wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/BasicResourceReferenceMapperTest.java (original)
+++ wicket/trunk/wicket/src/test/java/org/apache/wicket/request/mapper/BasicResourceReferenceMapperTest.java Tue Aug 31 21:35:31 2010
@@ -22,12 +22,16 @@ import org.apache.wicket.request.IReques
import org.apache.wicket.request.Url;
import org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler;
import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.mapper.parameter.PageParametersEncoder;
+import org.apache.wicket.util.ValueProvider;
/**
* @author Matej Knopp
*/
public class BasicResourceReferenceMapperTest extends AbstractResourceReferenceMapperTest
{
+ private static final ValueProvider<Boolean> TIMESTAMPS = new ValueProvider<Boolean>(false);
+
/**
* Construct.
*/
@@ -35,7 +39,7 @@ public class BasicResourceReferenceMappe
{
}
- private final BasicResourceReferenceMapper encoder = new BasicResourceReferenceMapper()
+ private final BasicResourceReferenceMapper encoder = new BasicResourceReferenceMapper(new PageParametersEncoder(), TIMESTAMPS)
{
@Override
protected IMapperContext getContext()