Coverage Report - org.apache.tapestry5.internal.services.AssetSourceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
AssetSourceImpl
100%
43/43
94%
15/16
0
 
 1  
 // Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
 2  
 //
 3  
 // Licensed under the Apache License, Version 2.0 (the "License");
 4  
 // you may not use this file except in compliance with the License.
 5  
 // You may obtain a copy of the License at
 6  
 //
 7  
 //     http://www.apache.org/licenses/LICENSE-2.0
 8  
 //
 9  
 // Unless required by applicable law or agreed to in writing, software
 10  
 // distributed under the License is distributed on an "AS IS" BASIS,
 11  
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  
 // See the License for the specific language governing permissions and
 13  
 // limitations under the License.
 14  
 
 15  
 package org.apache.tapestry5.internal.services;
 16  
 
 17  
 import org.apache.tapestry5.Asset;
 18  
 import org.apache.tapestry5.ioc.Resource;
 19  
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 20  
 import org.apache.tapestry5.ioc.internal.util.Defense;
 21  
 import org.apache.tapestry5.ioc.services.ThreadLocale;
 22  
 import org.apache.tapestry5.ioc.util.StrategyRegistry;
 23  
 import org.apache.tapestry5.services.AssetFactory;
 24  
 import org.apache.tapestry5.services.AssetSource;
 25  
 
 26  
 import java.util.Locale;
 27  
 import java.util.Map;
 28  
 
 29  
 public class AssetSourceImpl implements AssetSource
 30  
 {
 31  
     private static final String CLASSPATH = "classpath";
 32  
 
 33  
     private static final String CONTEXT = "context";
 34  
 
 35  
     private final StrategyRegistry<AssetFactory> registry;
 36  
 
 37  
     private final ThreadLocale threadLocale;
 38  
 
 39  68
     private final Map<String, Resource> prefixToRootResource = CollectionFactory.newMap();
 40  
 
 41  68
     private final Map<Resource, Asset> cache = CollectionFactory.newConcurrentMap();
 42  
 
 43  
     public AssetSourceImpl(ThreadLocale threadLocale,
 44  
 
 45  
                            Map<String, AssetFactory> configuration)
 46  68
     {
 47  68
         this.threadLocale = threadLocale;
 48  
 
 49  68
         Map<Class, AssetFactory> byResourceClass = CollectionFactory.newMap();
 50  
 
 51  68
         for (Map.Entry<String, AssetFactory> e : configuration.entrySet())
 52  
         {
 53  120
             String prefix = e.getKey();
 54  120
             AssetFactory factory = e.getValue();
 55  
 
 56  120
             Resource rootResource = factory.getRootResource();
 57  
 
 58  120
             byResourceClass.put(rootResource.getClass(), factory);
 59  
 
 60  120
             prefixToRootResource.put(prefix, rootResource);
 61  120
         }
 62  
 
 63  68
         registry = StrategyRegistry.newInstance(AssetFactory.class, byResourceClass);
 64  68
     }
 65  
 
 66  
     public Asset getClasspathAsset(String path)
 67  
     {
 68  2
         return getClasspathAsset(path, null);
 69  
     }
 70  
 
 71  
     public Asset getClasspathAsset(String path, Locale locale)
 72  
     {
 73  4
         return getAsset(null, path, locale);
 74  
     }
 75  
 
 76  
     public Asset getContextAsset(String path, Locale locale)
 77  
     {
 78  2
         return getAsset(prefixToRootResource.get(CONTEXT), path, locale);
 79  
     }
 80  
 
 81  
     public Asset getAsset(Resource baseResource, String path, Locale locale)
 82  
     {
 83  3079
         return getAssetInLocale(baseResource, path, defaulted(locale));
 84  
     }
 85  
 
 86  
     public Resource resourceForPath(String path)
 87  
     {
 88  56
         return getUnlocalizedResource(null, path);
 89  
     }
 90  
 
 91  
     private Asset getAssetInLocale(Resource baseResource, String path, Locale locale)
 92  
     {
 93  3079
         return getLocalizedAssetFromResource(getUnlocalizedResource(baseResource, path), locale);
 94  
     }
 95  
 
 96  
     private Resource getUnlocalizedResource(Resource baseResource, String path)
 97  
     {
 98  3135
         Defense.notBlank(path, "path");
 99  
 
 100  3135
         int colonx = path.indexOf(':');
 101  
 
 102  3135
         if (colonx < 0)
 103  
         {
 104  737
             Resource root = baseResource != null ? baseResource : prefixToRootResource.get(CLASSPATH);
 105  
 
 106  737
             return root.forFile(path);
 107  
         }
 108  
 
 109  2398
         String prefix = path.substring(0, colonx);
 110  
 
 111  2398
         Resource root = prefixToRootResource.get(prefix);
 112  
 
 113  2398
         if (root == null)
 114  2
             throw new IllegalArgumentException(ServicesMessages.unknownAssetPrefix(path));
 115  
 
 116  
 
 117  2396
         return root.forFile(path.substring(colonx + 1));
 118  
     }
 119  
 
 120  
 
 121  
     private Asset getLocalizedAssetFromResource(Resource unlocalized, Locale locale)
 122  
     {
 123  3077
         Resource localized = locale == null
 124  
                              ? unlocalized
 125  
                              : unlocalized.forLocale(locale);
 126  
 
 127  3077
         if (localized == null)
 128  2
             throw new RuntimeException(ServicesMessages.assetDoesNotExist(unlocalized));
 129  
 
 130  3075
         return getAssetForResource(localized);
 131  
     }
 132  
 
 133  
     private Asset getAssetForResource(Resource resource)
 134  
     {
 135  3075
         Asset result = cache.get(resource);
 136  
 
 137  3075
         if (result == null)
 138  
         {
 139  524
             result = createAssetFromResource(resource);
 140  524
             cache.put(resource, result);
 141  
         }
 142  
 
 143  3075
         return result;
 144  
     }
 145  
 
 146  
     private Locale defaulted(Locale locale)
 147  
     {
 148  3079
         return locale != null ? locale : threadLocale.getLocale();
 149  
     }
 150  
 
 151  
     private Asset createAssetFromResource(Resource resource)
 152  
     {
 153  
         // The class of the resource is derived from the class of the base resource.
 154  
         // So we can then use the class of the resource as a key to locate the correct asset
 155  
         // factory.
 156  
 
 157  524
         Class resourceClass = resource.getClass();
 158  
 
 159  524
         AssetFactory factory = registry.get(resourceClass);
 160  
 
 161  524
         return factory.createAsset(resource);
 162  
     }
 163  
 }