001// Licensed under the Apache License, Version 2.0 (the "License"); 002// you may not use this file except in compliance with the License. 003// You may obtain a copy of the License at 004// 005// http://www.apache.org/licenses/LICENSE-2.0 006// 007// Unless required by applicable law or agreed to in writing, software 008// distributed under the License is distributed on an "AS IS" BASIS, 009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 010// See the License for the specific language governing permissions and 011// limitations under the License. 012 013package org.apache.tapestry5.internal.services; 014 015import org.apache.tapestry5.Asset; 016import org.apache.tapestry5.ComponentResources; 017import org.apache.tapestry5.annotations.Path; 018import org.apache.tapestry5.commons.ObjectLocator; 019import org.apache.tapestry5.model.MutableComponentModel; 020import org.apache.tapestry5.plastic.ComputedValue; 021import org.apache.tapestry5.plastic.InstanceContext; 022import org.apache.tapestry5.plastic.PlasticField; 023import org.apache.tapestry5.services.AssetSource; 024import org.apache.tapestry5.services.transform.InjectionProvider2; 025 026/** 027 * Performs injection of assets, based on the presence of the {@link Path} annotation. This is more 028 * useful than the 029 * general {@link AssetObjectProvider}, because relative assets are supported. 030 */ 031public class AssetInjectionProvider implements InjectionProvider2 032{ 033 private final AssetSource assetSource; 034 035 public AssetInjectionProvider(AssetSource assetSource) 036 { 037 this.assetSource = assetSource; 038 } 039 040 public boolean provideInjection(PlasticField field, ObjectLocator locator, MutableComponentModel componentModel) 041 { 042 Path path = field.getAnnotation(Path.class); 043 044 if (path == null) 045 { 046 return false; 047 } 048 049 final String assetPath = path.value(); 050 final String libraryName = componentModel.getLibraryName(); 051 052 ComputedValue<Asset> computedAsset = new ComputedValue<Asset>() 053 { 054 public Asset get(InstanceContext context) 055 { 056 ComponentResources resources = context.get(ComponentResources.class); 057 058 // Note how this works: the resources represents the actual instantiated class, and the libraryName 059 // comes from the componentModel, potentially, the componentModel of a base class (which may have 060 // a different library name than the subclass). 061 return assetSource.getComponentAsset(resources, assetPath, libraryName); 062 } 063 }; 064 065 field.injectComputed(computedAsset); 066 067 return true; 068 } 069 070}