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 }