Package org.fenixedu.academic.domain.organizationalStructure

Source Code of org.fenixedu.academic.domain.organizationalStructure.Unit

/**
* 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/>.
*/
/*
* Created on Sep 16, 2005
*  by mrsp
*/
package org.fenixedu.academic.domain.organizationalStructure;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import org.apache.commons.lang.StringUtils;
import org.fenixedu.academic.domain.Country;
import org.fenixedu.academic.domain.Degree;
import org.fenixedu.academic.domain.Department;
import org.fenixedu.academic.domain.ExternalCurricularCourse;
import org.fenixedu.academic.domain.NonAffiliatedTeacher;
import org.fenixedu.academic.domain.Person;
import org.fenixedu.academic.domain.UnitFile;
import org.fenixedu.academic.domain.UnitFileTag;
import org.fenixedu.academic.domain.accessControl.MembersLinkGroup;
import org.fenixedu.academic.domain.accessControl.PersistentGroupMembers;
import org.fenixedu.academic.domain.administrativeOffice.AdministrativeOffice;
import org.fenixedu.academic.domain.exceptions.DomainException;
import org.fenixedu.academic.domain.util.email.UnitBasedSender;
import org.fenixedu.academic.predicate.AccessControl;
import org.fenixedu.academic.util.Bundle;
import org.fenixedu.academic.util.domain.OrderedRelationAdapter;
import org.fenixedu.bennu.core.domain.Bennu;
import org.fenixedu.bennu.core.groups.Group;
import org.fenixedu.bennu.core.i18n.BundleUtil;
import org.fenixedu.commons.StringNormalizer;
import org.fenixedu.spaces.domain.Space;
import org.joda.time.YearMonthDay;

import pt.ist.fenixframework.Atomic;
import pt.utl.ist.fenix.tools.util.i18n.MultiLanguageString;

public class Unit extends Unit_Base {

    public static OrderedRelationAdapter<Unit, Function> FUNCTION_ORDERED_ADAPTER;
    static {
        FUNCTION_ORDERED_ADAPTER = new OrderedRelationAdapter<Unit, Function>("activeFunctions", "functionOrder");
        getRelationUnitFunction().addListener(FUNCTION_ORDERED_ADAPTER);
    }

    protected Unit() {
        super();
    }

    protected void init(MultiLanguageString name, String unitNameCard, Integer costCenterCode, String acronym,
            YearMonthDay beginDate, YearMonthDay endDate, String webAddress, UnitClassification classification,
            AdministrativeOffice administrativeOffice, Boolean canBeResponsibleOfSpaces, Space campus) {

        setPartyName(name);
        if (acronym != null) {
            setAcronym(acronym);
        }
        if (getCostCenterCode() == null || !getCostCenterCode().equals(costCenterCode)) {
            setCostCenterCode(costCenterCode);
        }
        setIdentificationCardLabel(unitNameCard);
        setBeginDateYearMonthDay(beginDate);
        setEndDateYearMonthDay(endDate);
        setClassification(classification);
        setAdministrativeOffice(administrativeOffice);
        setCanBeResponsibleOfSpaces(canBeResponsibleOfSpaces);
        setCampus(campus);
        setDefaultWebAddressUrl(webAddress);
    }

    @Override
    public void setPartyName(MultiLanguageString partyName) {
        if (partyName == null || partyName.isEmpty()) {
            throw new DomainException("error.Party.empty.partyName");
        }
        super.setPartyName(partyName);
        setName(partyName.getPreferedContent());
    }

    @Override
    public String getName() {
        return getPartyName().getPreferedContent();
    }

    @Override
    public void setName(String name) {

        if (name == null || StringUtils.isEmpty(name.trim())) {
            throw new DomainException("error.person.empty.name");
        }

        MultiLanguageString partyName = getPartyName();

        partyName =
                partyName == null ? new MultiLanguageString(Locale.getDefault(), name) : partyName
                        .with(Locale.getDefault(), name);

        super.setPartyName(partyName);

        UnitName unitName = getUnitName();
        unitName = unitName == null ? new UnitName(this) : unitName;
        unitName.setName(name);
    }

    public void edit(MultiLanguageString name, String acronym) {
        setPartyName(name);
        setAcronym(acronym);
    }

    public void edit(MultiLanguageString unitName, String unitNameCard, Integer unitCostCenter, String acronym,
            YearMonthDay beginDate, YearMonthDay endDate, String webAddress, UnitClassification classification,
            Department department, Degree degree, AdministrativeOffice administrativeOffice, Boolean canBeResponsibleOfSpaces,
            Space campus) {

        init(unitName, unitNameCard, unitCostCenter, acronym, beginDate, endDate, webAddress, classification,
                administrativeOffice, canBeResponsibleOfSpaces, campus);
    }

    @Override
    public void setCanBeResponsibleOfSpaces(Boolean canBeResponsibleOfSpaces) {
        super.setCanBeResponsibleOfSpaces(canBeResponsibleOfSpaces != null ? canBeResponsibleOfSpaces : Boolean.FALSE);
    }

