001    package net.sf.tacos.seam.annotations;
002    
003    import java.lang.reflect.Method;
004    import java.lang.reflect.Modifier;
005    
006    import net.sf.tacos.seam.Bijection;
007    
008    import org.apache.hivemind.Location;
009    import org.apache.hivemind.service.BodyBuilder;
010    import org.apache.hivemind.service.MethodSignature;
011    import org.apache.tapestry.annotations.AnnotationUtils;
012    import org.apache.tapestry.annotations.MethodAnnotationEnhancementWorker;
013    import org.apache.tapestry.enhance.EnhanceUtils;
014    import org.apache.tapestry.enhance.EnhancementOperation;
015    import org.apache.tapestry.spec.IComponentSpecification;
016    import org.jboss.seam.annotations.In;
017    
018    /**
019     * Injects a reference to a Seam component.
020     * 
021     * @author Igor Drobiazko
022     *
023     */
024    public class InAnnotationtWorker implements MethodAnnotationEnhancementWorker {
025    
026            public void performEnhancement(EnhancementOperation op,
027                            IComponentSpecification spec, Method method, Location location) {
028                    injectSeamComponent(op, method, location);
029            }
030            
031            public void injectSeamComponent(EnhancementOperation op,
032                            Method method, Location location) {
033                    String property = AnnotationUtils.getPropertyName(method);
034                    In annotation = method.getAnnotation(In.class);
035            Class<?> propertyType = op.getPropertyType(property);
036            if (propertyType == null)
037                propertyType = Object.class;
038    
039            op.claimProperty(property);
040    
041            String name = annotation.value();
042            if(name.equals("")){
043                    name = property;
044            }
045            Object injectedValue = Bijection.inject(
046                                                                    propertyType, name,
047                                                                    annotation.scope(),
048                                                                    annotation.required(),
049                                                                    annotation.create());
050            String fieldName;
051            if(injectedValue!=null){
052                    fieldName = op.addInjectedField("_$" + property,
053                                                   propertyType, injectedValue);
054            }else{
055                    fieldName = null;
056            }
057            
058            addAccessor(op, property, fieldName,  propertyType, location);
059            
060            addMutator(op, property, fieldName,  propertyType, location);
061            }
062            private void addAccessor(EnhancementOperation op, String property, String fieldName,
063                Class<?> propertyType, Location location){
064            String methodName = EnhanceUtils.createAccessorMethodName(property);
065            op.addMethod(Modifier.PUBLIC, new MethodSignature(propertyType,
066                                                              methodName, null, null), "return " + fieldName + ";", location);
067            }
068        private void addMutator(EnhancementOperation op, String property, String fieldName,
069                Class<?> propertyType, Location location){
070            String methodName = EnhanceUtils.createMutatorMethodName(property);
071            BodyBuilder body = new BodyBuilder();
072            body.begin();
073            if(fieldName!=null){
074                    body.addln("{0} = $1;", fieldName);
075            }
076            body.end();
077            MethodSignature sig = new MethodSignature(void.class, methodName,
078                    new Class[] { propertyType }, null);
079            op.addMethod(Modifier.PUBLIC, sig, body.toString(), location);
080        }
081    }