/* * @(#)SearchMissions.java * * Copyright 2011 Instituto Superior Tecnico * Founding Authors: Luis Cruz, Nuno Ochoa, Paulo Abrantes * * https://fenix-ashes.ist.utl.pt/ * * This file is part of the Expenditure Tracking Module. * * The Expenditure Tracking 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 Expenditure Tracking 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 Expenditure Tracking Module. If not, see <http://www.gnu.org/licenses/>. * */ package module.mission.domain.util; import java.util.Calendar; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import module.mission.domain.ForeignMission; import module.mission.domain.Mission; import module.mission.domain.MissionFinancer; import module.mission.domain.MissionProcess; import module.mission.domain.MissionSystem; import module.mission.domain.MissionYear; import module.mission.domain.NationalMission; import module.mission.domain.PersonMissionAuthorization; import module.organization.domain.Party; import module.organization.domain.Person; import org.joda.time.Interval; import org.joda.time.LocalDate; import pt.ist.expenditureTrackingSystem.domain.Search; import pt.ist.expenditureTrackingSystem.domain.organization.AccountingUnit; import pt.ist.expenditureTrackingSystem.domain.organization.SubProject; import pt.ist.expenditureTrackingSystem.domain.organization.Unit; /** * * @author João Neves * @author Luis Cruz * */ public class SearchMissions extends Search<Mission> { private static class MissionProcessMissionSet implements Set<Mission> { private final Set<MissionProcess> missionProcesses; private MissionProcessMissionSet(final Set<MissionProcess> missionProcesses) { this.missionProcesses = missionProcesses; } @Override public Iterator<Mission> iterator() { return new Iterator<Mission>() { private final Iterator<MissionProcess> iterator = missionProcesses.iterator(); @Override public boolean hasNext() { return iterator.hasNext(); } @Override public Mission next() { return iterator.next().getMission(); } @Override public void remove() { throw new IllegalAccessError(); } }; } @Override public boolean add(final Mission e) { throw new IllegalAccessError(); } @Override public boolean addAll(Collection<? extends Mission> c) { throw new IllegalAccessError(); } @Override public void clear() { throw new IllegalAccessError(); } @Override public boolean contains(Object o) { throw new Error("not.implemented"); } @Override public boolean containsAll(Collection<?> c) { throw new Error("not.implemented"); } @Override public boolean isEmpty() { return missionProcesses.isEmpty(); } @Override public boolean remove(Object o) { throw new IllegalAccessError(); } @Override public boolean removeAll(Collection<?> c) { throw new IllegalAccessError(); } @Override public boolean retainAll(Collection<?> c) { throw new IllegalAccessError(); } @Override public int size() { return missionProcesses.size(); } @Override public Object[] toArray() { throw new Error("not.implemented"); } @Override public <T> T[] toArray(T[] a) { throw new Error("not.implemented"); } } private String processNumber = Integer.toString(Calendar.getInstance().get(Calendar.YEAR)) + "/M"; private Party missionResponsible; private Unit payingUnit; private AccountingUnit accountingUnit; private Boolean national = Boolean.TRUE; private Boolean foreign = Boolean.TRUE; private LocalDate date; private Interval interval; private Person requestingPerson; private Person participant; private Person accountManager; private Boolean filterCanceledProcesses = Boolean.FALSE; private boolean filterTakenProcesses = false; private MissionState pendingState; private Person participantAuthorizationAuthority; @Override public Set<Mission> search() { final Set<Mission> missions = limitSearchSet(); return new SearchResult(missions); } private Set<Mission> limitSearchSet() { if (missionResponsible != null) { missionResponsible.getMissionsFromResponsibleSet(); } if (requestingPerson != null) { return requestingPerson.getRequestedMissionsSet(); } if (participant != null) { return participant.getMissionsSet(); } if (participantAuthorizationAuthority != null) { return getMissionsFromParticipantAuthorizationAuthority(participantAuthorizationAuthority); } if (processNumber != null && !processNumber.isEmpty()) { String[] processIdParts = processNumber.split("/"); if (processIdParts.length >= 2) { String year = processIdParts[processIdParts.length - 2]; final MissionYear missionYear = MissionYear.findMissionYear(Integer.parseInt(year)); if (missionYear != null) { return new MissionProcessMissionSet(missionYear.getMissionProcessSet()); } } } return MissionSystem.getInstance().getMissionsSet(); } private Set<Mission> getMissionsFromParticipantAuthorizationAuthority(final Person person) { final Set<Mission> result = new HashSet<Mission>(); for (final PersonMissionAuthorization authorization : person.getPersonMissionAuthorizationFromAuthoritySet()) { final Mission mission = authorization.getAssociatedMission(); result.add(mission); } return result; } protected class SearchResult extends SearchResultSet<Mission> { public SearchResult(Collection<? extends Mission> c) { super(c); } @Override protected boolean matchesSearchCriteria(Mission mission) { return matchProcessNumberCriteria(mission) && matchRequestingUnitCriteria(mission.getMissionResponsible()) && matchPayingUnitCriteria(mission.getMissionVersion().getFinancer()) && matchAccountingUnitCriteria(mission.getMissionVersion().getFinancer()) && matchMissionTypeCriteria(mission) && matchDateCriteria(mission) && matchIntervalCriteria(mission) && matchRequestingPersonCriteria(mission.getRequestingPerson()) && matchParticipantCriteria(mission) && matchParticipantAuthorizationAuthorityCriteria(mission) && matchAccountManagerCriteria(mission) && matchCanceledCriteria(mission) && matchTakenCriteria(mission) && mission.getMissionProcess().isAccessibleToCurrentUser() && matchState(mission); } private boolean matchCanceledCriteria(final Mission mission) { return filterCanceledProcesses == null || !filterCanceledProcesses.booleanValue() || !mission.getMissionProcess().isProcessCanceled(); } private boolean matchTakenCriteria(final Mission mission) { return !filterTakenProcesses || mission.getMissionProcess().getCurrentOwner() == null; } private boolean matchProcessNumberCriteria(final Mission mission) { return processNumber == null || processNumber.isEmpty() || mission.getMissionProcess().getProcessIdentification().indexOf(processNumber) >= 0; } private boolean matchParticipantCriteria(final Mission mission) { return participant == null || mission.getParticipantesSet().contains(participant); } private boolean matchParticipantAuthorizationAuthorityCriteria(final Mission mission) { if (participantAuthorizationAuthority == null) { return true; } for (final PersonMissionAuthorization authorization : participantAuthorizationAuthority .getPersonMissionAuthorizationFromAuthoritySet()) { if (mission == authorization.getAssociatedMission()) { return true; } } return false; } private boolean matchRequestingPersonCriteria(Person rp) { return requestingPerson == null || requestingPerson == rp; } private boolean matchAccountManagerCriteria(final Mission mission) { return accountManager == null || mission.containsAccountManager(accountManager); } private boolean matchDateCriteria(final Mission mission) { return date == null || (mission.getDaparture().isBefore(date.plusDays(1).toDateTimeAtStartOfDay()) && mission.getArrival() .isAfter(date.toDateTimeAtStartOfDay())); } private boolean matchIntervalCriteria(final Mission mission) { return interval == null || interval.contains(mission.getDaparture()) || interval.contains(mission.getArrival()); } private boolean matchState(final Mission mission) { if (pendingState == null) { return true; } return pendingState.getStateProgress(mission.getMissionProcess()) == MissionStateProgress.PENDING; } private boolean matchMissionTypeCriteria(Mission mission) { return (national != null && national.booleanValue() && mission instanceof NationalMission) || (foreign != null && foreign.booleanValue() && mission instanceof ForeignMission); } private boolean matchPayingUnitCriteria(Collection<MissionFinancer> financers) { if (payingUnit == null) { return true; } for (final MissionFinancer missionFinancer : financers) { final Unit unit = missionFinancer.getUnit(); if (unit == payingUnit || (unit instanceof SubProject && unit.getParentUnit() == payingUnit)) { return true; } } return false; } private boolean matchAccountingUnitCriteria(Collection<MissionFinancer> financers) { if (getAccountingUnit() == null) { return true; } for (final MissionFinancer missionFinancer : financers) { if (missionFinancer.getAccountingUnit() == getAccountingUnit()) { return true; } } return false; } private boolean matchRequestingUnitCriteria(final Party mr) { return missionResponsible == null || missionResponsible == mr; } } public Unit getPayingUnit() { return payingUnit; } public void setPayingUnit(Unit payingUnit) { this.payingUnit = payingUnit; } public Boolean getForeign() { return foreign; } public void setForeign(Boolean foreign) { this.foreign = foreign; } public LocalDate getDate() { return date; } public void setDate(LocalDate date) { this.date = date; } public Person getRequestingPerson() { return requestingPerson; } public void setRequestingPerson(Person requestingPerson) { this.requestingPerson = requestingPerson; } public Person getParticipant() { return participant; } public void setParticipant(Person participant) { this.participant = participant; } public String getProcessNumber() { return processNumber; } public void setProcessNumber(String processNumber) { this.processNumber = processNumber.trim(); } public Boolean getNational() { return national; } public void setNational(Boolean national) { this.national = national; } public Boolean getFilterCanceledProcesses() { return filterCanceledProcesses; } public void setFilterCanceledProcesses(Boolean filterCanceledProcesses) { this.filterCanceledProcesses = filterCanceledProcesses; } public boolean getFilterTakenProcesses() { return filterTakenProcesses; } public void setFilterTakenProcesses(boolean filterTakenProcesses) { this.filterTakenProcesses = filterTakenProcesses; } public Party getMissionResponsible() { return missionResponsible; } public void setMissionResponsible(Party missionResponsible) { this.missionResponsible = missionResponsible; } public Person getAccountManager() { return accountManager; } public void setAccountManager(Person accountManager) { this.accountManager = accountManager; } public void setAccountingUnit(AccountingUnit accountingUnit) { this.accountingUnit = accountingUnit; } public AccountingUnit getAccountingUnit() { return accountingUnit; } public Interval getInterval() { return interval; } public void setInterval(Interval interval) { this.interval = interval; } public MissionState getPendingState() { return pendingState; } public void setPendingState(MissionState pendingState) { this.pendingState = pendingState; } public Person getParticipantAuthorizationAuthority() { return participantAuthorizationAuthority; } public void setParticipantAuthorizationAuthority(Person participantAuthorizationAuthority) { this.participantAuthorizationAuthority = participantAuthorizationAuthority; } }