001// Copyright 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.ioc.internal.util;
016
017import org.apache.tapestry5.commons.ObjectCreator;
018import org.apache.tapestry5.commons.util.CollectionFactory;
019import org.apache.tapestry5.ioc.Invokable;
020import org.apache.tapestry5.ioc.OperationTracker;
021
022import java.util.List;
023
024/**
025 * Encapsulates the initial construction of an object instance, followed by a series
026 * {@link InitializationPlan}s to initialize fields and invoke other methods of the constructed object.
027 *
028 * @since 5.3
029 */
030public class ConstructionPlan<T> implements ObjectCreator<T>
031{
032    private final OperationTracker tracker;
033
034    private final String description;
035
036    private final Invokable<T> instanceConstructor;
037
038    private List<InitializationPlan> initializationPlans;
039
040    public ConstructionPlan(OperationTracker tracker, String description, Invokable<T> instanceConstructor)
041    {
042        this.tracker = tracker;
043        this.description = description;
044        this.instanceConstructor = instanceConstructor;
045    }
046
047    public ConstructionPlan add(InitializationPlan plan)
048    {
049        if (initializationPlans == null)
050        {
051            initializationPlans = CollectionFactory.newList();
052        }
053
054        initializationPlans.add(plan);
055
056        return this;
057    }
058
059    @Override
060    public T createObject()
061    {
062        T result = tracker.invoke(description, instanceConstructor);
063
064        if (initializationPlans != null)
065        {
066            executeInitializationPLans(result);
067        }
068
069        return result;
070    }
071
072    private void executeInitializationPLans(final T newInstance)
073    {
074        for (final InitializationPlan<T> plan : initializationPlans)
075        {
076            tracker.run(plan.getDescription(), new Runnable()
077            {
078                @Override
079                public void run()
080                {
081                    plan.initialize(newInstance);
082                }
083            });
084        }
085    }
086}