module.organization.domain.Party.java Source code

Java tutorial

Introduction

Here is the source code for module.organization.domain.Party.java

Source

/*
 * @(#)Party.java
 *
 * Copyright 2009 Instituto Superior Tecnico
 * Founding Authors: Joo Figueiredo, Luis Cruz
 * 
 *      https://fenix-ashes.ist.utl.pt/
 * 
 *   This file is part of the Organization Module.
 *
 *   The Organization Module 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.
 *
 *   The Organization Module 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 the Organization Module. If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package module.organization.domain;

import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import module.organization.domain.predicates.PartyPredicate;
import module.organization.domain.predicates.PartyPredicate.PartyByAccTypeAndDates;
import module.organization.domain.predicates.PartyPredicate.PartyByAccountabilityType;
import module.organization.domain.predicates.PartyPredicate.PartyByClassType;
import module.organization.domain.predicates.PartyPredicate.PartyByPartyType;
import module.organization.domain.predicates.PartyPredicate.TruePartyPredicate;
import module.organization.domain.predicates.PartyResultCollection;

import org.fenixedu.bennu.core.domain.Bennu;
import org.fenixedu.bennu.core.groups.DynamicGroup;
import org.fenixedu.bennu.core.security.Authenticate;
import org.fenixedu.commons.i18n.I18N;
import org.joda.time.LocalDate;

import pt.ist.fenixframework.Atomic;

/**
 * 
 * @author Joo Antunes
 * @author Joo Neves
 * @author Pedro Santos
 * @author Joo Figueiredo
 * @author Srgio Silva
 * @author Paulo Abrantes
 * @author Luis Cruz
 * 
 */
abstract public class Party extends Party_Base {

    static public final Comparator<Party> COMPARATOR_BY_NAME = new Comparator<Party>() {
        @Override
        public int compare(Party o1, Party o2) {
            int res = o1.getPartyName().compareTo(o2.getPartyName());
            return res != 0 ? res : o1.getExternalId().compareTo(o2.getExternalId());
        }
    };

    static public final Comparator<Party> COMPARATOR_BY_TYPE_AND_NAME = new Comparator<Party>() {
        @Override
        public int compare(Party o1, Party o2) {
            int result = o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
            return result == 0 ? COMPARATOR_BY_NAME.compare(o1, o2) : result;
        }
    };

    protected Party() {
        super();
        setMyOrg(Bennu.getInstance());
    }

    /**
     * 
     * @return gets all of immediately above parents
     */
    public Collection<Party> getParents() {
        return getParents(new TruePartyPredicate());
    }

    public Collection<Party> getParents(final AccountabilityType type) {
        return getParents(new PartyByAccountabilityType(type));
    }

    public Collection<Party> getParents(final Collection<AccountabilityType> types) {
        return getParents(new PartyByAccountabilityType(types));
    }

    public Collection<Party> getParents(final PartyType type) {
        return getParents(new PartyByPartyType(type));
    }

    public Collection<Unit> getParentUnits() {
        return getParents(new PartyByClassType(Unit.class));
    }

    public Collection<Unit> getParentUnits(final AccountabilityType type) {
        return getParents(new PartyByAccountabilityType(Unit.class, type));
    }

    public Collection<Unit> getParentUnits(final PartyType type) {
        return getParents(new PartyByPartyType(Unit.class, type));
    }

    public Set<Accountability> getAllParentAccountabilities() {
        return super.getParentAccountabilitiesSet();
    }

    // Overriden methods to hide the erased accs: 
    @Override
    public Set<Accountability> getParentAccountabilitiesSet() {
        Set<Accountability> accsToReturn = new HashSet<Accountability>();
        for (Accountability acc : super.getParentAccountabilitiesSet()) {
            if (!acc.isErased()) {
                accsToReturn.add(acc);
            }
        }
        return accsToReturn;
    }

    public Iterator<Accountability> getParentAccountabilitiesIterator() {
        return super.getParentAccountabilitiesSet().iterator();
    }

    @Override
    public Set<Accountability> getChildAccountabilitiesSet() {
        Set<Accountability> accsToReturn = new HashSet<Accountability>();
        for (Accountability acc : super.getChildAccountabilitiesSet()) {
            if (!acc.isErased()) {
                accsToReturn.add(acc);
            }
        }
        return accsToReturn;
    }

    @Deprecated
    @Override
    public void removeChildAccountabilities(Accountability childAccountabilities) {
        throw new UnsupportedOperationException("dont.use.this.api");
    }

