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 015 package org.apache.tapestry5.internal.transform; 016 017 import org.apache.tapestry5.func.F; 018 import org.apache.tapestry5.func.Predicate; 019 import org.apache.tapestry5.ioc.ObjectLocator; 020 import org.apache.tapestry5.ioc.OperationTracker; 021 import org.apache.tapestry5.ioc.annotations.Inject; 022 import org.apache.tapestry5.model.MutableComponentModel; 023 import org.apache.tapestry5.plastic.PlasticClass; 024 import org.apache.tapestry5.plastic.PlasticField; 025 import org.apache.tapestry5.services.transform.ComponentClassTransformWorker2; 026 import org.apache.tapestry5.services.transform.InjectionProvider2; 027 import 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 */ 035 public 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 }