/**
* 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.academicAdministration;
import java.util.Collections;
import java.util.Comparator;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.fenixedu.academic.domain.AcademicProgram;
import org.fenixedu.academic.domain.accessControl.academicAdministration.AcademicAccessRule.AcademicAccessTarget;
import org.fenixedu.academic.domain.accessControl.academicAdministration.AcademicAccessRule.AcademicProgramAccessTarget;
import org.fenixedu.academic.domain.accessControl.academicAdministration.AcademicAccessRule.AdministrativeOfficeAccessTarget;
import org.fenixedu.academic.domain.accessControl.rules.AccessOperation;
import org.fenixedu.academic.domain.administrativeOffice.AdministrativeOffice;
import org.fenixedu.academic.util.Bundle;
import org.fenixedu.bennu.core.domain.User;
import org.fenixedu.bennu.core.groups.Group;
import org.fenixedu.bennu.core.i18n.BundleUtil;
import pt.ist.fenixWebFramework.rendererExtensions.util.IPresentableEnum;
import com.google.common.collect.Sets;
public enum AcademicOperationType implements IPresentableEnum, AccessOperation<AcademicAccessRule, AcademicAccessTarget> {
MANAGE_AUTHORIZATIONS(false, false, Scope.ADMINISTRATION),
MANAGE_EQUIVALENCES(true, true, Scope.ADMINISTRATION), // Migrated from Manager
MANAGE_ACADEMIC_CALENDARS(false, false, Scope.ADMINISTRATION), // Migrated from Manager
/*
* Student stuff
*/
EDIT_STUDENT_PERSONAL_DATA(true, true, Scope.OFFICE),
STUDENT_ENROLMENTS(true, true, Scope.OFFICE),
MANAGE_REGISTRATIONS(true, true, Scope.OFFICE),
MANAGE_STATUTES(false, false, Scope.OFFICE),
MANAGE_CONCLUSION(true, true, Scope.OFFICE),
UPDATE_REGISTRATION_AFTER_CONCLUSION(true, true, Scope.OFFICE),
REPEAT_CONCLUSION_PROCESS(true, true, Scope.OFFICE),
ENROLMENT_WITHOUT_RULES(true, true, Scope.OFFICE),
MOVE_CURRICULUM_LINES_WITHOUT_RULES(true, true, Scope.OFFICE),
REPORT_STUDENTS_UTL_CANDIDATES(true, true, Scope.ADMINISTRATION),
MANAGE_REGISTERED_DEGREE_CANDIDACIES(true, true, Scope.ADMINISTRATION),
MANAGE_ENROLMENT_PERIODS(true, true, Scope.ADMINISTRATION), // Migrated from Manager
/*
* Mark Sheets
*/
MANAGE_MARKSHEETS(true, true, Scope.ADMINISTRATION),
RECTIFICATION_MARKSHEETS(true, true, Scope.ADMINISTRATION),
REMOVE_GRADES(true, true, Scope.ADMINISTRATION), // Migrated from Manager
DISSERTATION_MARKSHEETS(true, true, Scope.ADMINISTRATION),
REGISTRATION_CONCLUSION_CURRICULUM_VALIDATION(true, true, Scope.OFFICE),
CREATE_REGISTRATION(true, true, Scope.OFFICE),
STUDENT_LISTINGS(true, true, Scope.ADMINISTRATION),
SERVICE_REQUESTS(true, true, Scope.OFFICE),
SERVICE_REQUESTS_RECTORAL_SENDING(true, true, Scope.OFFICE),
MANAGE_EXECUTION_COURSES(true, true, Scope.ADMINISTRATION), // Migrated from Manager
MANAGE_EXECUTION_COURSES_ADV(true, true, Scope.ADMINISTRATION), // Migrated from Manager
MANAGE_DEGREE_CURRICULAR_PLANS(true, true, Scope.ADMINISTRATION),
MANAGE_EVENT_REPORTS(true, false, Scope.ADMINISTRATION),
// Student Section
MANAGE_STUDENT_PAYMENTS(true, false, Scope.OFFICE),
MANAGE_STUDENT_PAYMENTS_ADV(true, true, Scope.ADMINISTRATION), // Migrated from Manager
CREATE_SIBS_PAYMENTS_REPORT(false, false, Scope.ADMINISTRATION), // Migrated from Manager
MANAGE_ACCOUNTING_EVENTS(true, true, Scope.OFFICE),
/* End of Payments */
MANAGE_PRICES(true, false, Scope.ADMINISTRATION),
MANAGE_EXTRA_CURRICULAR_ACTIVITIES(false, false, Scope.ADMINISTRATION),
MANAGE_EXTERNAL_UNITS(false, false, Scope.ADMINISTRATION),
/* Candidacies Management */
MANAGE_INDIVIDUAL_CANDIDACIES(true, true, Scope.ADMINISTRATION),
MANAGE_CANDIDACY_PROCESSES(true, true, Scope.ADMINISTRATION),
/* End of Candidacies Management */
VIEW_FULL_STUDENT_CURRICULUM(true, true, Scope.OFFICE),
MANAGE_DOCUMENTS(true, true, Scope.OFFICE),
/* Phd Management */
VIEW_PHD_CANDIDACY_ALERTS(true, true, Scope.OFFICE),
VIEW_PHD_PUBLIC_PRESENTATION_ALERTS(true, true, Scope.OFFICE),
VIEW_PHD_THESIS_ALERTS(true, true, Scope.OFFICE),
MANAGE_PHD_ENROLMENT_PERIODS(true, true, Scope.OFFICE),
MANAGE_PHD_PROCESSES(true, true, Scope.OFFICE),
MANAGE_PHD_PROCESS_STATE(true, true, Scope.OFFICE),
MANAGE_MOBILITY_OUTBOUND(false, false, Scope.ADMINISTRATION),
VALIDATE_MOBILITY_OUTBOUND_CANDIDACIES(false, false, Scope.ADMINISTRATION),
VIEW_SCHEDULING_OVERSIGHT(false, false, Scope.ADMINISTRATION),
/* MANAGE TEACHER AUTHORIZATIONS */
MANAGE_TEACHER_AUTHORIZATIONS(false, false, Scope.ADMINISTRATION),
MANAGE_TEACHER_PROFESSORSHIPS(false, false, Scope.ADMINISTRATION),
SUMMARIES_CONTROL(false, false, Scope.ADMINISTRATION);
public static enum Scope {
OFFICE, ADMINISTRATION;
public boolean contains(AcademicOperationType function) {
if (function instanceof AcademicOperationType) {
return function.scope == this;
}
return false;
}
}
private boolean allowOffices;
private boolean allowPrograms;
private Scope scope;
static public Comparator<AcademicOperationType> COMPARATOR_BY_LOCALIZED_NAME = new Comparator<AcademicOperationType>() {
@Override
public int compare(final AcademicOperationType p1, final AcademicOperationType p2) {
String operationName1 = p1.getLocalizedName();
String operationName2 = p2.getLocalizedName();
int res = operationName1.compareTo(operationName2);
return res;
}
};
private AcademicOperationType(boolean allowOffices, boolean allowPrograms, Scope scope) {
this.allowOffices = allowOffices;
this.allowPrograms = allowPrograms;
this.scope = scope;
}
public boolean isOfficeAllowedAsTarget() {
return allowOffices;
}
public boolean isProgramAllowedAsTarget() {
return allowPrograms;
}
public boolean isOfScope(Scope scope) {
return this.scope.equals(scope);
}
@Override
public String getLocalizedName() {
return BundleUtil.getString(Bundle.ENUMERATION, getClass().getName() + "." + name());
}
@Override
public String exportAsString() {
return getClass().getName() + ":" + name();
}
@Override
public Optional<AcademicAccessRule> grant(Group whoCanAccess, Set<AcademicAccessTarget> whatCanAffect) {
if (whoCanAccess.equals(Group.nobody())) {
return Optional.empty();
}
Optional<AcademicAccessRule> match =
AcademicAccessRule
.accessRules()
.filter(r -> r.getOperation().equals(this) && r.getWhoCanAccess().equals(whoCanAccess)
&& Sets.symmetricDifference(r.getWhatCanAffect(), whatCanAffect).isEmpty()).findAny();
return Optional.of(match.orElseGet(() -> new AcademicAccessRule(this, whoCanAccess, whatCanAffect)));
}
public Optional<AcademicAccessRule> grant(Group whoCanAccess, Set<AcademicProgram> programs, Set<AdministrativeOffice> offices) {
Set<AcademicAccessTarget> targets =
Stream.concat(programs.stream().map(AcademicProgramAccessTarget::new),
offices.stream().map(AdministrativeOfficeAccessTarget::new)).collect(Collectors.toSet());
return grant(whoCanAccess, targets);
}
@Override
public Optional<AcademicAccessRule> grant(User user) {
Optional<AcademicAccessRule> match =
AcademicAccessRule.accessRules().filter(r -> r.getOperation().equals(this) && r.getWhatCanAffect().isEmpty())
.findAny();
return match.map(r -> r.<AcademicAccessRule> grant(user)).orElseGet(
() -> Optional.of(new AcademicAccessRule(this, user.groupOf(), Collections.emptySet())));
}
@Override
public Optional<AcademicAccessRule> revoke(User user) {
Optional<AcademicAccessRule> match =
AcademicAccessRule.accessRules().filter(r -> r.getOperation().equals(this) && r.getWhatCanAffect().isEmpty())
.findAny();
return match.map(r -> r.<AcademicAccessRule> revoke(user)).orElse(Optional.empty());
}
}