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.annotations; 016 017 import java.lang.reflect.Method; 018 import java.lang.reflect.Modifier; 019 020 import org.apache.hivemind.ApplicationRuntimeException; 021 import org.apache.hivemind.Location; 022 import org.apache.hivemind.service.BodyBuilder; 023 import org.apache.hivemind.service.MethodSignature; 024 import org.apache.tapestry.Tapestry; 025 import org.apache.tapestry.enhance.EnhancementOperation; 026 import org.apache.tapestry.spec.IComponentSpecification; 027 028 /** 029 * Builds a method that accesses component messages. 030 * 031 * @author Howard Lewis Ship 032 * @since 4.0 033 */ 034 public class MessageAnnotationWorker implements MethodAnnotationEnhancementWorker 035 { 036 037 public void performEnhancement(EnhancementOperation op, IComponentSpecification spec, 038 Method method, Location location) 039 { 040 if (!method.getReturnType().equals(String.class)) 041 throw new ApplicationRuntimeException(AnnotationMessages.returnStringOnly(method 042 .getReturnType())); 043 044 Message message = method.getAnnotation(Message.class); 045 046 String keyName = message.value(); 047 048 if (keyName.equals("")) 049 keyName = AnnotationUtils.convertMethodNameToKeyName(method.getName()); 050 051 BodyBuilder builder = new BodyBuilder(); 052 053 builder.begin(); 054 055 Class[] parameterTypes = method.getParameterTypes(); 056 int paramCount = Tapestry.size(parameterTypes); 057 058 if (paramCount > 0) 059 { 060 builder.addln("java.lang.Object[] params = new java.lang.Object[{0}];", paramCount); 061 for (int i = 0; i < paramCount; i++) 062 { 063 builder.add("params[{0}] = ", i); 064 065 if (parameterTypes[i].isPrimitive()) 066 builder.add("($w) "); 067 068 // Parameter $0 is this, so $1 is the first real parameter. 069 070 builder.addln("${0};", i + 1); 071 } 072 } 073 074 builder.add("return getMessages()."); 075 076 if (paramCount == 0) 077 builder.addln("getMessage(\"{0}\");", keyName); 078 else 079 builder.addln("format(\"{0}\", params);", keyName); 080 081 builder.end(); 082 083 op.addMethod(Modifier.PUBLIC, new MethodSignature(method), builder.toString(), location); 084 085 if (isGetter(method)) 086 op.claimReadonlyProperty(AnnotationUtils.getPropertyName(method)); 087 } 088 089 boolean isGetter(Method method) 090 { 091 // We already know the return type is String 092 093 return method.getName().startsWith("get") && method.getParameterTypes().length == 0; 094 } 095 }