    public void setCostCenterCode(Integer costCenterCode) {
        final UnitCostCenterCode otherUnitCostCenterCode = UnitCostCenterCode.find(costCenterCode);
        if (otherUnitCostCenterCode != null && otherUnitCostCenterCode.getUnit() != this) {
            throw new DomainException("error.costCenter.alreadyExists");
        }
        final UnitCostCenterCode unitCostCenterCode = getUnitCostCenterCode();
        if (unitCostCenterCode == null && costCenterCode != null) {
            new UnitCostCenterCode(this, costCenterCode);
        } else if (unitCostCenterCode != null && costCenterCode != null) {
            unitCostCenterCode.setCostCenterCode(costCenterCode);
        } else if (unitCostCenterCode != null && costCenterCode == null) {
            unitCostCenterCode.delete();
        }
    }

    public Integer getCostCenterCode() {
        final UnitCostCenterCode unitCostCenterCode = getUnitCostCenterCode();
        return unitCostCenterCode == null ? null : unitCostCenterCode.getCostCenterCode();
    }

    @jvstm.cps.ConsistencyPredicate
    protected boolean checkDateInterval() {
        final YearMonthDay start = getBeginDateYearMonthDay();
        final YearMonthDay end = getEndDateYearMonthDay();
        return start != null && (end == null || !start.isAfter(end));
    }

    @Override
    public void delete() {

        DomainException.throwWhenDeleteBlocked(getDeletionBlockers());

        if (hasAnyParentUnits()) {
            getParentsSet().iterator().next().delete();
        }

        for (; !getUnitFileTagsSet().isEmpty(); getUnitFileTagsSet().iterator().next().delete()) {
            ;
        }

        getUnitName().delete();
        getAllowedPeopleToUploadFilesSet().clear();

        setRootDomainObjectForEarthUnit(null);
        setRootDomainObjectForExternalInstitutionUnit(null);
        setRootDomainObjectForInstitutionUnit(null);
        setCampus(null);
        setUnitAcronym(null);
        setAdministrativeOffice(null);
        super.delete();
    }

    @Override
    protected void checkForDeletionBlockers(Collection<String> blockers) {
        super.checkForDeletionBlockers(blockers);
        if (!(getParentsSet().isEmpty() || (getParentsSet().size() == 1 && getParentUnits().size() == 1))
                && getChildsSet().isEmpty() && getFunctionsSet().isEmpty()) {
            blockers.add(BundleUtil.getString(Bundle.APPLICATION, "error.unit.cannot.be.deleted"));
        }
        if (!(getUnitServiceAgreementTemplate() == null && getOwnedReceiptsSet().isEmpty())) {
            blockers.add(BundleUtil.getString(Bundle.APPLICATION, "error.unit.cannot.be.deleted"));
        }

        if (!(getAssociatedNonAffiliatedTeachersSet().isEmpty() && getExternalCurricularCoursesSet().isEmpty()
                && getPrecedentDegreeInformationsSet().isEmpty() && getCandidacyPrecedentDegreeInformationsSet().isEmpty()
                && getExternalRegistrationDatasSet().isEmpty() && getFilesSet().isEmpty() && getPersistentGroupsSet().isEmpty()
                && getExternalCourseLoadRequestsSet().isEmpty() && getExternalProgramCertificateRequestsSet().isEmpty() && getUnitGroupSet()
                .isEmpty())) {
            blockers.add(BundleUtil.getString(Bundle.APPLICATION, "error.unit.cannot.be.deleted"));
        }
    }

    @Override
    public Space getCampus() {

        Space campus = super.getCampus();

        if (campus != null) {
            return campus;
        }

        Collection<Unit> parentUnits = getParentUnits();
        if (parentUnits.size() == 1) {
            campus = parentUnits.iterator().next().getCampus();
        }

        return campus;
    }

    public boolean isInternal() {
        if (this.equals(UnitUtils.readInstitutionUnit())) {
            return true;
        }

        for (final Unit parentUnit : getParentUnits()) {
            if (parentUnit.isInternal()) {
                return true;
            }
        }

        return false;
    }

    public boolean isNoOfficialExternal() {
        if (this.equals(UnitUtils.readExternalInstitutionUnit())) {
            return true;
        }
        for (final Unit parentUnit : getParentUnits()) {
            if (parentUnit.isNoOfficialExternal()) {
                return true;
            }
        }
        return false;
    }

    public boolean isOfficialExternal() {
        return !isInternal() && !isNoOfficialExternal();
    }

    public boolean isActive(YearMonthDay currentDate) {
        return (!this.getBeginDateYearMonthDay().isAfter(currentDate) && (this.getEndDateYearMonthDay() == null || !this
                .getEndDateYearMonthDay().isBefore(currentDate)));
    }

    @Override
    public boolean isUnit() {
        return true;
    }

    public List<Unit> getTopUnits() {
        Unit unit = this;
        List<Unit> allTopUnits = new ArrayList<Unit>();
        if (unit.hasAnyParentUnits()) {
            for (Unit parentUnit : this.getParentUnits()) {
                if (!parentUnit.hasAnyParentUnits() && !allTopUnits.contains(parentUnit)) {
                    allTopUnits.add(parentUnit);
                } else if (parentUnit.hasAnyParentUnits()) {
                    for (Unit parentUnit2 : parentUnit.getTopUnits()) {
                        if (!allTopUnits.contains(parentUnit2)) {
                            allTopUnits.add(parentUnit2);
                        }
                    }
                }
            }
        }
        return allTopUnits;
    }

    public Department getDepartment() {
        return null;
    }

    public Degree getDegree() {
        return null;
    }

