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 }