001// Copyright 2006, 2007, 2011 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 015package org.apache.tapestry5.internal.transform; 016 017import org.apache.tapestry5.func.F; 018import org.apache.tapestry5.func.Predicate; 019import org.apache.tapestry5.ioc.ObjectLocator; 020import org.apache.tapestry5.ioc.OperationTracker; 021import org.apache.tapestry5.ioc.annotations.Inject; 022import org.apache.tapestry5.model.MutableComponentModel; 023import org.apache.tapestry5.plastic.PlasticClass; 024import org.apache.tapestry5.plastic.PlasticField; 025import org.apache.tapestry5.services.transform.ComponentClassTransformWorker2; 026import org.apache.tapestry5.services.transform.InjectionProvider2; 027import org.apache.tapestry5.services.transform.TransformationSupport; 028 029/** 030 * Performs injection triggered by any field annotated with the {@link org.apache.tapestry5.ioc.annotations.Inject} 031 * annotation or the {@link javax.inject.Inject} annotation. 032 * <p/> 033 * The implementation of this worker mostly delegates to a chain of command of {@link InjectionProvider2}. 034 */ 035public class InjectWorker implements ComponentClassTransformWorker2 036{ 037 private final ObjectLocator locator; 038 039 // Really, a chain of command 040 041 private final InjectionProvider2 injectionProvider; 042 043 private final OperationTracker tracker; 044 045 private final Predicate<PlasticField> MATCHER = new Predicate<PlasticField>() 046 { 047 public boolean accept(PlasticField field) 048 { 049 return field.hasAnnotation(Inject.class) || 050 field.hasAnnotation(javax.inject.Inject.class); 051 } 052 }; 053 054 public InjectWorker(ObjectLocator locator, InjectionProvider2 injectionProvider, OperationTracker tracker) 055 { 056 this.locator = locator; 057 this.injectionProvider = injectionProvider; 058 this.tracker = tracker; 059 } 060 061 public void transform(final PlasticClass plasticClass, TransformationSupport support, final MutableComponentModel model) 062 { 063 for (final PlasticField field : F.flow(plasticClass.getUnclaimedFields()).filter(MATCHER)) 064 { 065 final String fieldName = field.getName(); 066 067 tracker.run(String.format("Injecting field %s.%s", plasticClass.getClassName(), fieldName), new Runnable() 068 { 069 public void run() 070 { 071 try 072 { 073 boolean success = injectionProvider.provideInjection(field, locator, model); 074 075 if (success) 076 { 077 field.claim("@Inject"); 078 } 079 } catch (RuntimeException ex) 080 { 081 throw new RuntimeException(TransformMessages.fieldInjectionError(plasticClass.getClassName(), 082 fieldName, ex), ex); 083 } 084 } 085 }); 086 } 087 } 088}