/* * This file is part of LibrePlan * * Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e * Desenvolvemento Tecnolóxico de Galicia * Copyright (C) 2010-2011 Igalia, S.L. * * 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.orders.entities; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.libreplan.business.requirements.entities.CriterionRequirement; import org.libreplan.business.requirements.entities.DirectCriterionRequirement; import org.libreplan.business.requirements.entities.IndirectCriterionRequirement; import org.libreplan.business.resources.entities.Criterion; import org.libreplan.business.templates.entities.OrderElementTemplate; /** * * @author Diego Pino Garcia <dpino@igalia.com> * */ public class CriterionRequirementOrderElementHandler extends CriterionRequirementHandler<OrderElement, OrderLine, OrderLineGroup> { private static final CriterionRequirementOrderElementHandler singleton = new CriterionRequirementOrderElementHandler(); private CriterionRequirementOrderElementHandler() { } public static CriterionRequirementOrderElementHandler getInstance() { return singleton; } @Override protected List<OrderElement> getOrderLineGroupChildren(OrderLineGroup orderLineGroup) { return orderLineGroup.getChildren(); } @Override protected List<OrderElement> getAllChildren(OrderElement orderElement) { return orderElement.getAllChildren(); } @Override protected List<OrderElement> getChildren(OrderElement orderElement) { return orderElement.getChildren(); } @Override protected Set<CriterionRequirement> getCriterionRequirements(OrderElement orderElement) { return orderElement.getCriterionRequirements(); } @Override protected Set<IndirectCriterionRequirement> getIndirectCriterionRequirement(OrderElement orderElement) { return orderElement.getIndirectCriterionRequirement(); } @Override protected void removeCriterionRequirement(OrderElement orderElement, CriterionRequirement criterionRequirement) { orderElement.removeCriterionRequirement(criterionRequirement); } @Override protected List<HoursGroup> getOrderLineHoursGroups(OrderLine orderLine) { return orderLine.getHoursGroups(); } @Override protected Set<DirectCriterionRequirement> getDirectCriterionRequirement(OrderElement orderElement) { return orderElement.getDirectCriterionRequirement(); } @Override protected void basicAddCriterionRequirement(OrderElement orderElement, CriterionRequirement criterionRequirement) { orderElement.basicAddCriterionRequirement(criterionRequirement); } @Override protected List<HoursGroup> getHoursGroups(OrderLine orderline) { return orderline.getHoursGroups(); } @Override protected boolean isOrderLine(OrderElement orderElement) { return (orderElement instanceof OrderLine); } @Override protected OrderLine toOrderLine(OrderElement orderElement) { return (OrderLine) orderElement; } @Override protected OrderLineGroup toOrderLineGroup(OrderElement orderElement) { return (OrderLineGroup) orderElement; } @Override protected OrderElement toOrderElement(OrderLine orderLine) { return (OrderElement) orderLine; } @Override protected Set<DirectCriterionRequirement> getDirectCriterionRequirementFromOrderLineGroup(OrderLineGroup orderLineGroup) { return orderLineGroup.getDirectCriterionRequirement(); } @Override protected void addIndirectCriterionRequirementToOrderLine(OrderLine orderLine, IndirectCriterionRequirement indirect) { orderLine.addIndirectCriterionRequirement(indirect); } @Override protected Set<IndirectCriterionRequirement> getIndirectCriterionRequirementFromOrderLineGroup( OrderLineGroup orderLine) { return orderLine.getIndirectCriterionRequirement(); } @Override protected Set<DirectCriterionRequirement> getDirectCriterionRequirementFromOrderLine(OrderLine orderLine) { return orderLine.getDirectCriterionRequirement(); } @Override protected Set<IndirectCriterionRequirement> getIndirectCriterionRequirementFromOrderLine(OrderLine orderLine) { return orderLine.getIndirectCriterionRequirement(); } @Override protected void basicAddCriterionRequirementIntoOrderLineGroup(OrderLineGroup orderLineGroup, CriterionRequirement criterionRequirement) { orderLineGroup.basicAddCriterionRequirement(criterionRequirement); } @Override protected OrderElement getParent(OrderElement orderElement) { return orderElement.getParent(); } @Override protected boolean isOrderLineGroup(OrderElement orderElement) { return (orderElement instanceof OrderLineGroup); } @Override protected Collection<HoursGroup> myHoursGroups(OrderLine orderline) { return orderline.myHoursGroups(); } /** * For every OrderLineGroup, its {@link DirectCriterionRequirement} are * copied to their children ({@link IndirectCriterionRequirement}). Every entry of * {@link DirectCriterionRequirement} keeps a reference to its original * (_origin_). Original {@link IndirectCriterionRequirement} can be accessed * from _origin_. * * A unique IndirectCriterionRequirements can be referenced knowing two * parameters: {@link OrderElement} or {@link OrderElementTemplate}, and * {@link Criterion}. A map containing the original valid value of an * indirect criterion is created, indexing by order element and criterion. * * Every order element keeps a reference to its template, and vice-versa. So * when propagating a criterion it's possible to know the original value of * valid via the map previously created */ @Override public void copyIndirectCriterionRequirementsFromOriginalToOrderLineGroupChildren( OrderLineGroup orderLineGroup, DirectCriterionRequirement parent) { final List<OrderElement> orderElements = orderLineGroup.getChildren(); final Criterion criterion = parent.getCriterion(); final Set<IndirectCriterionRequirement> originalIndirectCriterionRequirements = parent .getOrigin().getChildren(); final Map<OrderElementTemplate, Map<Criterion, Boolean>> mapTemplateCriterion = createTemplateCriterionMap(originalIndirectCriterionRequirements); for (OrderElement each : orderElements) { Map<Criterion, Boolean> criterionMap = mapTemplateCriterion .get(each.getTemplate()); if (criterionMap != null) { IndirectCriterionRequirement indirect = IndirectCriterionRequirement .create(parent, criterion); indirect.setValid(criterionMap.get(criterion)); addIndirectCriterionRequirement(each, indirect); } if (isOrderLineGroup(each)) { copyIndirectCriterionRequirementsFromOriginalToOrderLineGroupChildren( toOrderLineGroup(each), parent); } } } /** * Map containing {@link IndirectCriterionRequirement} valid attribute, * indexing by {@link OrderElementTemplate} and {@link Criterion} * * @param indirects * @return */ private Map<OrderElementTemplate, Map<Criterion, Boolean>> createTemplateCriterionMap( Set<IndirectCriterionRequirement> indirects) { Map<OrderElementTemplate, Map<Criterion, Boolean>> result = new HashMap<OrderElementTemplate, Map<Criterion, Boolean>>(); for (IndirectCriterionRequirement each: indirects) { final OrderElementTemplate template = each.getOrderElementTemplate(); if (template != null) { Map<Criterion, Boolean> value = result.get(template); if (value == null) { value = new HashMap<Criterion, Boolean>(); } value.put(each.getCriterion(), each.isValid()); result.put(template, value); } } return result; } }