Package org.libreplan.business.planner.entities

Source Code of org.libreplan.business.planner.entities.AssignedEffortForResource$IAssignedEffortForResource

/*
* This file is part of LibrePlan
*
* Copyright (C) 2012 Óscar González Fernández
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.libreplan.business.planner.entities;

import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.joda.time.LocalDate;
import org.libreplan.business.common.BaseEntity;
import org.libreplan.business.resources.entities.Resource;
import org.libreplan.business.workingday.EffortDuration;

/**
* This class contains methods to build an {@link IAssignedEffortForResource}.
*
* @author Oscar Gonzalez Fernandez <ogfernandez@gmail.com>
*/
public class AssignedEffortForResource {

    /**
     * It allows to know how much load a Resource has at the given day. It's
     * used by {@link GenericResourceAllocation} so it distributes new load
     * among the least loaded resources. The right object implementing this
     * interface is built using factory methods from
     * {@link AssignedEffortForResource}.
     *
     * @see AssignedEffortForResource#sum(IAssignedEffortForResource...)
     * @see AssignedEffortForResource#withTheLoadOf(Collection)
     */
    public interface IAssignedEffortForResource {

        public EffortDuration getAssignedDurationAt(Resource resource,
                LocalDate day);
    }

    private AssignedEffortForResource() {
        // not instantiable
    }

    /**
     * It returns a new {@link IAssignedEffortForResource} that looks into
     * {@link Resource#dayAssignments} for knowing which load the
     * {@link Resource} has for a given day.
     *
     * Sometimes we have to discount the load of some allocations that are being
     * removed or changed. They can be provided to this method.
     *
     * @param allocations
     *            The allocations whose load shouldn't be summed.
     * @return A {@link IAssignedEffortForResource} that calculates the load
     *         associated for all allocations but the provided ones.
     */
    public static IAssignedEffortForResource effortDiscounting(
            Collection<? extends BaseEntity> allocations) {
        return new AssignedEffortDiscounting(allocations);
    }

    /**
     * It creates a new {@link IAssignedEffortForResource} that sums all
     * provided {@link IAssignedEffortForResource}. Sometimes you have to
     * combine several {@link IAssignedEffortForResource} to calculate the right
     * effort.
     * @param assignedEffortForResources
     *            The {@link IAssignedEffortForResource} to sum.
     * @return a {@link IAssignedEffortForResource} that returns the sum of
     *         calling all provided <code>assignedEffortForResources</code>.
     */
    public static IAssignedEffortForResource sum(
            final IAssignedEffortForResource... assignedEffortForResources) {
        return new IAssignedEffortForResource() {

            @Override
            public EffortDuration getAssignedDurationAt(Resource resource,
                    LocalDate day) {
                EffortDuration result = EffortDuration.zero();
                for (IAssignedEffortForResource each : assignedEffortForResources) {
                    EffortDuration e = each
                            .getAssignedDurationAt(resource, day);
                    if (e != null) {
                        result = result.plus(e);
                    }
                }
                return result;
            }
        };
    }

    /**
     * @see AssignedEffortForResource#sum(IAssignedEffortForResource...)
     */
    public static IAssignedEffortForResource sum(
            Collection<? extends IAssignedEffortForResource> assignedEffortForResources) {
        return sum(assignedEffortForResources
                .toArray(new IAssignedEffortForResource[0]));
    }

    public static WithTheLoadOf withTheLoadOf(
            Collection<? extends ResourceAllocation<?>> allocations) {
        return new WithTheLoadOf(allocations);
    }

    /**
     * This class allows to specify the load of some {@link ResourceAllocation
     * resource allocations} which their {@link DayAssignment day assignments}
     * aren't associated to a Resource yet. Without this, their load wouldn't be
     * noticed.
     */
    public static class WithTheLoadOf implements IAssignedEffortForResource {

        private final Set<? extends ResourceAllocation<?>> allocations;
        private final IAssignedEffortForResource implementation;

        public WithTheLoadOf(
                Collection<? extends ResourceAllocation<?>> allocations) {
            this.allocations = new HashSet<ResourceAllocation<?>>(allocations);
            this.implementation = sum(this.allocations);
        }

        @Override
        public EffortDuration getAssignedDurationAt(Resource resource,
                LocalDate day) {
            return implementation.getAssignedDurationAt(resource, day);
        }

        /**
         * It returns a {@link IAssignedEffortForResource} that returns the same
         * load as <code>this</code> but without the provided
         * <code>allocation</code>. When you're doing an allocation you don't
         * want to consider the allocation currently being done, so it's
         * excluded.
         */
        public WithTheLoadOf withoutConsidering(ResourceAllocation<?> allocation) {
            Set<ResourceAllocation<?>> copy = new HashSet<ResourceAllocation<?>>(
                    this.allocations);
            copy.remove(allocation);
            return new WithTheLoadOf(copy);
        }
    }

    private static class AssignedEffortDiscounting implements
            IAssignedEffortForResource {

        private final Map<Long, Set<BaseEntity>> allocations;

        AssignedEffortDiscounting(Collection<? extends BaseEntity> discountFrom) {
            this.allocations = BaseEntity.byId(discountFrom);
        }

        public EffortDuration getAssignedDurationAt(Resource resource,
                LocalDate day) {
            return resource.getAssignedDurationDiscounting(allocations, day);
        }
    }

}
TOP

Related Classes of org.libreplan.business.planner.entities.AssignedEffortForResource$IAssignedEffortForResource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.