    public DepartmentUnit getDepartmentUnit() {
        if (this.isDepartmentUnit()) {
            return (DepartmentUnit) this;
        } else {
            for (Unit parentUnit : getParentUnits()) {
                if (parentUnit.isDepartmentUnit()) {
                    return (DepartmentUnit) parentUnit;
                } else if (parentUnit.hasAnyParentUnits()) {
                    Unit departmentUnit = parentUnit.getDepartmentUnit();
                    if (departmentUnit == null) {
                        continue;
                    } else {
                        return (DepartmentUnit) departmentUnit;
                    }
                }
            }
        }
        return null;
    }

    final public Collection<Function> getFunctions(final FunctionType functionType) {
        final Collection<Function> result = new HashSet<Function>();

        for (Function function : super.getFunctionsSet()) {
            if (function.getFunctionType() == functionType) {
                result.add(function);
            }
        }

        return result;
    }

    final public Function getUnitCoordinatorFunction() {
        final Collection<Function> possibleCoordinators = getFunctions(FunctionType.ASSIDUOUSNESS_RESPONSIBLE);
        if (possibleCoordinators.isEmpty()) {
            throw new DomainException("Unit.no.one.entitled.to.be.unit.coordinator");
        } else if (possibleCoordinators.size() > 1) {
            throw new DomainException("Unit.more.than.one.person.entitled.to.be.unit.coordinator");
        }

        return possibleCoordinators.iterator().next();
    }

    public List<Unit> getInactiveSubUnits(YearMonthDay currentDate) {
        return getSubUnitsByState(currentDate, false);
    }

    public List<Unit> getActiveSubUnits(YearMonthDay currentDate) {
        return getSubUnitsByState(currentDate, true);
    }

    private List<Unit> getSubUnitsByState(YearMonthDay currentDate, boolean state) {
        List<Unit> allSubUnits = new ArrayList<Unit>();
        for (Unit subUnit : this.getSubUnits()) {
            if (subUnit.isActive(currentDate) == state) {
                allSubUnits.add(subUnit);
            }
        }
        return allSubUnits;
    }

    public List<Unit> getInactiveParentUnits(YearMonthDay currentDate) {
        return getParentUnitsByState(currentDate, false);
    }

    public List<Unit> getActiveParentUnits(YearMonthDay currentDate) {
        return getParentUnitsByState(currentDate, true);
    }

    private List<Unit> getParentUnitsByState(YearMonthDay currentDate, boolean state) {
        List<Unit> allParentUnits = new ArrayList<Unit>();
        for (Unit subUnit : this.getParentUnits()) {
            if (subUnit.isActive(currentDate) == state) {
                allParentUnits.add(subUnit);
            }
        }
        return allParentUnits;
    }

    public List<Unit> getInactiveSubUnits(YearMonthDay currentDate, AccountabilityTypeEnum accountabilityTypeEnum) {
        return getSubUnitsByState(currentDate, accountabilityTypeEnum, false);
    }

    public List<Unit> getActiveSubUnits(YearMonthDay currentDate, AccountabilityTypeEnum accountabilityTypeEnum) {
        return getSubUnitsByState(currentDate, accountabilityTypeEnum, true);
    }

    private List<Unit> getSubUnitsByState(YearMonthDay currentDate, AccountabilityTypeEnum accountabilityTypeEnum, boolean state) {
        List<Unit> allSubUnits = new ArrayList<Unit>();
        for (Unit subUnit : getSubUnits(accountabilityTypeEnum)) {
            if (subUnit.isActive(currentDate) == state) {
                allSubUnits.add(subUnit);
            }
        }
        return allSubUnits;
    }

    public List<Unit> getActiveSubUnits(YearMonthDay currentDate, List<AccountabilityTypeEnum> accountabilityTypeEnums) {
        return getSubUnitsByState(currentDate, accountabilityTypeEnums, true);
    }

    public List<Unit> getInactiveSubUnits(YearMonthDay currentDate, List<AccountabilityTypeEnum> accountabilityTypeEnums) {
        return getSubUnitsByState(currentDate, accountabilityTypeEnums, false);
    }

    private List<Unit> getSubUnitsByState(YearMonthDay currentDate, List<AccountabilityTypeEnum> accountabilityTypeEnums,
            boolean state) {
        List<Unit> allSubUnits = new ArrayList<Unit>();
        for (Unit subUnit : this.getSubUnits(accountabilityTypeEnums)) {
            if (subUnit.isActive(currentDate) == state) {
                allSubUnits.add(subUnit);
            }
        }
        return allSubUnits;
    }

    public List<Unit> getAllInactiveParentUnits(YearMonthDay currentDate) {
        Set<Unit> allInactiveParentUnits = new HashSet<Unit>();
        allInactiveParentUnits.addAll(getInactiveParentUnits(currentDate));
        for (Unit subUnit : getParentUnits()) {
            allInactiveParentUnits.addAll(subUnit.getAllInactiveParentUnits(currentDate));
        }
        return new ArrayList<Unit>(allInactiveParentUnits);
    }

    public List<Unit> getAllActiveParentUnits(YearMonthDay currentDate) {
        Set<Unit> allActiveParentUnits = new HashSet<Unit>();
        allActiveParentUnits.addAll(getActiveParentUnits(currentDate));
        for (Unit subUnit : getParentUnits()) {
            allActiveParentUnits.addAll(subUnit.getAllActiveParentUnits(currentDate));
        }
        return new ArrayList<Unit>(allActiveParentUnits);
    }

