View Javadoc

1   //
2   // Licensed under the Apache License, Version 2.0 (the "License");
3   // you may not use this file except in compliance with the License.
4   // You may obtain a copy of the License at
5   //
6   //     http://www.apache.org/licenses/LICENSE-2.0
7   //
8   // Unless required by applicable law or agreed to in writing, software
9   // distributed under the License is distributed on an "AS IS" BASIS,
10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  // See the License for the specific language governing permissions and
12  // limitations under the License.
13  
14  package net.sf.tacos.annotations;
15  
16  import java.lang.reflect.Method;
17  import java.lang.reflect.Modifier;
18  
19  import org.apache.hivemind.ApplicationRuntimeException;
20  import org.apache.hivemind.Location;
21  import org.apache.hivemind.service.BodyBuilder;
22  import org.apache.hivemind.service.MethodSignature;
23  import org.apache.tapestry.Tapestry;
24  import org.apache.tapestry.annotations.AnnotationUtils;
25  import org.apache.tapestry.annotations.MethodAnnotationEnhancementWorker;
26  import org.apache.tapestry.engine.ILink;
27  import org.apache.tapestry.enhance.EnhancementOperation;
28  import org.apache.tapestry.spec.IComponentSpecification;
29  
30  /**
31   * @author Ming Jiang
32   * @author Andreas Andreou
33   */
34  
35  public class InjectExternalLinkAnnotationWorker implements
36  		MethodAnnotationEnhancementWorker {
37  
38      public void performEnhancement(EnhancementOperation op, IComponentSpecification spec,
39              Method method, Location location) {
40          if (!method.getReturnType().equals(ILink.class))
41                  throw new ApplicationRuntimeException("injectExternalLink annotation must return ILink");
42  
43          InjectExternalLink injectExternalLink = method.getAnnotation(InjectExternalLink.class);
44  
45          String pageName = injectExternalLink.value();
46  
47          BodyBuilder builder = new BodyBuilder();
48  
49          builder.begin();
50          builder.addln("String pageName=\"{0}\";", pageName);
51          if (injectExternalLink.currentNamespace())
52              builder.addln("pageName=getNamespace().constructQualifiedName(pageName);");        
53  
54          Class[] parameterTypes = method.getParameterTypes();
55          int paramCount = Tapestry.size(parameterTypes);
56  
57          if (paramCount > 0) {
58                  if (parameterTypes[0].isArray()) {
59                          builder.addln("return getPage().getRequestCycle().getInfrastructure().getServiceMap()." +
60                                  "getService(org.apache.tapestry.Tapestry.EXTERNAL_SERVICE).getLink(false, new org.apache.tapestry.engine.ExternalServiceParameter(pageName,$1));");
61                  } else {
62                          builder.addln("java.lang.Object[] params = new java.lang.Object[{0}];", paramCount);
63                          for (int i = 0; i < paramCount; i++) {
64                                  builder.add("params[{0}] = ", i);
65                                  if (parameterTypes[i].isPrimitive())
66                                          builder.add("($w) ");
67                                  builder.addln("${0};", i + 1);
68                          }
69                          builder.addln("return getPage().getRequestCycle().getInfrastructure().getServiceMap()." +
70                                  "getService(org.apache.tapestry.Tapestry.EXTERNAL_SERVICE).getLink(false, new org.apache.tapestry.engine.ExternalServiceParameter(pageName,params));");
71                  }
72          }
73  
74          builder.end();
75  
76          op.addMethod(Modifier.PUBLIC, new MethodSignature(method), builder
77                          .toString(), location);
78  
79          if (isGetter(method))
80                  op.claimReadonlyProperty(AnnotationUtils.getPropertyName(method));
81      }
82  
83      boolean isGetter(Method method) {
84              return method.getName().startsWith("get")
85                              && method.getParameterTypes().length == 0;
86      }
87  }