    @Deprecated
    @Override
    public void removeParentAccountabilities(Accountability parentAccountabilities) {
        throw new UnsupportedOperationException("dont.use.this.api");
    }

    @Deprecated
    @Override
    public void addChildAccountabilities(Accountability childAccountabilities) {
        throw new UnsupportedOperationException("dont.use.this.api");
    }

    @Deprecated
    @Override
    public void addParentAccountabilities(Accountability parentAccountabilities) {
        throw new UnsupportedOperationException("dont.use.this.api");
    }

    //end of overriden methods

    @SuppressWarnings("unchecked")
    public <T extends Party> Collection<T> getParents(final PartyPredicate predicate) {
        final Collection<Party> result = new LinkedList<Party>();
        for (final Accountability accountability : getParentAccountabilities()) {
            if (predicate.eval(accountability.getParent(), accountability)) {
                result.add(accountability.getParent());
            }
        }
        return (List<T>) result;
    }

    public Collection<Accountability> getParentAccountabilities(final LocalDate startDate, final LocalDate endDate,
            final AccountabilityType... types) {
        return getParentAccountabilities(new PartyByAccTypeAndDates(startDate, endDate, types));
    }

    public Collection<? extends Accountability> getParentAccountabilities(LocalDate startDate, LocalDate endDate,
            List<AccountabilityType> accTypes) {
        return getParentAccountabilities(new PartyByAccTypeAndDates(startDate, endDate, accTypes));
    }

    public Collection<Accountability> getChildrenAccountabilities(final LocalDate startDate,
            final LocalDate endDate, final AccountabilityType... types) {
        return getChildrenAccountabilities(new PartyByAccTypeAndDates(startDate, endDate, types));
    }

    public Collection<? extends Accountability> getChildrenAccountabilities(LocalDate startDate, LocalDate endDate,
            List<AccountabilityType> accTypes) {
        return getChildrenAccountabilities(new PartyByAccTypeAndDates(startDate, endDate, accTypes));
    }

    public Collection<Accountability> getParentAccountabilities(final Collection<AccountabilityType> types) {
        return getParentAccountabilities(new PartyByAccountabilityType(types));
    }

    public Collection<Accountability> getParentAccountabilities(final AccountabilityType... types) {
        return getParentAccountabilities(new PartyByAccountabilityType(types));
    }

    @SuppressWarnings("unchecked")
    protected <T extends Accountability> Collection<T> getParentAccountabilities(final PartyPredicate predicate) {
        final Collection<Accountability> result = new LinkedList<Accountability>();
        for (final Accountability accountability : getParentAccountabilities()) {
            if (predicate.eval(accountability.getParent(), accountability)) {
                result.add(accountability);
            }
        }
        return (List<T>) result;
    }

    public Collection<Party> getChildren() {
        return getChildren(new TruePartyPredicate());
    }

    public Collection<Party> getChildren(final AccountabilityType type) {
        return getChildren(new PartyByAccountabilityType(type));
    }

    public Collection<Party> getChildren(final Collection<AccountabilityType> types) {
        return getChildren(new PartyByAccountabilityType(types));
    }

    public Collection<Party> getChildren(final PartyType type) {
        return getChildren(new PartyByPartyType(type));
    }

    public Collection<Unit> getChildUnits() {
        return getChildren(new PartyByClassType(Unit.class));
    }

    public Collection<Unit> getChildUnits(final AccountabilityType type) {
        return getChildren(new PartyByAccountabilityType(Unit.class, type));
    }

    public Collection<Unit> getChildUnits(final Collection<AccountabilityType> types) {
        return getChildren(new PartyByAccountabilityType(Unit.class, types));
    }

    public Collection<Unit> getChildUnits(final PartyType type) {
        return getChildren(new PartyByPartyType(Unit.class, type));
    }

    public Collection<Person> getChildPersons() {
        return getChildren(new PartyByClassType(Person.class));
    }

    public Collection<Person> getChildPersons(final AccountabilityType type) {
        return getChildren(new PartyByAccountabilityType(Person.class, type));
    }

    public Collection<Person> getChildPersons(final Collection<AccountabilityType> types) {
        return getChildren(new PartyByAccountabilityType(Person.class, types));
    }

    public Collection<Person> getChildPersons(final PartyType type) {
        return getChildren(new PartyByPartyType(Person.class, type));
    }