    public List<Unit> getAllInactiveSubUnits(YearMonthDay currentDate) {
        Set<Unit> allInactiveSubUnits = new HashSet<Unit>();
        allInactiveSubUnits.addAll(getInactiveSubUnits(currentDate));
        for (Unit subUnit : getSubUnits()) {
            allInactiveSubUnits.addAll(subUnit.getAllInactiveSubUnits(currentDate));
        }
        return new ArrayList<Unit>(allInactiveSubUnits);
    }

    public List<Unit> getAllActiveSubUnits(YearMonthDay currentDate) {
        Set<Unit> allActiveSubUnits = new HashSet<Unit>();
        allActiveSubUnits.addAll(getActiveSubUnits(currentDate));
        for (Unit subUnit : getSubUnits()) {
            allActiveSubUnits.addAll(subUnit.getAllActiveSubUnits(currentDate));
        }
        return new ArrayList<Unit>(allActiveSubUnits);
    }

    public List<Unit> getAllActiveSubUnits(YearMonthDay currentDate, AccountabilityTypeEnum accountabilityTypeEnum) {
        Set<Unit> allActiveSubUnits = new HashSet<Unit>();
        allActiveSubUnits.addAll(getActiveSubUnits(currentDate, accountabilityTypeEnum));
        for (Unit subUnit : getSubUnits(accountabilityTypeEnum)) {
            allActiveSubUnits.addAll(subUnit.getAllActiveSubUnits(currentDate));
        }
        return new ArrayList<Unit>(allActiveSubUnits);
    }

    public List<Unit> getAllInactiveSubUnits(YearMonthDay currentDate, AccountabilityTypeEnum accountabilityTypeEnum) {
        Set<Unit> allInactiveSubUnits = new HashSet<Unit>();
        allInactiveSubUnits.addAll(getInactiveSubUnits(currentDate, accountabilityTypeEnum));
        for (Unit subUnit : getSubUnits(accountabilityTypeEnum)) {
            allInactiveSubUnits.addAll(subUnit.getAllInactiveSubUnits(currentDate));
        }
        return new ArrayList<Unit>(allInactiveSubUnits);
    }

    public Collection<Unit> getAllSubUnits() {
        Set<Unit> allSubUnits = new HashSet<Unit>();
        Collection<Unit> subUnits = getSubUnits();
        allSubUnits.addAll(subUnits);
        for (Unit subUnit : subUnits) {
            allSubUnits.addAll(subUnit.getAllSubUnits());
        }
        return allSubUnits;
    }

    public Collection<Unit> getAllParentUnits() {
        Set<Unit> allParentUnits = new HashSet<Unit>();
        Collection<Unit> parentUnits = getParentUnits();
        allParentUnits.addAll(parentUnits);
        for (Unit subUnit : parentUnits) {
            allParentUnits.addAll(subUnit.getAllParentUnits());
        }
        return allParentUnits;
    }

    @Override
    public Collection<Unit> getParentUnits() {
        return (Collection<Unit>) getParentParties(Unit.class);
    }

    @Override
    public Collection<Unit> getParentUnits(String accountabilityTypeEnum) {
        return (Collection<Unit>) getParentParties(AccountabilityTypeEnum.valueOf(accountabilityTypeEnum), Unit.class);
    }

    @Override
    public Collection<Unit> getParentUnits(AccountabilityTypeEnum accountabilityTypeEnum) {
        return (Collection<Unit>) getParentParties(accountabilityTypeEnum, Unit.class);
    }

    @Override
    public Collection<Unit> getParentUnits(List<AccountabilityTypeEnum> accountabilityTypeEnums) {
        return (Collection<Unit>) getParentParties(accountabilityTypeEnums, Unit.class);
    }

    @Override
    public Collection<Unit> getSubUnits() {
        return (Collection<Unit>) getChildParties(Unit.class);
    }

    public boolean hasSubUnit(final Unit unit) {
        if (unit != null) {
            for (final Unit child : getSubUnits()) {
                if (child.equals(unit)) {
                    return true;
                }
            }
        }
        return false;
    }

    public Collection<Unit> getSubUnits(AccountabilityTypeEnum accountabilityTypeEnum) {
        return (Collection<Unit>) getChildParties(accountabilityTypeEnum, Unit.class);
    }

    public Collection<Unit> getSubUnits(List<AccountabilityTypeEnum> accountabilityTypeEnums) {
        return (Collection<Unit>) getChildParties(accountabilityTypeEnums, Unit.class);
    }

    public Collection<Unit> getSubUnits(final PartyTypeEnum type) {
        return (Collection<Unit>) getChildParties(type, Unit.class);
    }

    public boolean hasAnyParentUnits() {
        return !getParentUnits().isEmpty();
    }

    public boolean hasAnySubUnits() {
        return !getSubUnits().isEmpty();
    }

    public Collection<Unit> getCurrentParentByOrganizationalStructureAccountabilityType() {
        return (Collection<Unit>) getCurrentParentParties(AccountabilityTypeEnum.ORGANIZATIONAL_STRUCTURE, Unit.class);
    }

    public Collection<Unit> getParentUnitsByOrganizationalStructureAccountabilityType() {
        return (Collection<Unit>) getParentParties(AccountabilityTypeEnum.ORGANIZATIONAL_STRUCTURE, Unit.class);
    }

