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
015package org.apache.tapestry.asset;
016
017import java.util.HashMap;
018import java.util.Iterator;
019import java.util.List;
020import java.util.Locale;
021import java.util.Map;
022
023import org.apache.hivemind.Location;
024import org.apache.hivemind.Resource;
025import org.apache.hivemind.util.Defense;
026import 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 */
034public 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}