    @SuppressWarnings("unchecked")
    public <T extends Party> Collection<T> getChildren(final PartyPredicate predicate) {
        final Collection<Party> result = new LinkedList<Party>();
        for (final Accountability accountability : getChildAccountabilities()) {
            if (predicate.eval(accountability.getChild(), accountability)) {
                result.add(accountability.getChild());
            }
        }
        return (List<T>) result;
    }

    public Collection<Accountability> getChildrenAccountabilities(final Collection<AccountabilityType> types) {
        return getChildrenAccountabilities(new PartyByAccountabilityType(types));
    }

    public Collection<Accountability> getChildrenAccountabilities(final AccountabilityType... types) {
        return getChildrenAccountabilities(new PartyByAccountabilityType(types));
    }

    public Collection<Accountability> getChildrenAccountabilities(final Class<? extends Party> clazz,
            final Collection<AccountabilityType> types) {
        return getChildrenAccountabilities(new PartyByAccountabilityType(clazz, types));
    }

    @SuppressWarnings("unchecked")
    protected <T extends Accountability> Collection<T> getChildrenAccountabilities(final PartyPredicate predicate) {
        final Collection<Accountability> result = new LinkedList<Accountability>();
        for (final Accountability accountability : getChildAccountabilities()) {
            if (predicate.eval(accountability.getChild(), accountability)) {
                result.add(accountability);
            }
        }
        return (List<T>) result;
    }

    public Collection<Party> getAncestors() {
        final PartyResultCollection result = new PartyResultCollection(new TruePartyPredicate());
        getAncestors(result);
        return result.getResult();
    }

    public Collection<Party> getAncestors(final AccountabilityType type) {
        final PartyResultCollection result = new PartyResultCollection(new PartyByAccountabilityType(type));
        getAncestors(result);
        return result.getResult();
    }

    public Collection<Party> getAncestors(final PartyType type) {
        final PartyResultCollection result = new PartyResultCollection(new PartyByPartyType(type));
        getAncestors(result);
        return result.getResult();
    }

    public Collection<Unit> getAncestorUnits() {
        final PartyResultCollection result = new PartyResultCollection(new PartyByClassType(Unit.class));
        getAncestors(result);
        return result.getResult();
    }

    public Collection<Unit> getAncestorUnits(final AccountabilityType type) {
        final PartyResultCollection result = new PartyResultCollection(
                new PartyByAccountabilityType(Unit.class, type));
        getAncestors(result);
        return result.getResult();
    }

    public Collection<Unit> getAncestorUnits(final PartyType type) {
        final PartyResultCollection result = new PartyResultCollection(new PartyByPartyType(Unit.class, type));
        getAncestors(result);
        return result.getResult();
    }

    /**
     * 
     * @param result
     *            all of the ancestors (recursively)
     */
    protected void getAncestors(final PartyResultCollection result) {
        for (final Accountability accountability : getParentAccountabilities()) {
            result.conditionalAddParty(accountability.getParent(), accountability);
            accountability.getParent().getAncestors(result);
        }
    }

    public boolean ancestorsInclude(final Party party, final AccountabilityType type) {
        for (final Accountability accountability : getParentAccountabilities()) {
            if (accountability.hasAccountabilityType(type)) {
                if (accountability.getParent().equals(party)) {
                    return true;
                }
                if (accountability.getParent().ancestorsInclude(party, type)) {
                    return true;
                }
            }
        }

        return false;
    }

    public Collection<Party> getDescendents() {
        final PartyResultCollection result = new PartyResultCollection(new TruePartyPredicate());
        getDescendents(result);
        return result.getResult();
    }

    public Collection<Party> getDescendents(final AccountabilityType type) {
        final PartyResultCollection result = new PartyResultCollection(new PartyByAccountabilityType(type));
        getDescendents(result);
        return result.getResult();
    }

    public Collection<Party> getDescendents(final PartyType type) {
        final PartyResultCollection result = new PartyResultCollection(new PartyByPartyType(type));
        getDescendents(result);
        return result.getResult();
    }

    public Collection<Unit> getDescendentUnits() {
        final PartyResultCollection result = new PartyResultCollection(new PartyByClassType(Unit.class));
        getDescendents(result);
        return result.getResult();
    }

    public Collection<Unit> getDescendentUnits(final AccountabilityType type) {
        final PartyResultCollection result = new PartyResultCollection(
                new PartyByAccountabilityType(Unit.class, type));
        getDescendents(result);
        return result.getResult();
    }

    public Collection<Unit> getDescendentUnits(final PartyType type) {
        final PartyResultCollection result = new PartyResultCollection(new PartyByPartyType(Unit.class, type));
        getDescendents(result);
        return result.getResult();
    }