    @Atomic
    /*
     * @See UnitMailSenderAction
     */
    public UnitBasedSender getOneUnitBasedSender() {
        if (!getUnitBasedSenderSet().isEmpty()) {
            return getUnitBasedSenderSet().iterator().next();
        } else {
            return UnitBasedSender.newInstance(this);
        }
    }

    public int getUnitDepth() {
        int depth = 0;

        for (Unit unit : getParentUnits()) {
            depth = Math.max(depth, 1 + unit.getUnitDepth());
        }

        return depth;
    }

    public Accountability addParentUnit(Unit parentUnit, AccountabilityType accountabilityType) {
        if (this.equals(parentUnit)) {
            throw new DomainException("error.unit.equals.parentUnit");
        }
        if (getParentUnits(accountabilityType.getType()).contains(parentUnit)) {
            throw new DomainException("error.unit.parentUnit.is.already.parentUnit");
        }

        YearMonthDay currentDate = new YearMonthDay();
        List<Unit> subUnits =
                (parentUnit.isActive(currentDate)) ? getAllActiveSubUnits(currentDate) : getAllInactiveSubUnits(currentDate);
        if (subUnits.contains(parentUnit)) {
            throw new DomainException("error.unit.parentUnit.is.already.subUnit");
        }

        return new Accountability(parentUnit, this, accountabilityType);
    }

    public NonAffiliatedTeacher findNonAffiliatedTeacherByName(final String name) {
        for (final NonAffiliatedTeacher nonAffiliatedTeacher : getAssociatedNonAffiliatedTeachersSet()) {
            if (nonAffiliatedTeacher.getName().equalsIgnoreCase(name)) {
                return nonAffiliatedTeacher;
            }
        }
        return null;
    }

    public Unit getChildUnitByAcronym(String acronym) {
        for (Unit subUnit : getSubUnits()) {
            if ((subUnit.getAcronym() != null) && (subUnit.getAcronym().equals(acronym))) {
                return subUnit;
            }
        }
        return null;
    }

    public static List<Unit> readAllUnits() {
        final List<Unit> allUnits = new ArrayList<Unit>();
        for (final Party party : Bennu.getInstance().getPartysSet()) {
            if (party.isUnit()) {
                allUnits.add((Unit) party);
            }
        }
        return allUnits;
    }

    /**
     * This method should be used only for Unit types where acronyms are unique.
     */
    public static Unit readUnitByAcronymAndType(String acronym, PartyTypeEnum partyTypeEnum) {
        if (acronym != null
                && !acronym.equals("")
                && partyTypeEnum != null
                && (partyTypeEnum.equals(PartyTypeEnum.DEGREE_UNIT) || partyTypeEnum.equals(PartyTypeEnum.DEPARTMENT)
                        || partyTypeEnum.equals(PartyTypeEnum.PLANET) || partyTypeEnum.equals(PartyTypeEnum.COUNTRY)
                        || partyTypeEnum.equals(PartyTypeEnum.DEPARTMENT) || partyTypeEnum.equals(PartyTypeEnum.UNIVERSITY)
                        || partyTypeEnum.equals(PartyTypeEnum.SCHOOL) || partyTypeEnum.equals(PartyTypeEnum.RESEARCH_UNIT))) {

            UnitAcronym unitAcronymByAcronym = UnitAcronym.readUnitAcronymByAcronym(acronym);
            if (unitAcronymByAcronym != null) {
                for (Unit unit : unitAcronymByAcronym.getUnitsSet()) {
                    if (unit.getType() != null && unit.getType().equals(partyTypeEnum)) {
                        return unit;
                    }
                }
            }
        }
        return null;
    }

    public static List<Unit> readUnitsByAcronym(String acronym, boolean shouldNormalize) {
        List<Unit> result = new ArrayList<Unit>();
        if (!StringUtils.isEmpty(acronym.trim())) {
            UnitAcronym unitAcronymByAcronym = UnitAcronym.readUnitAcronymByAcronym(acronym, shouldNormalize);
            if (unitAcronymByAcronym != null) {
                result.addAll(unitAcronymByAcronym.getUnitsSet());
            }
        }
        return result;
    }

    public static List<Unit> readUnitsByAcronym(String acronym) {
        return readUnitsByAcronym(acronym, false);
    }

    public static Unit readByCostCenterCode(Integer costCenterCode) {
        final UnitCostCenterCode unitCostCenterCode = UnitCostCenterCode.find(costCenterCode);
        return unitCostCenterCode == null ? null : unitCostCenterCode.getUnit();
    }

    public static Unit createNewUnit(MultiLanguageString unitName, String unitNameCard, Integer costCenterCode, String acronym,
            YearMonthDay beginDate, YearMonthDay endDate, Unit parentUnit, AccountabilityType accountabilityType,
            String webAddress, UnitClassification classification, AdministrativeOffice administrativeOffice,
            Boolean canBeResponsibleOfSpaces, Space campus) {

        Unit unit = new Unit();
        unit.init(unitName, unitNameCard, costCenterCode, acronym, beginDate, endDate, webAddress, classification,
                administrativeOffice, canBeResponsibleOfSpaces, campus);
        if (parentUnit != null && accountabilityType != null) {
            unit.addParentUnit(parentUnit, accountabilityType);
        }
        return unit;
    }

