You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2011/10/20 02:32:29 UTC
svn commit: r1186581 - in /tapestry/tapestry5/trunk:
tapestry-core/src/main/java/org/apache/tapestry5/
tapestry-core/src/main/java/org/apache/tapestry5/internal/services/
tapestry-core/src/main/java/org/apache/tapestry5/services/
tapestry-core/src/test...
Author: hlship
Date: Thu Oct 20 00:32:28 2011
New Revision: 1186581
URL: http://svn.apache.org/viewvc?rev=1186581&view=rev
Log:
TAP5-1710: AssetSource service can retain large numbers of Asset and Resource objects
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/Asset.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetSourceImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClasspathAssetFactory.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ContextAssetFactory.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetFactoryTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/Asset.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/Asset.java?rev=1186581&r1=1186580&r2=1186581&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/Asset.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/Asset.java Thu Oct 20 00:32:28 2011
@@ -25,6 +25,8 @@ import org.apache.tapestry5.ioc.Resource
* <p/>
* Release 5.1.0.0 introduced {@link org.apache.tapestry5.Asset2}, which extends this interface with an additional
* method.
+ *
+ * @see org.apache.tapestry5.services.AssetPathConverter
*/
public interface Asset
{
@@ -34,7 +36,7 @@ public interface Asset
* <p/>
* Tapestry's built-in asset types (context and classpath) always incorporate a version number as part of the path,
* and alternate implementations are encouraged to do so as well. In addition, Tapestry ensures that context and
- * classpath assets have a far-future expires header (to ensure aggresive caching by the client).
+ * classpath assets have a far-future expires header (to ensure aggressive caching by the client).
* <p/>
*/
String toClientURL();
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetSourceImpl.java?rev=1186581&r1=1186580&r2=1186581&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetSourceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetSourceImpl.java Thu Oct 20 00:32:28 2011
@@ -14,11 +14,9 @@
package org.apache.tapestry5.internal.services;
-import java.util.Locale;
-import java.util.Map;
-
import org.apache.tapestry5.Asset;
import org.apache.tapestry5.internal.AssetConstants;
+import org.apache.tapestry5.internal.TapestryInternalUtils;
import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
@@ -28,6 +26,10 @@ import org.apache.tapestry5.ioc.util.Str
import org.apache.tapestry5.services.AssetFactory;
import org.apache.tapestry5.services.AssetSource;
+import java.lang.ref.SoftReference;
+import java.util.Locale;
+import java.util.Map;
+
@SuppressWarnings("all")
public class AssetSourceImpl implements AssetSource
{
@@ -37,13 +39,13 @@ public class AssetSourceImpl implements
private final Map<String, Resource> prefixToRootResource = CollectionFactory.newMap();
- private final Map<Resource, Asset> cache = CollectionFactory.newConcurrentMap();
+ private final Map<Resource, SoftReference<Asset>> cache = CollectionFactory.newWeakHashMap();
private final SymbolSource symbolSource;
public AssetSourceImpl(ThreadLocale threadLocale,
- Map<String, AssetFactory> configuration, SymbolSource symbolSource)
+ Map<String, AssetFactory> configuration, SymbolSource symbolSource)
{
this.threadLocale = threadLocale;
this.symbolSource = symbolSource;
@@ -137,14 +139,14 @@ public class AssetSourceImpl implements
return getAssetForResource(localized);
}
- private Asset getAssetForResource(Resource resource)
+ private synchronized Asset getAssetForResource(Resource resource)
{
- Asset result = cache.get(resource);
+ Asset result = TapestryInternalUtils.getAndDeref(cache, resource);
if (result == null)
{
result = createAssetFromResource(resource);
- cache.put(resource, result);
+ cache.put(resource, new SoftReference(result));
}
return result;
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClasspathAssetFactory.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClasspathAssetFactory.java?rev=1186581&r1=1186580&r2=1186581&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClasspathAssetFactory.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClasspathAssetFactory.java Thu Oct 20 00:32:28 2011
@@ -16,14 +16,12 @@ package org.apache.tapestry5.internal.se
import org.apache.tapestry5.Asset;
import org.apache.tapestry5.ioc.Resource;
+import org.apache.tapestry5.ioc.annotations.Marker;
import org.apache.tapestry5.ioc.internal.util.ClasspathResource;
-import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.services.AssetFactory;
import org.apache.tapestry5.services.AssetPathConverter;
import org.apache.tapestry5.services.ClasspathAssetAliasManager;
-import org.apache.tapestry5.services.InvalidationListener;
-
-import java.util.Map;
+import org.apache.tapestry5.services.ClasspathProvider;
/**
* Generates Assets for files on the classpath. Caches generated client URLs internally, and clears that cache when
@@ -31,14 +29,13 @@ import java.util.Map;
*
* @see AssetDispatcher
*/
-public class ClasspathAssetFactory implements AssetFactory, InvalidationListener
+@Marker(ClasspathProvider.class)
+public class ClasspathAssetFactory implements AssetFactory
{
private final ResourceDigestManager digestManager;
private final ClasspathAssetAliasManager aliasManager;
- private final Map<Resource, String> resourceToDefaultPath = CollectionFactory.newConcurrentMap();
-
private final ClasspathResource rootResource;
private final AssetPathConverter converter;
@@ -57,21 +54,9 @@ public class ClasspathAssetFactory imple
invariant = converter.isInvariant();
}
- public void objectWasInvalidated()
- {
- resourceToDefaultPath.clear();
- }
-
private String clientURL(Resource resource)
{
- String defaultPath = resourceToDefaultPath.get(resource);
-
- if (defaultPath == null)
- {
- defaultPath = buildDefaultPath(resource);
-
- resourceToDefaultPath.put(resource, defaultPath);
- }
+ String defaultPath = buildDefaultPath(resource);
return converter.convertAssetPath(defaultPath);
}
@@ -94,9 +79,22 @@ public class ClasspathAssetFactory imple
return aliasManager.toClientURL(path);
}
- public Asset createAsset(final Resource resource)
+ public Asset createAsset(Resource resource)
+ {
+ if (invariant)
+ {
+ return createInvariantAsset(resource);
+ }
+
+ return createVariantAsset(resource);
+ }
+
+ /**
+ * A variant asset must pass the resource through clientURL() all the time; very inefficient.
+ */
+ private Asset createVariantAsset(final Resource resource)
{
- return new AbstractAsset(invariant)
+ return new AbstractAsset(false)
{
public Resource getResource()
{
@@ -110,6 +108,32 @@ public class ClasspathAssetFactory imple
};
}
+ /**
+ * An invariant asset is normal, and only needs to compute the clientURL for the resource once.
+ */
+ private Asset createInvariantAsset(final Resource resource)
+ {
+ return new AbstractAsset(true)
+ {
+ private String clientURL;
+
+ public Resource getResource()
+ {
+ return resource;
+ }
+
+ public synchronized String toClientURL()
+ {
+ if (clientURL == null)
+ {
+ clientURL = clientURL(resource);
+ }
+
+ return clientURL;
+ }
+ };
+ }
+
public Resource getRootResource()
{
return rootResource;
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ContextAssetFactory.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ContextAssetFactory.java?rev=1186581&r1=1186580&r2=1186581&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ContextAssetFactory.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ContextAssetFactory.java Thu Oct 20 00:32:28 2011
@@ -23,7 +23,7 @@ import org.apache.tapestry5.services.ass
/**
* Implementation of {@link AssetFactory} for assets that are part of the web application context.
- *
+ *
* @see org.apache.tapestry5.internal.services.ContextResource
*/
public class ContextAssetFactory implements AssetFactory
@@ -38,7 +38,7 @@ public class ContextAssetFactory impleme
public ContextAssetFactory(AssetPathConstructor assetPathConstructor, Context context,
- AssetPathConverter converter)
+ AssetPathConverter converter)
{
this.assetPathConstructor = assetPathConstructor;
this.converter = converter;
@@ -47,12 +47,44 @@ public class ContextAssetFactory impleme
invariant = this.converter.isInvariant();
}
- public Asset createAsset(final Resource resource)
+ public Asset createAsset(Resource resource)
{
- final String defaultPath = assetPathConstructor.constructAssetPath(RequestConstants.CONTEXT_FOLDER, resource
- .getPath());
+ String defaultPath = assetPathConstructor.constructAssetPath(RequestConstants.CONTEXT_FOLDER, resource.getPath());
- return new AbstractAsset(invariant)
+ if (invariant)
+ {
+ return createInvariantAsset(resource, defaultPath);
+ }
+
+ return createVariantAsset(resource, defaultPath);
+ }
+
+ private Asset createInvariantAsset(final Resource resource, final String defaultPath)
+ {
+ return new AbstractAsset(true)
+ {
+ private String clientURL;
+
+ public Resource getResource()
+ {
+ return resource;
+ }
+
+ public synchronized String toClientURL()
+ {
+ if (clientURL == null)
+ {
+ clientURL = converter.convertAssetPath(defaultPath);
+ }
+
+ return clientURL;
+ }
+ };
+ }
+
+ private Asset createVariantAsset(final Resource resource, final String defaultPath)
+ {
+ return new AbstractAsset(false)
{
public Resource getResource()
{
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=1186581&r1=1186580&r2=1186581&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java Thu Oct 20 00:32:28 2011
@@ -371,6 +371,7 @@ public final class TapestryModule
binder.bind(ValidationDecoratorFactory.class, ValidationDecoratorFactoryImpl.class);
binder.bind(PropertyConduitSource.class, PropertyConduitSourceImpl.class);
binder.bind(ClientWhitelist.class, ClientWhitelistImpl.class);
+ binder.bind(AssetFactory.class, ClasspathAssetFactory.class).withSimpleId();
}
// ========================================================================
@@ -1214,17 +1215,6 @@ public final class TapestryModule
return service;
}
- @Marker(ClasspathProvider.class)
- public AssetFactory buildClasspathAssetFactory(ResourceDigestManager resourceDigestManager,
- ClasspathAssetAliasManager aliasManager, AssetPathConverter converter)
- {
- ClasspathAssetFactory factory = new ClasspathAssetFactory(resourceDigestManager, aliasManager, converter);
-
- resourceDigestManager.addInvalidationListener(factory);
-
- return factory;
- }
-
@Marker(ContextProvider.class)
public AssetFactory buildContextAssetFactory(ApplicationGlobals globals,
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetFactoryTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetFactoryTest.java?rev=1186581&r1=1186580&r2=1186581&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetFactoryTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ClasspathAssetFactoryTest.java Thu Oct 20 00:32:28 2011
@@ -54,19 +54,6 @@ public class ClasspathAssetFactoryTest e
assertEquals(asset.toClientURL(), expectedClientURL);
verify();
-
- // Now, to test cache clearing:
- train_requiresDigest(digestManager, r, false);
-
- train_toClientURL(aliasManager, "foo/Bar.txt", expectedClientURL);
-
- replay();
-
- factory.objectWasInvalidated();
-
- assertEquals(asset.toClientURL(), expectedClientURL);
-
- verify();
}
@Test
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java?rev=1186581&r1=1186580&r2=1186581&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/CollectionFactory.java Thu Oct 20 00:32:28 2011
@@ -86,6 +86,14 @@ public final class CollectionFactory
}
/**
+ * @since 5.3
+ */
+ public static <K, V> Map<K, V> newWeakHashMap()
+ {
+ return new WeakHashMap<K, V>();
+ }
+
+ /**
* Contructs and returns a new generic {@link java.util.ArrayList} instance.
*/
public static <T> List<T> newList()