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