001// Licensed under the Apache License, Version 2.0 (the "License"); 002// you may not use this file except in compliance with the License. 003// You may obtain a copy of the License at 004// 005// http://www.apache.org/licenses/LICENSE-2.0 006// 007// Unless required by applicable law or agreed to in writing, software 008// distributed under the License is distributed on an "AS IS" BASIS, 009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 010// See the License for the specific language governing permissions and 011// limitations under the License. 012 013package org.apache.tapestry5.internal.transform; 014 015import org.apache.tapestry5.commons.ObjectLocator; 016import org.apache.tapestry5.commons.util.ExceptionUtils; 017import org.apache.tapestry5.func.F; 018import org.apache.tapestry5.func.Predicate; 019import org.apache.tapestry5.ioc.OperationTracker; 020import org.apache.tapestry5.ioc.annotations.Inject; 021import org.apache.tapestry5.model.MutableComponentModel; 022import org.apache.tapestry5.plastic.PlasticClass; 023import org.apache.tapestry5.plastic.PlasticField; 024import org.apache.tapestry5.services.transform.ComponentClassTransformWorker2; 025import org.apache.tapestry5.services.transform.InjectionProvider2; 026import org.apache.tapestry5.services.transform.TransformationSupport; 027 028/** 029 * Performs injection triggered by any field annotated with the {@link org.apache.tapestry5.ioc.annotations.Inject} 030 * annotation or the {@link javax.inject.Inject} annotation. 031 * 032 * The implementation of this worker mostly delegates to a chain of command of {@link InjectionProvider2}. 033 */ 034public class InjectWorker implements ComponentClassTransformWorker2 035{ 036 private final ObjectLocator locator; 037 038 // Really, a chain of command 039 040 private final InjectionProvider2 injectionProvider; 041 042 private final OperationTracker tracker; 043 044 private final Predicate<PlasticField> MATCHER = new Predicate<PlasticField>() 045 { 046 public boolean accept(PlasticField field) 047 { 048 return field.hasAnnotation(Inject.class) || 049 field.hasAnnotation(javax.inject.Inject.class); 050 } 051 }; 052 053 public InjectWorker(ObjectLocator locator, InjectionProvider2 injectionProvider, OperationTracker tracker) 054 { 055 this.locator = locator; 056 this.injectionProvider = injectionProvider; 057 this.tracker = tracker; 058 } 059 060 public void transform(final PlasticClass plasticClass, TransformationSupport support, final MutableComponentModel model) 061 { 062 for (final PlasticField field : F.flow(plasticClass.getUnclaimedFields()).filter(MATCHER)) 063 { 064 final String fieldName = field.getName(); 065 066 tracker.run(String.format("Injecting field %s.%s", plasticClass.getClassName(), fieldName), new Runnable() 067 { 068 public void run() 069 { 070 try 071 { 072 boolean success = injectionProvider.provideInjection(field, locator, model); 073 074 if (success) 075 { 076 field.claim("@Inject"); 077 } 078 } catch (RuntimeException ex) 079 { 080 throw new RuntimeException(String.format("Error obtaining injected value for field %s.%s: %s", plasticClass.getClassName(), fieldName, ExceptionUtils.toMessage(ex)), ex); 081 } 082 } 083 }); 084 } 085 } 086}