001    // Copyright 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry.asset;
016    
017    import java.util.HashMap;
018    import java.util.Iterator;
019    import java.util.List;
020    import java.util.Locale;
021    import java.util.Map;
022    
023    import org.apache.hivemind.Location;
024    import org.apache.hivemind.Resource;
025    import org.apache.hivemind.util.Defense;
026    import org.apache.tapestry.IAsset;
027    
028    /**
029     * Implementation of the {@link org.apache.tapestry.asset.AssetSource}service interface.
030     * 
031     * @author Howard M. Lewis Ship
032     * @since 4.0
033     */
034    public class AssetSourceImpl implements AssetSource
035    {
036        private Map _assetFactoryByPrefix = new HashMap();
037    
038        private List _contributions;
039    
040        private AssetFactory _defaultAssetFactory;
041    
042        private AssetFactory _lookupAssetFactory;
043    
044        public void initializeService()
045        {
046            Iterator i = _contributions.iterator();
047            while (i.hasNext())
048            {
049                AssetFactoryContribution c = (AssetFactoryContribution) i.next();
050    
051                _assetFactoryByPrefix.put(c.getPrefix(), c.getFactory());
052            }
053        }
054    
055        public IAsset findAsset(Resource base, String path, Locale locale, Location location)
056        {
057            Defense.notNull(base, "base");
058            Defense.notNull(path, "path");
059            Defense.notNull(location, "location");
060    
061            int colonx = path.indexOf(':');
062    
063            if (colonx < 0)
064                return _lookupAssetFactory.createAsset(base, path, locale, location);
065    
066            String prefix = path.substring(0, colonx);
067            String truePath = path.substring(colonx + 1);
068    
069            AssetFactory factory = (AssetFactory) _assetFactoryByPrefix.get(prefix);
070    
071            // Unknown prefix is expected to happen when an external asset (using an established
072            // prefix such as http:) is referenced.
073    
074            if (factory == null)
075            {
076                factory = _defaultAssetFactory;
077    
078                // Path is the full path, including the prefix (which is really the scheme
079                // of the URL).
080    
081                truePath = path;
082            }
083    
084            if (truePath.startsWith("/"))
085                return factory.createAbsoluteAsset(truePath, locale, location);
086    
087            // This can happen when a 3.0 DTD is read in
088    
089            return factory.createAsset(base, truePath, locale, location);
090        }
091    
092        /**
093         * Factory used when the path has no prefix, and the type of asset must be inferred from the
094         * type of resource.
095         */
096    
097        public void setLookupAssetFactory(AssetFactory lookupAssetFactory)
098        {
099            _lookupAssetFactory = lookupAssetFactory;
100        }
101    
102        /**
103         * List of {@link org.apache.tapestry.asset.AssetFactoryContribution}.
104         */
105    
106        public void setContributions(List contributions)
107        {
108            _contributions = contributions;
109        }
110    
111        /**
112         * Factory used when an unrecognized prefix (typically, an arbitrary URL's scheme) is provided.
113         */
114    
115        public void setDefaultAssetFactory(AssetFactory defaultAssetFactory)
116        {
117            _defaultAssetFactory = defaultAssetFactory;
118        }
119    
120    }