/** * Copyright © 2002 Instituto Superior Técnico * * This file is part of FenixEdu Academic. * * FenixEdu Academic is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * FenixEdu Academic 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with FenixEdu Academic. If not, see <http://www.gnu.org/licenses/>. */ package org.fenixedu.academic.domain.accessControl; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Set; import java.util.stream.Stream; import org.fenixedu.academic.domain.Person; import org.fenixedu.academic.domain.organizationalStructure.Accountability; import org.fenixedu.academic.domain.organizationalStructure.AccountabilityTypeEnum; import org.fenixedu.academic.domain.organizationalStructure.Party; import org.fenixedu.academic.domain.organizationalStructure.Unit; import org.fenixedu.academic.util.Bundle; import org.fenixedu.bennu.core.annotation.GroupArgument; import org.fenixedu.bennu.core.annotation.GroupOperator; import org.fenixedu.bennu.core.domain.User; import org.fenixedu.bennu.core.domain.groups.PersistentGroup; import org.fenixedu.bennu.core.i18n.BundleUtil; import org.joda.time.DateTime; import org.joda.time.YearMonthDay; import com.google.common.base.Objects; @GroupOperator("unit") public class UnitGroup extends FenixGroup { private static final long serialVersionUID = 3393643895062911436L; @GroupArgument private Unit unit; @GroupArgument private AccountabilityTypeEnum relationType; @GroupArgument private Boolean includeSubUnits; private UnitGroup() { super(); } private UnitGroup(Unit unit, AccountabilityTypeEnum relationType, Boolean includeSubUnits) { this(); this.unit = unit; this.relationType = relationType; this.includeSubUnits = includeSubUnits; } public static UnitGroup recursiveWorkers(Unit unit) { return new UnitGroup(unit, AccountabilityTypeEnum.WORKING_CONTRACT, true); } public static UnitGroup workers(Unit unit) { return new UnitGroup(unit, AccountabilityTypeEnum.WORKING_CONTRACT, false); } public static UnitGroup get(Unit unit, AccountabilityTypeEnum relationType, Boolean includeSubUnits) { return new UnitGroup(unit, relationType, includeSubUnits); } public Unit getUnit() { return unit; } @Override public String[] getPresentationNameKeyArgs() { ArrayList<String> args = new ArrayList<String>(); args.add(unit.getNameI18n().getContent()); String type = ""; if (relationType != null) { type = BundleUtil.getString(Bundle.GROUP, "label.name.unit.connector.relation") + relationType.getLocalizedName(); } args.add(type); String subunits = ""; if (includeSubUnits) { subunits = BundleUtil.getString(Bundle.GROUP, "label.name.unit.subunits"); } args.add(subunits); return args.toArray(new String[3]); } @Override public Stream<User> getMembers() { return getMembers(new DateTime()); } @Override public Stream<User> getMembers(DateTime when) { Set<User> users = new HashSet<>(); collect(users, unit, when); return users.stream(); } private void collect(Set<User> users, Unit unit, DateTime when) { Collection<? extends Accountability> accs; if (relationType != null) { accs = unit.getChildAccountabilities(relationType); } else { accs = unit.getChildsSet(); } for (Accountability accountability : accs) { if (accountability.isActive(when.toYearMonthDay())) { Party party = accountability.getChildParty(); if (party instanceof Person) { User user = ((Person) party).getUser(); if (user != null) { users.add(user); } } } } if (includeSubUnits) { for (Unit subUnit : unit.getSubUnits()) { collect(users, subUnit, when); } } } @Override public boolean isMember(User user) { return isMember(user, new DateTime()); } @Override public boolean isMember(User user, DateTime when) { if (user == null) { return false; } YearMonthDay whenYMD = when.toYearMonthDay(); for (Accountability accountability : user.getPerson().getParentsSet()) { if (accountability.getAccountabilityType().getType() == relationType && accountability.isActive(whenYMD)) { if (accountability.getParentParty().equals(unit)) { return true; } else if (includeSubUnits && isAncestor(unit, accountability.getParentParty(), relationType, whenYMD)) { return true; } } } return false; } private boolean isAncestor(Party possibleAncestor, Party possibleChild, AccountabilityTypeEnum subUnitRecursionType, YearMonthDay when) { if (possibleChild == null) { return false; } if (possibleChild.equals(possibleAncestor)) { return true; } for (Accountability acc : possibleChild.getParentsSet()) { if (acc.getParentParty() instanceof Unit && acc.isActive(when) && isAncestor(possibleAncestor, acc.getParentParty(), subUnitRecursionType, when)) { return true; } } return false; } @Override public PersistentGroup toPersistentGroup() { return PersistentUnitGroup.getInstance(unit, relationType, includeSubUnits); } @Override public boolean equals(Object object) { if (object instanceof UnitGroup) { UnitGroup other = (UnitGroup) object; return Objects.equal(unit, other.unit) && Objects.equal(relationType, other.relationType) && Objects.equal(includeSubUnits, other.includeSubUnits); } return false; } @Override public int hashCode() { return Objects.hashCode(unit, relationType, includeSubUnits); } }