    public Collection<Person> getDescendentPersons() {
        final PartyResultCollection result = new PartyResultCollection(new PartyByClassType(Person.class));
        getDescendents(result);
        return result.getResult();
    }

    public Collection<Person> getDescendentPersons(final AccountabilityType type) {
        final PartyResultCollection result = new PartyResultCollection(
                new PartyByAccountabilityType(Person.class, type));
        getDescendents(result);
        return result.getResult();
    }

    public Collection<Person> getDescendentPersons(final PartyType type) {
        final PartyResultCollection result = new PartyResultCollection(new PartyByPartyType(Person.class, type));
        getDescendents(result);
        return result.getResult();
    }

    protected void getDescendents(final PartyResultCollection result) {
        for (final Accountability accountability : getChildAccountabilities()) {
            result.conditionalAddParty(accountability.getChild(), accountability);
            accountability.getChild().getDescendents(result);
        }
    }

    public Collection<Party> getSiblings() {
        final Collection<Party> result = new LinkedList<Party>();
        for (final Accountability accountability : getParentAccountabilities()) {
            result.addAll(accountability.getParent().getChildren());
        }
        result.remove(this);
        return result;
    }

    public boolean isUnit() {
        return false;
    }

    public boolean isPerson() {
        return false;
    }

    @Atomic
    public void delete() {
        canDelete();
        disconnect();
        deleteDomainObject();
    }

    protected void canDelete() {
        if (!getChildAccountabilitiesSet().isEmpty()) {
            throw new OrganizationDomainException("error.Party.delete.has.child.accountabilities");
        }
    }

    protected void disconnect() {
        for (Accountability acc : super.getParentAccountabilitiesSet()) {
            acc.delete();
        }
        getPartyTypes().clear();
        setMyOrg(null);
    }

    /**
     * 
     * @param parent parent
     * @param type type
     * @param begin begin
     * @param end end
     * @param justification an information justification/reason for the accountability change, or null if there is none, or none
     *            is provided
     * @return Accountability
     */
    @Atomic
    public Accountability addParent(final Party parent, final AccountabilityType type, final LocalDate begin,
            final LocalDate end, String justification) {
        return Accountability.create(parent, this, type, begin, end, justification);
    }

    /**
     * 
     * @deprecated Use {@link #addParent(Party, AccountabilityType, LocalDate, LocalDate, String)} instead
     * @param parent parent
     * @param type type
     * @param begin begin
     * @param end end
     * @return Accountability
     */
    @Deprecated
    public Accountability addParent(final Party parent, final AccountabilityType type, final LocalDate begin,
            final LocalDate end) {
        return addParent(parent, type, begin, end, null);

    }

    /**
     * 
     * @param child child
     * @param type type
     * @param begin begin
     * @param end end
     * @return Accountability
     * @deprecated Use {@link #addChild(Party, AccountabilityType, LocalDate, LocalDate, String)} instead
     */
    @Deprecated
    public Accountability addChild(final Party child, final AccountabilityType type, final LocalDate begin,
            final LocalDate end) {
        return addChild(child, type, begin, end, null);
    }

    /**
     * 
     * @param child child
     * @param type type
     * @param begin begin
     * @param end end
     * @param justification an information justification/reason for the change of accountability, or null if there is none, or
     *            none is provided
     * @return Accountability
     */
    @Atomic
    public Accountability addChild(final Party child, final AccountabilityType type, final LocalDate begin,
            final LocalDate end, String justification) {
        Accountability intersectingAccountability = getIntersectingChildAccountability(child, type, begin, end);
        if (intersectingAccountability != null) {
            if (begin == null || (begin != null && intersectingAccountability.getBeginDate() != null
                    && begin.isBefore(intersectingAccountability.getBeginDate()))) {
                intersectingAccountability.setBeginDate(begin);
            }
            if (end == null || (end != null && intersectingAccountability.getEndDate() != null
                    && end.isAfter(intersectingAccountability.getEndDate()))) {
                intersectingAccountability.editDates(intersectingAccountability.getBeginDate(), end);
            }
            return intersectingAccountability;
        }

        return Accountability.create(this, child, type, begin, end, justification);
    }

    public boolean hasAnyIntersectingChildAccountability(final Party child, final AccountabilityType type,
            final LocalDate begin, final LocalDate end) {
        for (final Accountability accountability : getChildAccountabilities()) {
            if (accountability.getChild() == child && accountability.getAccountabilityType() == type
                    && accountability.intersects(begin, end)) {
                return true;
            }
        }
        return false;
    }

