001 package org.chenillekit.tapestry.core.factories;
002
003 import java.io.UnsupportedEncodingException;
004 import java.net.URLEncoder;
005 import java.util.Map;
006
007 import org.apache.tapestry5.Asset;
008 import org.apache.tapestry5.internal.services.ResourceCache;
009 import org.apache.tapestry5.ioc.Resource;
010 import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newConcurrentMap;
011 import org.apache.tapestry5.services.AssetFactory;
012
013 import org.chenillekit.core.resources.URIResource;
014 import org.chenillekit.tapestry.core.services.URIAssetAliasManager;
015
016 /**
017 * @version $Id: URIAssetFactory.java 594 2009-12-05 15:17:26Z mlusetti $
018 */
019 public class URIAssetFactory implements AssetFactory
020 {
021 private final ResourceCache cache;
022
023 private final URIAssetAliasManager aliasManager;
024
025 private final Map<Resource, String> resourceToClientURL = newConcurrentMap();
026
027 public URIAssetFactory(final ResourceCache cache,
028 final URIAssetAliasManager aliasManager)
029 {
030 this.cache = cache;
031 this.aliasManager = aliasManager;
032 }
033
034 /**
035 * Returns the Resource representing the root folder of the domain this factory is responsible for.
036 */
037 public Resource getRootResource()
038 {
039 return new URIResource("/");
040 }
041
042 private String clientURL(Resource resource)
043 {
044 String clientURL = resourceToClientURL.get(resource);
045
046 if (clientURL == null)
047 {
048 clientURL = buildClientURL(resource);
049 resourceToClientURL.put(resource, clientURL);
050 }
051
052 // The path generated is partially request-dependent and therefore can't be cached, it will even
053 // vary from request to the next.
054
055 return aliasManager.toClientURL(clientURL);
056 }
057
058 private String buildClientURL(Resource resource)
059 {
060 boolean requiresDigest = cache.requiresDigest(resource);
061
062 String path = null;
063
064 try
065 {
066 path = URLEncoder.encode(resource.getPath(), "UTF-8");
067 }
068 catch (UnsupportedEncodingException e)
069 {
070 throw new RuntimeException(e);
071 }
072
073 if (requiresDigest)
074 {
075 // Resources with extensions go from foo/bar/baz.txt --> foo/bar/baz.CHECKSUM.txt
076
077 int lastdotx = path.lastIndexOf('.');
078
079 path = path.substring(0, lastdotx + 1) + cache.getDigest(resource) + path.substring(lastdotx);
080 }
081
082 return path;
083 }
084
085 public Asset createAsset(final Resource resource)
086 {
087 return new Asset()
088 {
089 public Resource getResource()
090 {
091 return resource;
092 }
093
094 public String toClientURL()
095 {
096 return clientURL(resource);
097 }
098
099 @Override
100 public String toString()
101 {
102 return toClientURL();
103 }
104 };
105 }
106 }