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.lang.reflect.Modifier; 018 019import org.apache.hivemind.ErrorLog; 020import org.apache.hivemind.Location; 021import org.apache.hivemind.Messages; 022import org.apache.hivemind.service.BodyBuilder; 023import org.apache.hivemind.service.MethodSignature; 024import org.apache.hivemind.util.Defense; 025import org.apache.tapestry.services.ComponentMessagesSource; 026import org.apache.tapestry.spec.IComponentSpecification; 027 028/** 029 * Injects the read-only {@link org.apache.tapestry.IComponent#getMessages() messages}property into 030 * all components. 031 * 032 * @author Howard M. Lewis Ship 033 * @since 4.0 034 */ 035public class InjectMessagesWorker implements EnhancementWorker 036{ 037 final String MESSAGES_PROPERTY = "messages"; 038 039 private ErrorLog _errorLog; 040 041 private ComponentMessagesSource _componentMessagesSource; 042 043 final MethodSignature METHOD_SIGNATURE = new MethodSignature(Messages.class, "getMessages", 044 null, null); 045 046 public void performEnhancement(EnhancementOperation op, IComponentSpecification spec) 047 { 048 Location location = spec.getLocation(); 049 050 try 051 { 052 injectMessages(op, location); 053 } 054 catch (Exception ex) 055 { 056 _errorLog.error(EnhanceMessages.errorAddingProperty(MESSAGES_PROPERTY, op 057 .getBaseClass(), ex), location, ex); 058 } 059 } 060 061 public void injectMessages(EnhancementOperation op, Location location) 062 { 063 Defense.notNull(op, "op"); 064 065 op.claimReadonlyProperty(MESSAGES_PROPERTY); 066 067 String sourceField = op.addInjectedField( 068 "_$componentMessagesSource", 069 ComponentMessagesSource.class, 070 _componentMessagesSource); 071 072 op.addField("_$messages", Messages.class); 073 074 BodyBuilder builder = new BodyBuilder(); 075 builder.begin(); 076 builder.addln("if (_$messages == null)"); 077 builder.addln(" _$messages = {0}.getMessages(this);", sourceField); 078 builder.addln("return _$messages;"); 079 builder.end(); 080 081 op.addMethod(Modifier.PUBLIC, METHOD_SIGNATURE, builder.toString(), location); 082 } 083 084 public void setComponentMessagesSource(ComponentMessagesSource componentMessagesSource) 085 { 086 _componentMessagesSource = componentMessagesSource; 087 } 088 089 public void setErrorLog(ErrorLog errorLog) 090 { 091 _errorLog = errorLog; 092 } 093}