    boolean hasAnyIntersectingChildAccountability(final Party child, final AccountabilityType type,
            final LocalDate begin, final LocalDate end, final Accountability exluding) {
        for (final Accountability accountability : getChildAccountabilities()) {
            if (exluding != accountability && accountability.getChild() == child
                    && accountability.getAccountabilityType() == type && accountability.intersects(begin, end)) {
                return true;
            }
        }
        return false;
    }

    private Accountability getIntersectingChildAccountability(final Party child, final AccountabilityType type,
            final LocalDate begin, final LocalDate end) {
        Accountability intersectingAccountability = null;
        for (final Accountability accountability : getChildAccountabilities()) {
            if (accountability.getChild() == child && accountability.getAccountabilityType() == type
                    && accountability.intersects(begin, end)) {
                if (intersectingAccountability != null) {
                    throw new OrganizationDomainException("error.Party.multiple.intersecting.accountabilities");
                }
                intersectingAccountability = accountability;
            }
        }
        return intersectingAccountability;
    }

    @Atomic
    public void removeParent(final Accountability accountability) {
        if (getParentAccountabilitiesSet().contains(accountability)) {
            if (isUnit() && getParentAccountabilitiesSet().size() == 1) {
                throw new OrganizationDomainException("error.Party.cannot.remove.parent.accountability");
            }
            accountability.delete();
        }
    }

    @Atomic
    public void editPartyTypes(final List<PartyType> partyTypes) {
        getPartyTypes().retainAll(partyTypes);
        getPartyTypes().addAll(partyTypes);

        if (getPartyTypesSet().isEmpty()) {
            throw new OrganizationDomainException("error.Party.must.have.at.least.one.party.type");
        }
        if (!accountabilitiesStillValid()) {
            throw new OrganizationDomainException(
                    "error.Party.invalid.party.types.accountability.rules.are.not.correct");
        }

    }

    protected boolean accountabilitiesStillValid() {
        for (final Accountability accountability : getParentAccountabilitiesSet()) {
            if (!accountability.isValid()) {
                return false;
            }
        }
        return true;
    }

    public String getPartyNameWithSuffixType() {
        return ResourceBundle.getBundle("resources.OrganizationResources", I18N.getLocale()).getString(
                "label." + getClass().getSimpleName().toLowerCase()) + " - " + getPartyName().getContent();
    }

    public Set<OrganizationalModel> getAllOrganizationModels() {
        final Set<OrganizationalModel> organizationModels = new TreeSet<OrganizationalModel>(
                OrganizationalModel.COMPARATORY_BY_NAME);
        addAllOrganizationModels(organizationModels, new HashSet<Party>());
        return organizationModels;
    }

    public void addAllOrganizationModels(final Set<OrganizationalModel> organizationModels,
            final Set<Party> processed) {
        if (!processed.contains(this)) {
            processed.add(this);
            organizationModels.addAll(getOrganizationalModelsSet());
            for (final Accountability accountability : getParentAccountabilitiesSet()) {
                final Party party = accountability.getParent();
                party.addAllOrganizationModels(organizationModels, processed);
            }
        }
    }

    public void setPartyTypes(final List<PartyType> partyTypes) {
        getPartyTypesSet().clear();
        getPartyTypesSet().addAll(partyTypes);
    }

    public boolean isAuthorizedToManage() {
        return DynamicGroup.get("managers").isMember(Authenticate.getUser());
    }

    public boolean hasChildAccountabilityIncludingAncestry(final Collection<AccountabilityType> accountabilityTypes,
            final Party party) {
        return hasActiveChildAccountabilityIncludingAncestry(new HashSet<Party>(), accountabilityTypes, party);
    }

