001 // 002 // Licensed under the Apache License, Version 2.0 (the "License"); 003 // you may not use this file except in compliance with the License. 004 // You may obtain a copy of the License at 005 // 006 // http://www.apache.org/licenses/LICENSE-2.0 007 // 008 // Unless required by applicable law or agreed to in writing, software 009 // distributed under the License is distributed on an "AS IS" BASIS, 010 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 011 // See the License for the specific language governing permissions and 012 // limitations under the License. 013 014 package net.sf.tacos.annotations; 015 016 import java.lang.reflect.Method; 017 import java.lang.reflect.Modifier; 018 019 import org.apache.hivemind.ApplicationRuntimeException; 020 import org.apache.hivemind.Location; 021 import org.apache.hivemind.service.BodyBuilder; 022 import org.apache.hivemind.service.MethodSignature; 023 import org.apache.tapestry.Tapestry; 024 import org.apache.tapestry.annotations.AnnotationUtils; 025 import org.apache.tapestry.annotations.MethodAnnotationEnhancementWorker; 026 import org.apache.tapestry.engine.ILink; 027 import org.apache.tapestry.enhance.EnhancementOperation; 028 import org.apache.tapestry.spec.IComponentSpecification; 029 030 /** 031 * @author Ming Jiang 032 * @author Andreas Andreou 033 */ 034 035 public class InjectExternalLinkAnnotationWorker implements 036 MethodAnnotationEnhancementWorker { 037 038 public void performEnhancement(EnhancementOperation op, IComponentSpecification spec, 039 Method method, Location location) { 040 if (!method.getReturnType().equals(ILink.class)) 041 throw new ApplicationRuntimeException("injectExternalLink annotation must return ILink"); 042 043 InjectExternalLink injectExternalLink = method.getAnnotation(InjectExternalLink.class); 044 045 String pageName = injectExternalLink.value(); 046 047 BodyBuilder builder = new BodyBuilder(); 048 049 builder.begin(); 050 builder.addln("String pageName=\"{0}\";", pageName); 051 if (injectExternalLink.currentNamespace()) 052 builder.addln("pageName=getNamespace().constructQualifiedName(pageName);"); 053 054 Class[] parameterTypes = method.getParameterTypes(); 055 int paramCount = Tapestry.size(parameterTypes); 056 057 if (paramCount > 0) { 058 if (parameterTypes[0].isArray()) { 059 builder.addln("return getPage().getRequestCycle().getInfrastructure().getServiceMap()." + 060 "getService(org.apache.tapestry.Tapestry.EXTERNAL_SERVICE).getLink(false, new org.apache.tapestry.engine.ExternalServiceParameter(pageName,$1));"); 061 } else { 062 builder.addln("java.lang.Object[] params = new java.lang.Object[{0}];", paramCount); 063 for (int i = 0; i < paramCount; i++) { 064 builder.add("params[{0}] = ", i); 065 if (parameterTypes[i].isPrimitive()) 066 builder.add("($w) "); 067 builder.addln("${0};", i + 1); 068 } 069 builder.addln("return getPage().getRequestCycle().getInfrastructure().getServiceMap()." + 070 "getService(org.apache.tapestry.Tapestry.EXTERNAL_SERVICE).getLink(false, new org.apache.tapestry.engine.ExternalServiceParameter(pageName,params));"); 071 } 072 } 073 074 builder.end(); 075 076 op.addMethod(Modifier.PUBLIC, new MethodSignature(method), builder 077 .toString(), location); 078 079 if (isGetter(method)) 080 op.claimReadonlyProperty(AnnotationUtils.getPropertyName(method)); 081 } 082 083 boolean isGetter(Method method) { 084 return method.getName().startsWith("get") 085 && method.getParameterTypes().length == 0; 086 } 087 }