    public static Unit createNewNoOfficialExternalInstitution(String unitName) {
        return createNewNoOfficialExternalInstitution(unitName, null);
    }

    public static Unit createNewNoOfficialExternalInstitution(String unitName, Country country) {
        Unit externalInstitutionUnit = UnitUtils.readExternalInstitutionUnit();
        Unit noOfficialExternalInstitutionUnit = new Unit();
        noOfficialExternalInstitutionUnit.init(new MultiLanguageString(Locale.getDefault(), unitName), null, null, null,
                new YearMonthDay(), null, null, null, null, null, null);
        noOfficialExternalInstitutionUnit.addParentUnit(externalInstitutionUnit,
                AccountabilityType.readByType(AccountabilityTypeEnum.ORGANIZATIONAL_STRUCTURE));
        noOfficialExternalInstitutionUnit.setCountry(country);
        return noOfficialExternalInstitutionUnit;
    }

    public static Unit findFirstExternalUnitByName(final String unitName) {
        if (unitName == null || unitName.length() == 0) {
            return null;
        }
        for (final Party party : Bennu.getInstance().getExternalInstitutionUnit().getSubUnits()) {
            if (!party.isPerson() && unitName.equalsIgnoreCase(party.getName())) {
                final Unit unit = (Unit) party;
                return unit;
            }
        }
        return null;
    }

    public static Unit findFirstUnitByName(final String unitNameString) {
        if (StringUtils.isEmpty(unitNameString)) {
            return null;
        }
        final Collection<UnitName> unitNames = UnitName.find(unitNameString, Integer.MAX_VALUE);
        for (final UnitName unitName : unitNames) {
            final Unit unit = unitName.getUnit();
            if (StringNormalizer.normalize(unitNameString).equalsIgnoreCase(StringNormalizer.normalize(unit.getName()))) {
                return unit;
            }
        }
        return null;
    }

    public String getNameWithAcronym() {
        String name = getName().trim();
        return (getAcronym() == null || StringUtils.isEmpty(getAcronym().trim())) ? name : name + " (" + getAcronym().trim()
                + ")";
    }

    public String getPresentationName() {
        StringBuilder builder = new StringBuilder();
        builder.append(getNameWithAcronym());
        if (getCostCenterCode() != null) {
            builder.append(" [c.c. ").append(getCostCenterCode()).append("]");
        }
        return builder.toString();
    }

    public String getPresentationNameWithParents() {
        String parentUnits = getParentUnitsPresentationName();
        return (!StringUtils.isEmpty(parentUnits.trim())) ? parentUnits + " - " + getPresentationName() : getPresentationName();
    }

    public String getPresentationNameWithParentsAndBreakLine() {
        String parentUnits = getParentUnitsPresentationNameWithBreakLine();
        return (!StringUtils.isEmpty(parentUnits.trim())) ? parentUnits
                + BundleUtil.getString(Bundle.APPLICATION, "label.html.breakLine") + getPresentationName() : getPresentationName();
    }

    public String getParentUnitsPresentationNameWithBreakLine() {
        return getParentUnitsPresentationName(BundleUtil.getString(Bundle.APPLICATION, "label.html.breakLine"));
    }

    public String getParentUnitsPresentationName() {
        return getParentUnitsPresentationName(" - ");
    }

    private String getParentUnitsPresentationName(String separator) {
        StringBuilder builder = new StringBuilder();
        List<Unit> parentUnits = getParentUnitsPath();
        int index = 1;

        for (Unit unit : parentUnits) {
            if (!unit.isAggregateUnit()) {
                if (index == 1) {
                    builder.append(unit.getNameWithAcronym());
                } else {
                    builder.append(separator + unit.getNameWithAcronym());
                }
            }
            index++;
        }

        return builder.toString();
    }

    public String getUnitPath(String separator) {
        return getUnitPath(separator, true);
    }

    public String getUnitPath(String separator, boolean addInstitutionalUnit) {
        StringBuilder builder = new StringBuilder();
        List<Unit> parentUnits = getParentUnitsPath(addInstitutionalUnit);
        int index = 1;

        for (Unit unit : parentUnits) {
            if (!unit.isAggregateUnit()) {
                if (index == 1) {
                    builder.append(unit.getAcronym());
                } else {
                    builder.append(separator + unit.getAcronym());
                }
            }
            index++;
        }

        builder.append("/");
        builder.append(this.getAcronym());
        return builder.toString();
    }

    public List<Unit> getParentUnitsPath() {
        return getParentUnitsPath(true);
    }

    public List<Unit> getParentUnitsPath(boolean addInstitutionalUnit) {

        List<Unit> parentUnits = new ArrayList<Unit>();
        Unit searchedUnit = this;
        Unit externalInstitutionUnit = UnitUtils.readExternalInstitutionUnit();
        Unit institutionUnit = UnitUtils.readInstitutionUnit();
        Unit earthUnit = UnitUtils.readEarthUnit();

        while (searchedUnit.getParentUnits().size() == 1) {
            Unit parentUnit = searchedUnit.getParentUnits().iterator().next();
            if (addInstitutionalUnit || parentUnit != institutionUnit) {
                parentUnits.add(0, parentUnit);
            }
            if (parentUnit != institutionUnit && parentUnit != externalInstitutionUnit && parentUnit != earthUnit) {
                searchedUnit = parentUnit;
                continue;
            }
            break;
        }

        if (searchedUnit.getParentUnits().size() > 1) {
            if (searchedUnit.isInternal() && addInstitutionalUnit) {
                parentUnits.add(0, institutionUnit);
            } else if (searchedUnit.isNoOfficialExternal()) {
                parentUnits.add(0, externalInstitutionUnit);
            } else {
                parentUnits.add(0, earthUnit);
            }
        }

        return parentUnits;
    }