    private boolean hasActiveChildAccountabilityIncludingAncestry(final Set<Party> processed,
            final Collection<AccountabilityType> accountabilityTypes, final Party party) {
        if (!processed.contains(this)) {
            processed.add(this);
            for (final Accountability accountability : getChildAccountabilitiesSet()) {
                if (accountability.isActiveNow()
                        && accountabilityTypes.contains(accountability.getAccountabilityType())) {
                    final Party child = accountability.getChild();
                    if (child == party) {
                        return true;
                    }
                }
            }
            for (final Accountability accountability : getParentAccountabilitiesSet()) {
                if (accountability.isActiveNow()
                        && accountabilityTypes.contains(accountability.getAccountabilityType())) {
                    final Party parent = accountability.getParent();
                    if (parent.hasActiveChildAccountabilityIncludingAncestry(processed, accountabilityTypes,
                            party)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public static Party findPartyByPartyTypeAndAcronymForAccountabilityTypeLink(final Set<Party> parties,
            final AccountabilityType accountabilityType, final PartyType partyType, final String acronym) {
        for (final Party party : parties) {
            final Party result = party.findPartyByPartyTypeAndAcronymForAccountabilityTypeLink(accountabilityType,
                    partyType, acronym);
            if (result != null) {
                return result;
            }
        }
        return null;
    }

    protected Party findPartyByPartyTypeAndAcronymForAccountabilityTypeLink(
            final AccountabilityType accountabilityType, final PartyType partyType, final String acronym) {
        return null;
    }

    public String getPresentationName() {
        return getPartyName().getContent();
    }

    public boolean isTop() {
        return false;
    }

    public boolean hasActiveAncestry(final AccountabilityType accountabilityType, final LocalDate when) {
        return isTop() || hasParentWithActiveAncestry(accountabilityType, when);
    }

    public boolean hasDirectActiveAncestry(final AccountabilityType accountabilityType, final LocalDate when) {
        return !getParents(new PartyPredicate() {

            @Override
            public boolean eval(Party party, Accountability accountability) {
                return accountability.getAccountabilityType() == accountabilityType
                        && accountability.isActive(when);
            }

        }).isEmpty();
    }

    private boolean hasParentWithActiveAncestry(final AccountabilityType accountabilityType, final LocalDate when) {
        for (final Accountability accountability : getParentAccountabilitiesSet()) {
            if (accountability.getAccountabilityType() == accountabilityType && accountability.isActive(when)) {
                final Party parent = accountability.getParent();
                return parent.hasActiveAncestry(accountabilityType, when);
            }
        }
        return false;
    }

    public boolean hasPartyAsAncestor(final Party party, final Set<AccountabilityType> accountabilityTypes) {
        for (final Accountability accountability : getParentAccountabilitiesSet()) {
            final AccountabilityType accountabilityType = accountability.getAccountabilityType();
            if (accountabilityTypes.contains(accountabilityType) && accountability.isActiveNow()) {
                final Party parent = accountability.getParent();
                if (parent == party || parent.hasPartyAsAncestor(party, accountabilityTypes)) {
                    return true;
                }
            }
        }
        return false;
    }

    public boolean hasPartyAsAncestor(final Party party, final Set<AccountabilityType> accountabilityTypes,
            final LocalDate when) {
        for (final Accountability accountability : getParentAccountabilitiesSet()) {
            final AccountabilityType accountabilityType = accountability.getAccountabilityType();
            if (accountabilityTypes.contains(accountabilityType) && accountability.isActive(when)) {
                final Party parent = accountability.getParent();
                if (parent == party || parent.hasPartyAsAncestor(party, accountabilityTypes)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 
     * @param accTypes
     *            the AccountabilityType types to use on the retrieval or null
     *            to get all
     * @param dateOfStart
     *            the mininum date to retrieve elements for, or null if there is
     *            no minimum
     * @param dateOfEnd
     *            the maximum date to retrieve elements for, or null if there is
     *            no maximum
     * @return a list of historic and actual Accountabilities {@link Accountability}
     */
    public SortedSet<Accountability> getAccountabilitiesAndHistoricItems(List<AccountabilityType> accTypes,
            LocalDate dateOfStart, LocalDate dateOfEnd) {
        TreeSet<Accountability> accountabilities = new TreeSet<Accountability>(
                Accountability.COMPARATOR_BY_CREATION_DATE_FALLBACK_TO_START_DATE);

        accountabilities.addAll(getParentAccountabilities(dateOfStart, dateOfEnd, accTypes));
        accountabilities.addAll(getChildrenAccountabilities(dateOfStart, dateOfEnd, accTypes));

        return accountabilities;

    }

    @Deprecated
    public java.util.Set<module.organization.domain.Accountability> getParentAccountabilities() {
        return getParentAccountabilitiesSet();
    }

    @Deprecated
    public java.util.Set<module.organization.domain.OrganizationalModel> getOrganizationalModels() {
        return getOrganizationalModelsSet();
    }

    @Deprecated
    public java.util.Set<module.organization.domain.Accountability> getChildAccountabilities() {
        return getChildAccountabilitiesSet();
    }

    @Deprecated
    public java.util.Set<module.organization.domain.PartyType> getPartyTypes() {
        return getPartyTypesSet();
    }

}