/* * 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.web.orders.labels; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.libreplan.business.common.IAdHocTransactionService; import org.libreplan.business.common.IOnTransaction; import org.libreplan.business.labels.daos.ILabelDAO; import org.libreplan.business.labels.entities.Label; import org.libreplan.business.labels.entities.LabelType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.transaction.annotation.Transactional; /** * @author Óscar González Fernández <ogonzalez@igalia.com> */ public abstract class AssignedLabelsModel<T> implements IAssignedLabelsModel<T> { @Autowired private ILabelDAO labelDAO; private T element; @Autowired private IAdHocTransactionService adHocTransactionService; @Transactional(readOnly = true) public void init(T element) { this.element = element; initializeElementAndChildren(this.element); } private void initializeElementAndChildren(T element) { reattachLabels(); initialize(element); T current = getParent(element); while (current != null) { initialize(current); current = getParent(current); } initializeChildren(element); } protected abstract T getParent(T element); private void initializeChildren(T element) { initialize(element); for (T child : getChildren(element)) { initializeChildren(child); } } protected abstract List<T> getChildren(T element); private void initialize(T orderElement) { reattach(orderElement); initializeLabels(getLabels(orderElement)); } protected abstract List<Label> getLabels(T orderElement); protected abstract void reattach(T element); private void reattachLabels() { for (Label label : getLabelsOnConversation()) { labelDAO.reattach(label); } } protected abstract List<Label> getLabelsOnConversation(); private void initializeLabels(Collection<Label> labels) { for (Label label : labels) { initializeLabel(label); } } public void initializeLabel(Label label) { label.getName(); label.getType().getName(); } @Transactional(readOnly = true) public List<Label> getLabels() { List<Label> result = new ArrayList<>(); if (element != null && getLabels(element) != null) { reattachLabels(); result.addAll(getLabels(element)); } return result; } @Transactional(readOnly = true) public List<Label> getInheritedLabels() { List<Label> result = new ArrayList<>(); if (element != null) { reattachLabels(); T parent = getParent(element); while (parent != null) { result.addAll(getLabels(parent)); parent = getParent(parent); } } return result; } @Transactional(readOnly = true) public Label createLabel(final String labelName, final LabelType labelType) { Label label = createAndSaveLabelOrGetFromDatabase(labelName, labelType); addLabelToConversation(label); return label; } private Label createAndSaveLabelOrGetFromDatabase(final String labelName, final LabelType labelType) { Label label; try { label = saveLabelOnAnotherTransaction(labelName, labelType); label.dontPoseAsTransientObjectAnymore(); } catch (DataIntegrityViolationException e) { // Label was already created by another user while editing the order label = labelDAO.findByNameAndType(labelName, labelType); forceLoad(label); } return label; } private Label saveLabelOnAnotherTransaction(final String labelName, final LabelType labelType) { return adHocTransactionService.runOnAnotherTransaction(new IOnTransaction<Label>() { @Override public Label execute() { Label label = Label.create(labelName); label.setType(labelType); labelDAO.save(label); return label; } }); } private void forceLoad(Label label) { label.getType().getName(); } protected abstract void addLabelToConversation(Label label); @Transactional(readOnly = true) public void assignLabel(Label label) { reattachLabels(); addLabelToElement(element, label); } protected abstract void addLabelToElement(T element, Label label); @Transactional(readOnly = true) public void deleteLabel(Label label) { reattachLabels(); removeLabel(element, label); } protected abstract void removeLabel(T element, Label label); @Transactional(readOnly = true) public Label findLabelByNameAndType(String labelName, LabelType labelType) { Label label = findLabelByNameAndTypeName(labelName, labelType.getName()); if (label != null) { initializeLabel(label); } return label; } /** * Search {@link Label} by name and type in cache of labels. * * @param labelName * @param labelTypeName * @return {@link Label} */ private Label findLabelByNameAndTypeName(String labelName, String labelTypeName) { for (Label label : getLabelsOnConversation()) { if (label.getName().equals(labelName) && label.getType().getName().equals(labelTypeName)) { return label; } } return null; } public boolean isAssigned(Label label) { for (Label each : getLabels(element)) { if (each.getId().equals(label.getId())) { return true; } } return false; } @Transactional(readOnly = true) public List<Label> getAllLabels() { return getLabelsOnConversation(); } }