    public String getDirectParentUnitsPresentationName() {
        StringBuilder builder = new StringBuilder();
        for (Unit unit : getParentUnits()) {
            if (!unit.isAggregateUnit()) {
                builder.append(unit.getNameWithAcronym());
            }
        }
        return builder.toString();
    }

    public String getShortPresentationName() {
        final StringBuilder stringBuilder = new StringBuilder();
        for (final Unit unit : getParentUnits()) {
            if (!unit.isAggregateUnit() && unit != Bennu.getInstance().getInstitutionUnit()) {
                stringBuilder.append(unit.getName());
                stringBuilder.append(" - ");
            }
        }
        stringBuilder.append(getName());
        return stringBuilder.toString();
    }

    public SortedSet<Unit> getSortedExternalChilds() {
        final SortedSet<Unit> result = new TreeSet<Unit>(Unit.COMPARATOR_BY_NAME_AND_ID);
        for (final Unit unit : getSubUnits()) {
            if (!unit.isInternal()) {
                result.add(unit);
            }
        }
        return result;
    }

    public List<ExternalCurricularCourse> getAllExternalCurricularCourses() {
        return new ArrayList<ExternalCurricularCourse>(getExternalCurricularCoursesSet());
    }

    public List<UnitFile> getAccessibileFiles(Person person) {
        List<UnitFile> files = new ArrayList<UnitFile>();
        for (UnitFile file : getFilesSet()) {
            if (file.isPersonAllowedToAccess(person)) {
                files.add(file);
            }
        }
        return files;
    }

    public List<UnitFile> getAccessibileFiles(Person person, Collection<UnitFileTag> tag) {
        List<UnitFile> files = new ArrayList<UnitFile>();
        for (UnitFile file : getAccessibileFiles(person)) {
            if (file.hasUnitFileTags(tag)) {
                files.add(file);
            }
        }
        return files;
    }

    public List<UnitFile> getAccessibileFiles(Person person, UnitFileTag tag) {
        List<UnitFile> files = new ArrayList<UnitFile>();
        if (tag != null) {
            for (UnitFile file : tag.getTaggedFilesSet()) {
                if (file.isPersonAllowedToAccess(person)) {
                    files.add(file);
                }
            }
        }
        return files;

    }

    public List<UnitFile> getAccessibileFiles(Person person, String tagName) {
        return getAccessibileFiles(person, getUnitFileTag(tagName));
    }

    public UnitFileTag getUnitFileTag(String name) {
        for (UnitFileTag tag : getUnitFileTagsSet()) {
            if (tag.getName().equalsIgnoreCase(name)) {
                return tag;
            }
        }
        return null;
    }

    public void removeGroupFromUnitFiles(PersistentGroupMembers members) {
        MembersLinkGroup group = MembersLinkGroup.get(members);
        for (UnitFile file : getFilesSet()) {
            file.updatePermissions(group);
        }
    }

    public boolean isUserAllowedToUploadFiles(Person person) {
        return getAllowedPeopleToUploadFilesSet().contains(person);
    }

    public boolean isCurrentUserAllowedToUploadFiles() {
        return isUserAllowedToUploadFiles(AccessControl.getPerson());
    }

    public void setAllowedPeopleToUploadFiles(List<Person> allowedPeople) {
        getAllowedPeopleToUploadFilesSet().clear();
        getAllowedPeopleToUploadFilesSet().addAll(allowedPeople);
    }

    public MultiLanguageString getNameI18n() {
        return getPartyName();
    }

    public List<Group> getUserDefinedGroups() {
        final List<Group> groups = new ArrayList<Group>();
        for (final PersistentGroupMembers persistentMembers : this.getPersistentGroupsSet()) {
            groups.add(MembersLinkGroup.get(persistentMembers));
        }
        return groups;
    }

    public boolean isEarth() {
        return this.equals(Bennu.getInstance().getEarthUnit());
    }

    @Override
    public String getPartyPresentationName() {
        return getPresentationNameWithParents();
    }

    /**
     * Used by messaging system
     *
     * @return Groups to used as recipients
     */
    public List<Group> getGroups() {
        List<Group> groups = new ArrayList<Group>();
        groups.addAll(getDefaultGroups());
        groups.addAll(getUserDefinedGroups());
        return groups;
    }

    protected List<Group> getDefaultGroups() {
        return new ArrayList<Group>();
    }

    public Collection<Function> getVirtualFunctions() {
        return getFunctions(FunctionType.VIRTUAL);
    }

    public void setFunctionsOrder(Collection<Function> functions) {
        Unit.FUNCTION_ORDERED_ADAPTER.updateOrder(this, functions);
    }

    public Collection<Function> getFunctions(boolean active) {
        List<Function> result = new ArrayList<Function>();
        YearMonthDay today = new YearMonthDay();
        for (Function function : getFunctionsSet()) {
            if (function.isActive(today) != active) {
                continue;
            }
            result.add(function);
        }
        return result;
    }

