| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.wicket.request.resource.caching.version; |
| |
| import java.io.Serializable; |
| import java.util.Collections; |
| import java.util.Map; |
| import java.util.regex.Pattern; |
| |
| import org.apache.wicket.request.resource.caching.IStaticCacheableResource; |
| import org.apache.wicket.util.collections.MostRecentlyUsedMap; |
| import org.apache.wicket.util.lang.Args; |
| |
| /** |
| * Caches the results of a delegating {@link IResourceVersion} instance |
| * in a member variable. The cache will be valid for the lifetime of |
| * this instance. It will expire the oldest entries if the maximum number |
| * of entries is exceeded. |
| * |
| * @author Peter Ertl |
| * |
| * @since 1.5 |
| */ |
| public class CachingResourceVersion implements IResourceVersion |
| { |
| /** |
| * default maximum entries in cache |
| */ |
| private static final int DEFAULT_MAX_CACHE_ENTRIES = 5000; |
| |
| /** |
| * null value replacement holder for storing <code>null</code> in the map |
| */ |
| private static final String NULL_VALUE = "null"; |
| |
| /** |
| * delegating resource version provider |
| */ |
| private final IResourceVersion delegate; |
| |
| /** |
| * cache for resource versions |
| */ |
| private final Map<Serializable, String> cache; |
| |
| /** |
| * create version cache |
| * <p/> |
| * the cache will accept up to {@value #DEFAULT_MAX_CACHE_ENTRIES} before |
| * evicting the oldest entries. |
| * |
| * @param delegate |
| * delegating resource version provider |
| */ |
| public CachingResourceVersion(IResourceVersion delegate) |
| { |
| this(delegate, DEFAULT_MAX_CACHE_ENTRIES); |
| } |
| |
| /** |
| * create version cache |
| * <p/> |
| * the cache will accept a maximum number of entries specified |
| * by <code>maxEntries</code> before evicting the oldest entries. |
| * |
| * @param delegate |
| * resource version provider |
| * @param maxEntries |
| * maximum number of cache entries |
| */ |
| public CachingResourceVersion(IResourceVersion delegate, int maxEntries) |
| { |
| if (maxEntries < 1) |
| { |
| throw new IllegalArgumentException("maxEntries must be greater than zero"); |
| } |
| |
| this.delegate = Args.notNull(delegate, "delegate"); |
| this.cache = Collections.synchronizedMap( |
| new MostRecentlyUsedMap<Serializable, String>(maxEntries)); |
| } |
| |
| @Override |
| public String getVersion(IStaticCacheableResource resource) |
| { |
| // get unique cache key for resource reference |
| final Serializable key = resource.getCacheKey(); |
| |
| // if key can not be determined do not cache |
| if(key == null) |
| { |
| return null; |
| } |
| |
| // lookup version in cache |
| String version = cache.get(key); |
| |
| // if not found |
| if (version == null) |
| { |
| // get version from delegate |
| version = delegate.getVersion(resource); |
| |
| // replace null values with holder |
| if (version == null) |
| { |
| version = NULL_VALUE; |
| } |
| // update cache |
| cache.put(key, version); |
| } |
| |
| //noinspection StringEquality |
| if (version == NULL_VALUE) |
| { |
| // replace holder with null value |
| return null; |
| } |
| |
| // return version string |
| return version; |
| } |
| |
| @Override |
| public Pattern getVersionPattern() { |
| return delegate.getVersionPattern(); |
| } |
| |
| /** |
| * remove cacheable resource from cache |
| * |
| * @param resource |
| * cacheable resource |
| */ |
| public void invalidate(IStaticCacheableResource resource) |
| { |
| // get cache key for resource reference |
| final Serializable key = Args.notNull(resource, "resource").getCacheKey(); |
| |
| // if key is available purge cache entry |
| if(key != null) |
| { |
| cache.remove(key); |
| } |
| } |
| |
| public void invalidateAll() { |
| cache.clear(); |
| } |
| } |