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.enhance; 016 017import java.util.Iterator; 018 019import org.apache.hivemind.ErrorLog; 020import org.apache.hivemind.Location; 021import org.apache.hivemind.service.BodyBuilder; 022import org.apache.hivemind.service.ClassFabUtils; 023import org.apache.hivemind.util.Defense; 024import org.apache.tapestry.IComponent; 025import org.apache.tapestry.TapestryUtils; 026import org.apache.tapestry.spec.IComponentSpecification; 027import org.apache.tapestry.spec.IContainedComponent; 028 029/** 030 * Injects components for which the property attribute of the <component> element was 031 * specified. This makes it easier to reference a particular component from Java code. 032 * 033 * @author Howard M. Lewis Ship 034 * @since 4.0 035 */ 036public class InjectComponentWorker implements EnhancementWorker 037{ 038 private ErrorLog _errorLog; 039 040 public void performEnhancement(EnhancementOperation op, IComponentSpecification spec) 041 { 042 Iterator i = spec.getComponentIds().iterator(); 043 044 while (i.hasNext()) 045 { 046 String id = (String) i.next(); 047 048 IContainedComponent cc = spec.getComponent(id); 049 050 String propertyName = cc.getPropertyName(); 051 052 if (propertyName != null) 053 { 054 try 055 { 056 injectComponent(op, id, propertyName, cc.getLocation()); 057 } 058 catch (Exception ex) 059 { 060 _errorLog.error(EnhanceMessages.errorAddingProperty(propertyName, op 061 .getBaseClass(), ex), cc.getLocation(), ex); 062 } 063 } 064 } 065 } 066 067 public void injectComponent(EnhancementOperation op, String componentId, String propertyName, 068 Location location) 069 { 070 Defense.notNull(op, "op"); 071 Defense.notNull(componentId, "componentId"); 072 Defense.notNull(propertyName, "propertyName"); 073 074 Class propertyType = EnhanceUtils.extractPropertyType(op, propertyName, null); 075 076 op.claimReadonlyProperty(propertyName); 077 078 String fieldName = "_$" + propertyName; 079 String classField = op.getClassReference(propertyType); 080 String locationField = op.addInjectedField( 081 fieldName + "$location", 082 Location.class, 083 location); 084 085 op.addField(fieldName, propertyType); 086 087 EnhanceUtils.createSimpleAccessor(op, fieldName, propertyName, propertyType, location); 088 089 // I.e. _$fred = (IComponent) TapestryUtils.getComponent(this, "fred", IComponent.class, 090 // location) 091 092 BodyBuilder builder = new BodyBuilder(); 093 094 builder.add("{0} = ({1}) ", fieldName, ClassFabUtils.getJavaClassName(propertyType)); 095 builder.add("{0}#getComponent(this, ", TapestryUtils.class.getName()); 096 builder.addQuoted(componentId); 097 builder.add(", {0}, {1});", classField, locationField); 098 099 op.extendMethodImplementation(IComponent.class, EnhanceUtils.FINISH_LOAD_SIGNATURE, builder 100 .toString()); 101 } 102 103 public void setErrorLog(ErrorLog errorLog) 104 { 105 _errorLog = errorLog; 106 } 107}