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 org.apache.hivemind.Location;
018 import org.apache.hivemind.Resource;
019 import org.apache.hivemind.util.Defense;
020 import org.apache.tapestry.IAsset;
021 import org.apache.tapestry.spec.IComponentSpecification;
022
023 import java.util.*;
024
025 /**
026 * Implementation of the {@link org.apache.tapestry.asset.AssetSource} service interface.
027 *
028 */
029 public class AssetSourceImpl implements AssetSource
030 {
031 private Map _assetFactoryByPrefix = new HashMap();
032
033 private List _contributions;
034
035 private AssetFactory _defaultAssetFactory;
036
037 private AssetFactory _lookupAssetFactory;
038
039 private AssetFactory _classpathAssetFactory;
040
041 private AssetFactory _contextAssetFactory;
042
043 public void initializeService()
044 {
045 Iterator i = _contributions.iterator();
046 while (i.hasNext())
047 {
048 AssetFactoryContribution c = (AssetFactoryContribution) i.next();
049
050 _assetFactoryByPrefix.put(c.getPrefix(), c.getFactory());
051 }
052 }
053
054 public IAsset findAsset(Resource base, String path, Locale locale, Location location)
055 {
056 return findAsset(base, null, path, locale, location);
057 }
058
059 public IAsset findAsset(Resource base, IComponentSpecification spec, String path, Locale locale, Location location)
060 {
061 Defense.notNull(path, "path");
062 Defense.notNull(location, "location");
063
064 int colonx = path.indexOf(':');
065
066 String prefix = colonx > -1 ? path.substring(0, colonx) : null;
067 String truePath = colonx > -1 ? path.substring(colonx + 1) : path;
068
069 AssetFactory factory = null;
070
071 if (prefix != null) {
072
073 factory = (AssetFactory) _assetFactoryByPrefix.get(prefix);
074 }
075
076 // now we have to search
077
078 if (factory == null && prefix == null) {
079
080 factory = findAssetFactory(spec, base, truePath, locale);
081 }
082
083 // Unknown prefix is expected to happen when an external asset (using an established
084 // prefix such as http:) is referenced.
085
086 if (factory == null)
087 {
088 factory = _defaultAssetFactory;
089
090 // Path is the full path, including the prefix (which is really the scheme
091 // of the URL).
092
093 truePath = path;
094 }
095
096 if (truePath.startsWith("/"))
097 return factory.createAbsoluteAsset(truePath, locale, location);
098
099 // This can happen when a 3.0 DTD is read in
100
101 return factory.createAsset(base, spec, truePath, locale, location);
102 }
103
104 AssetFactory findAssetFactory(IComponentSpecification spec, Resource baseResource, String path, Locale locale)
105 {
106 // need to check these two core factories in order first
107
108 if (_classpathAssetFactory.assetExists(spec, baseResource, path, locale))
109 return _classpathAssetFactory;
110
111 if (_contextAssetFactory.assetExists(spec, baseResource, path, locale))
112 return _contextAssetFactory;
113
114 for (int i=0; i < _contributions.size(); i++) {
115
116 AssetFactoryContribution c = (AssetFactoryContribution)_contributions.get(i);
117
118 if (c.getFactory().assetExists(spec, baseResource, path, locale))
119 return c.getFactory();
120 }
121
122 return null;
123 }
124
125 /**
126 * Factory used when the path has no prefix, and the type of asset must be inferred from the
127 * type of resource.
128 */
129
130 public void setLookupAssetFactory(AssetFactory lookupAssetFactory)
131 {
132 _lookupAssetFactory = lookupAssetFactory;
133 }
134
135 /**
136 * List of {@link org.apache.tapestry.asset.AssetFactoryContribution}.
137 */
138
139 public void setContributions(List contributions)
140 {
141 _contributions = contributions;
142 }
143
144 /**
145 * Factory used when an unrecognized prefix (typically, an arbitrary URL's scheme) is provided.
146 */
147
148 public void setDefaultAssetFactory(AssetFactory defaultAssetFactory)
149 {
150 _defaultAssetFactory = defaultAssetFactory;
151 }
152
153 public void setClasspathAssetFactory(AssetFactory classpathAssetFactory)
154 {
155 _classpathAssetFactory = classpathAssetFactory;
156 }
157
158 public void setContextAssetFactory(AssetFactory contextAssetFactory)
159 {
160 _contextAssetFactory = contextAssetFactory;
161 }
162 }