    public Collection<Function> getActiveFunctions() {
        return getFunctions(true);
    }

    public Collection<Function> getInactiveFunctions() {
        return getFunctions(false);
    }

    public SortedSet<Function> getOrderedFunctions() {
        SortedSet<Function> functions = new TreeSet<Function>(Function.COMPARATOR_BY_ORDER);
        functions.addAll(getFunctionsSet());

        return functions;
    }

    public SortedSet<Function> getOrderedActiveFunctions() {
        SortedSet<Function> functions = new TreeSet<Function>(Function.COMPARATOR_BY_ORDER);
        functions.addAll(getActiveFunctions());

        return functions;
    }

    static public MultiLanguageString getInstitutionName() {
        final Bennu root = Bennu.getInstance();
        MultiLanguageString result = new MultiLanguageString();
        if (root != null) {
            final Unit institutionUnit = root.getInstitutionUnit();
            if (root != null) {
                result = institutionUnit.getNameI18n();
            }
        }
        if (result.isEmpty()) {
            result = result.with(Locale.getDefault(), BundleUtil.getString(Bundle.GLOBAL, "institution.name"));
        }

        return result;
    }

    static public String getInstitutionAcronym() {
        final Bennu root = Bennu.getInstance();
        String result = StringUtils.EMPTY;
        if (root != null) {
            final Unit institutionUnit = root.getInstitutionUnit();
            if (root != null) {
                result = institutionUnit.getAcronym();
            }
        }
        if (result.isEmpty()) {
            result = BundleUtil.getString(Bundle.GLOBAL, "institution.name.abbreviation");
        }

        return result;
    }

    @Override
    public Set<Function> getFunctionsSet() {
        Set<Function> result = new HashSet<Function>();
        for (Function function : super.getFunctionsSet()) {
            if (function.getType().equals(AccountabilityTypeEnum.MANAGEMENT_FUNCTION)) {
                result.add(function);
            }
        }
        return result;
    }

    /*
     * ResearchResultPublication getters
     */

    @Override
    public Country getCountry() {
        if (super.getCountry() != null) {
            return super.getCountry();
        }
        for (final Unit unit : getParentUnits()) {
            final Country country = unit.getCountry();
            if (country != null) {
                return country;
            }
        }
        return null;
    }

    @Override
    public void setAcronym(String acronym) {
        super.setAcronym(acronym);
        UnitAcronym unitAcronym = UnitAcronym.readUnitAcronymByAcronym(acronym);
        if (unitAcronym == null) {
            unitAcronym = new UnitAcronym(acronym);
        }
        setUnitAcronym(unitAcronym);
    }

    public Boolean hasParentUnit(Unit parentUnit) {
        for (Unit parent : getParentUnits()) {
            if (parent.equals(parentUnit)) {
                return Boolean.TRUE;
            }
        }
        return Boolean.FALSE;
    }

    public static Unit getParentUnit(String unitNormalizedName, Class<? extends Unit> clazz) {
        if (StringUtils.isEmpty(unitNormalizedName)) {
            return null;
        }

        for (final UnitName unitName : UnitName.find(unitNormalizedName, Integer.MAX_VALUE)) {
            final Unit unit = unitName.getUnit();
            if (unit.getClass().equals(clazz)) {
                return unit;
            }
        }
        return null;
    }

    public static Unit getParentUnitByNormalizedName(Unit childUnit, String parentNormalizedName) {
        for (Unit possibleParent : childUnit.getParentUnits()) {
            if (parentNormalizedName.equalsIgnoreCase(StringNormalizer.normalize(possibleParent.getName()))) {
                return possibleParent;
            }
        }
        return null;
    }

    public void deleteParentUnitRelation(Unit parentUnit) {
        for (Accountability relation : this.getParentsSet()) {
            if (relation.getParentParty().equals(parentUnit)) {
                relation.delete();
                return;
            }
        }
    }

    public Boolean isOfficial() {
        return Boolean.FALSE;
    }

    @Deprecated
    public java.util.Date getBeginDate() {
        org.joda.time.YearMonthDay ymd = getBeginDateYearMonthDay();
        return (ymd == null) ? null : new java.util.Date(ymd.getYear() - 1900, ymd.getMonthOfYear() - 1, ymd.getDayOfMonth());
    }

    @Deprecated
    public void setBeginDate(java.util.Date date) {
        if (date == null) {
            setBeginDateYearMonthDay(null);
        } else {
            setBeginDateYearMonthDay(org.joda.time.YearMonthDay.fromDateFields(date));
        }
    }

    @Deprecated
    public java.util.Date getEndDate() {
        org.joda.time.YearMonthDay ymd = getEndDateYearMonthDay();
        return (ymd == null) ? null : new java.util.Date(ymd.getYear() - 1900, ymd.getMonthOfYear() - 1, ymd.getDayOfMonth());
    }

    @Deprecated
    public void setEndDate(java.util.Date date) {
        if (date == null) {
            setEndDateYearMonthDay(null);
        } else {
            setEndDateYearMonthDay(org.joda.time.YearMonthDay.fromDateFields(date));
        }
    }

    @Override
    public boolean isAdministrativeOfficeUnit() {
        return getAdministrativeOffice() != null;
    }

}
TOP

Related Classes of org.fenixedu.academic.domain.organizationalStructure.Unit

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.