package net.sourceforge.fenixedu.domain; import java.math.BigDecimal; import java.text.Collator; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import net.sourceforge.fenixedu.applicationTier.strategy.groupEnrolment.strategys.GroupEnrolmentStrategyFactory; import net.sourceforge.fenixedu.applicationTier.strategy.groupEnrolment.strategys.IGroupEnrolmentStrategy; import net.sourceforge.fenixedu.applicationTier.strategy.groupEnrolment.strategys.IGroupEnrolmentStrategyFactory; import net.sourceforge.fenixedu.dataTransferObject.GenericPair; import net.sourceforge.fenixedu.dataTransferObject.teacher.executionCourse.SearchExecutionCourseAttendsBean; import net.sourceforge.fenixedu.domain.accessControl.EveryoneGroup; import net.sourceforge.fenixedu.domain.accessControl.ExecutionCourseTeachersGroup; import net.sourceforge.fenixedu.domain.accessControl.Group; import net.sourceforge.fenixedu.domain.accessControl.GroupUnion; import net.sourceforge.fenixedu.domain.accessControl.PersonGroup; import net.sourceforge.fenixedu.domain.accessControl.RoleTypeGroup; import net.sourceforge.fenixedu.domain.administrativeOffice.AdministrativeOfficeType; import net.sourceforge.fenixedu.domain.contents.Attachment; import net.sourceforge.fenixedu.domain.contents.Container; import net.sourceforge.fenixedu.domain.contents.Content; import net.sourceforge.fenixedu.domain.contents.ExplicitOrderNode; import net.sourceforge.fenixedu.domain.contents.Node; import net.sourceforge.fenixedu.domain.curriculum.CurricularCourseType; import net.sourceforge.fenixedu.domain.curriculum.EnrolmentEvaluationType; import net.sourceforge.fenixedu.domain.degree.DegreeType; import net.sourceforge.fenixedu.domain.degreeStructure.BibliographicReferences; import net.sourceforge.fenixedu.domain.degreeStructure.CompetenceCourseInformation; import net.sourceforge.fenixedu.domain.degreeStructure.BibliographicReferences.BibliographicReferenceType; import net.sourceforge.fenixedu.domain.exceptions.DomainException; import net.sourceforge.fenixedu.domain.executionCourse.SummariesSearchBean; import net.sourceforge.fenixedu.domain.functionalities.GroupAvailability; import net.sourceforge.fenixedu.domain.gesdis.CourseReport; import net.sourceforge.fenixedu.domain.inquiries.InquiriesCourse; import net.sourceforge.fenixedu.domain.inquiries.InquiriesRegistry; import net.sourceforge.fenixedu.domain.inquiries.StudentInquiriesCourseResult; import net.sourceforge.fenixedu.domain.inquiries.teacher.TeachingInquiry; import net.sourceforge.fenixedu.domain.messaging.Announcement; import net.sourceforge.fenixedu.domain.messaging.ConversationThread; import net.sourceforge.fenixedu.domain.messaging.ExecutionCourseAnnouncementBoard; import net.sourceforge.fenixedu.domain.messaging.ExecutionCourseForum; import net.sourceforge.fenixedu.domain.messaging.ForumSubscription; import net.sourceforge.fenixedu.domain.onlineTests.DistributedTest; import net.sourceforge.fenixedu.domain.onlineTests.Metadata; import net.sourceforge.fenixedu.domain.onlineTests.OnlineTest; import net.sourceforge.fenixedu.domain.onlineTests.TestScope; import net.sourceforge.fenixedu.domain.person.RoleType; import net.sourceforge.fenixedu.domain.space.AllocatableSpace; import net.sourceforge.fenixedu.domain.space.Campus; import net.sourceforge.fenixedu.domain.student.Registration; import net.sourceforge.fenixedu.domain.student.Student; import net.sourceforge.fenixedu.domain.student.WeeklyWorkLoad; import net.sourceforge.fenixedu.domain.tests.NewTestGroup; import net.sourceforge.fenixedu.domain.tests.TestGroupStatus; import net.sourceforge.fenixedu.domain.time.calendarStructure.AcademicInterval; import net.sourceforge.fenixedu.domain.util.email.Message; import net.sourceforge.fenixedu.domain.util.email.SystemSender; import net.sourceforge.fenixedu.injectionCode.IGroup; import net.sourceforge.fenixedu.util.EntryPhase; import net.sourceforge.fenixedu.util.ProposalState; import net.sourceforge.fenixedu.util.domain.OrderedRelationAdapter; import org.apache.commons.collections.comparators.ReverseComparator; import org.joda.time.DateTime; import org.joda.time.DateTimeFieldType; import org.joda.time.Interval; import org.joda.time.Period; import org.joda.time.YearMonthDay; import pt.ist.fenixWebFramework.renderers.utils.RenderUtils; import pt.ist.fenixWebFramework.security.accessControl.Checked; import pt.utl.ist.fenix.tools.predicates.Predicate; import pt.utl.ist.fenix.tools.util.CollectionUtils; import pt.utl.ist.fenix.tools.util.DateFormatUtil; import pt.utl.ist.fenix.tools.util.StringAppender; import pt.utl.ist.fenix.tools.util.StringNormalizer; import pt.utl.ist.fenix.tools.util.i18n.Language; import pt.utl.ist.fenix.tools.util.i18n.MultiLanguageString; import com.linkare.commons.metainfo.Linkare; public class ExecutionCourse extends ExecutionCourse_Base { public static final Comparator EXECUTION_COURSE_EXECUTION_PERIOD_COMPARATOR = new Comparator() { @Override public int compare(ExecutionCourse o1, ExecutionCourse o2) { return o1.getExecutionPeriod().compareTo(o2.getExecutionPeriod()); } }; public static final Comparator EXECUTION_COURSE_NAME_COMPARATOR = new Comparator() { @Override public int compare(ExecutionCourse o1, ExecutionCourse o2) { final int c = Collator.getInstance().compare(o1.getNome(), o2.getNome()); return c == 0 ? DomainObject.COMPARATOR_BY_ID.compare(o1, o2) : c; } }; public static final Comparator EXECUTION_COURSE_COMPARATOR_BY_EXECUTION_PERIOD_AND_NAME = new Comparator() { @Override public int compare(ExecutionCourse o1, ExecutionCourse o2) { final int cep = o1.getExecutionPeriod().compareTo(o2.getExecutionPeriod()); if (cep != 0) { return cep; } final int c = Collator.getInstance().compare(o1.getNome(), o2.getNome()); return c == 0 ? DomainObject.COMPARATOR_BY_ID.compare(o1, o2) : c; } }; public static OrderedRelationAdapter BIBLIOGRAPHIC_REFERENCE_ORDER_ADAPTER; static { CurricularCourseExecutionCourse.addListener(new CurricularCourseExecutionCourseListener()); BIBLIOGRAPHIC_REFERENCE_ORDER_ADAPTER = new OrderedRelationAdapter( "associatedBibliographicReferences", "referenceOrder"); ExecutionCourseBibliographicReference.addListener(BIBLIOGRAPHIC_REFERENCE_ORDER_ADAPTER); } @Linkare(author = "Paulo Zenida", comments = "Included the logic to generate a final evaluation for each evaluation type") public ExecutionCourse(final String nome, final String sigla, final ExecutionSemester executionSemester, EntryPhase entryPhase) { super(); setRootDomainObject(RootDomainObject.getInstance()); addAssociatedEvaluations(new FinalEvaluation()); createAllFinalEvaluationByEvaluationType(); setAvailableGradeSubmission(Boolean.TRUE); setAvailableForInquiries(Boolean.TRUE); setNome(nome); setExecutionPeriod(executionSemester); setSigla(sigla); setComment(""); createSite(); createExecutionCourseAnnouncementBoard(nome); if (entryPhase == null) { entryPhase = EntryPhase.FIRST_PHASE_OBJ; } setEntryPhase(entryPhase); } @Linkare(author = "Paulo Zenida") private void createAllFinalEvaluationByEvaluationType() { for (final EnrolmentEvaluationType enrolmentEvaluationType : EnrolmentEvaluationType.getFinalEvaluatableTypes()) { addAssociatedEvaluations(new FinalEvaluationByEvaluationType(enrolmentEvaluationType)); } } public void editInformation(String nome, String sigla, String comment, Boolean availableGradeSubmission, EntryPhase entryPhase) { setNome(nome); setSigla(sigla); setComment(comment); setAvailableGradeSubmission(availableGradeSubmission); if (entryPhase != null) { setEntryPhase(entryPhase); } } public void editCourseLoad(ShiftType type, BigDecimal unitQuantity, BigDecimal totalQuantity) { CourseLoad courseLoad = getCourseLoadByShiftType(type); if (courseLoad == null) { new CourseLoad(this, type, unitQuantity, totalQuantity); } else { courseLoad.edit(unitQuantity, totalQuantity); } } public List getGroupings() { List result = new ArrayList(); for (final ExportGrouping exportGrouping : this.getExportGroupings()) { if (exportGrouping.getProposalState().getState() == ProposalState.ACEITE || exportGrouping.getProposalState().getState() == ProposalState.CRIADOR) { result.add(exportGrouping.getGrouping()); } } return result; } public Grouping getGroupingByName(String groupingName) { for (final Grouping grouping : this.getGroupings()) { if (grouping.getName().equals(groupingName)) { return grouping; } } return null; } public boolean existsGroupingExecutionCourse(ExportGrouping groupPropertiesExecutionCourse) { return getExportGroupings().contains(groupPropertiesExecutionCourse); } public boolean existsGroupingExecutionCourse() { return getExportGroupings().isEmpty(); } public boolean hasProposals() { boolean result = false; boolean found = false; List groupPropertiesExecutionCourseList = getExportGroupings(); Iterator iter = groupPropertiesExecutionCourseList.iterator(); while (iter.hasNext() && !found) { ExportGrouping groupPropertiesExecutionCourseAux = iter.next(); if (groupPropertiesExecutionCourseAux.getProposalState().getState().intValue() == 3) { result = true; found = true; } } return result; } public boolean isMasterDegreeDFAOrDEAOnly() { for (final CurricularCourse curricularCourse : getAssociatedCurricularCourses()) { DegreeType degreeType = curricularCourse.getDegreeCurricularPlan().getDegree().getDegreeType(); if (!degreeType.equals(DegreeType.MASTER_DEGREE) && !degreeType.equals(DegreeType.BOLONHA_ADVANCED_FORMATION_DIPLOMA) && !degreeType.equals(DegreeType.BOLONHA_SPECIALIZATION_DEGREE) && !degreeType.equals(DegreeType.BOLONHA_ADVANCED_SPECIALIZATION_DIPLOMA)) { return false; } } return true; } public ExecutionCourseSite createSite() { return new ExecutionCourseSite(this); } public void copySectionsAndItemsFrom(final ExecutionCourse executionCourseFrom) { this.getSite().copySectionsAndItemsFrom(executionCourseFrom.getSite()); } public void createEvaluationMethod(final MultiLanguageString evaluationElements) { if (evaluationElements == null) { throw new NullPointerException(); } final EvaluationMethod evaluationMethod = new EvaluationMethod(); evaluationMethod.setEvaluationElements(evaluationElements); evaluationMethod.setExecutionCourse(this); } public void copyEvaluationMethodFrom(ExecutionCourse executionCourseFrom) { if (executionCourseFrom.getEvaluationMethod() != null) { final EvaluationMethod evaluationMethodFrom = executionCourseFrom.getEvaluationMethod(); final EvaluationMethod evaluationMethodTo = this.getEvaluationMethod(); if (evaluationMethodTo == null) { this.createEvaluationMethod(evaluationMethodFrom.getEvaluationElements()); } else { evaluationMethodTo.edit(evaluationMethodFrom.getEvaluationElements()); } } } public void createBibliographicReference(final String title, final String authors, final String reference, final String year, final Boolean optional) { if (title == null || authors == null || reference == null || year == null || optional == null) throw new NullPointerException(); final BibliographicReference bibliographicReference = new BibliographicReference(); bibliographicReference.setTitle(title); bibliographicReference.setAuthors(authors); bibliographicReference.setReference(reference); bibliographicReference.setYear(year); bibliographicReference.setOptional(optional); bibliographicReference.setExecutionCourse(this); } public List copyBibliographicReferencesFrom(final ExecutionCourse executionCourseFrom) { final List notCopiedBibliographicReferences = new ArrayList(); for (final BibliographicReference bibliographicReference : executionCourseFrom.getAssociatedBibliographicReferences()) { if (canAddBibliographicReference(bibliographicReference)) { this.createBibliographicReference(bibliographicReference.getTitle(), bibliographicReference.getAuthors(), bibliographicReference.getReference(), bibliographicReference.getYear(), bibliographicReference .getOptional()); } else { notCopiedBibliographicReferences.add(bibliographicReference); } } return notCopiedBibliographicReferences; } private boolean canAddBibliographicReference(final BibliographicReference bibliographicReferenceToAdd) { for (final BibliographicReference bibliographicReference : this.getAssociatedBibliographicReferences()) { if (bibliographicReference.getTitle().equals(bibliographicReferenceToAdd.getTitle())) { return false; } } return true; } public CourseReport createCourseReport(String report) { if (report == null) throw new NullPointerException(); final CourseReport courseReport = new CourseReport(); courseReport.setReport(report); courseReport.setLastModificationDateDateTime(new DateTime()); courseReport.setExecutionCourse(this); return courseReport; } public List responsibleFors() { final List res = new ArrayList(); for (final Professorship professorship : this.getProfessorships()) { Boolean responsibleFor = professorship.getResponsibleFor(); if (professorship != null && responsibleFor != null && responsibleFor) { res.add(professorship); } } return res; } public Attends getAttendsByStudent(final Registration registration) { for (final Attends attends : getAttendsSet()) { if (attends.getRegistration() == registration) { return attends; } } return null; } public Attends getAttendsByStudent(final Student student) { for (final Attends attends : getAttends()) { if (attends.isFor(student)) { return attends; } } return null; } public List getAssociatedExams() { List associatedExams = new ArrayList(); for (Evaluation evaluation : this.getAssociatedEvaluations()) { if (evaluation instanceof Exam) { associatedExams.add((Exam) evaluation); } } return associatedExams; } public List getAssociatedWrittenEvaluations() { Set writtenEvaluations = new HashSet(); writtenEvaluations.addAll(this.getAssociatedExams()); writtenEvaluations.addAll(this.getAssociatedWrittenTests()); return new ArrayList(writtenEvaluations); } public List getAssociatedWrittenTests() { List associatedWrittenTests = new ArrayList(); for (Evaluation evaluation : this.getAssociatedEvaluations()) { if (evaluation instanceof WrittenTest) { associatedWrittenTests.add((WrittenTest) evaluation); } } return associatedWrittenTests; } public List getAssociatedOnlineTests() { List associatedOnlineTests = new ArrayList(); for (Evaluation evaluation : this.getAssociatedEvaluations()) { if (evaluation instanceof OnlineTest) { associatedOnlineTests.add((OnlineTest) evaluation); } } return associatedOnlineTests; } // Delete Method public void delete() { if (canBeDeleted()) { if (hasSender()) { removeSender(); } if (hasSite()) { getSite().delete(); } if (hasBoard()) { getBoard().delete(); } for (; !getCourseLoads().isEmpty(); getCourseLoads().get(0).delete()) ; for (; !getProfessorships().isEmpty(); getProfessorships().get(0).delete()) ; for (; !getLessonPlannings().isEmpty(); getLessonPlannings().get(0).delete()) ; for (; !getExecutionCourseProperties().isEmpty(); getExecutionCourseProperties().get(0).delete()) ; for (; !getAttends().isEmpty(); getAttends().get(0).delete()) ; for (; !getForuns().isEmpty(); getForuns().get(0).delete()) ; removeFinalEvaluations(); getAssociatedCurricularCourses().clear(); getNonAffiliatedTeachers().clear(); removeExecutionPeriod(); removeRootDomainObject(); super.deleteDomainObject(); } else { throw new DomainException("error.execution.course.cant.delete"); } } private void removeFinalEvaluations() { final Iterator iterator = getAssociatedEvaluationsIterator(); while (iterator.hasNext()) { final Evaluation evaluation = iterator.next(); if (evaluation.isFinal()) { iterator.remove(); evaluation.delete(); } else { throw new DomainException("error.ExecutionCourse.cannot.remove.non.final.evaluation"); } } } public boolean canBeDeleted() { if (hasAnyAssociatedInquiriesCourses() || hasAnyAssociatedInquiriesRegistries() || hasAnyAssociatedSummaries() || !getGroupings().isEmpty() || hasAnyAssociatedBibliographicReferences() || !hasOnlyFinalEvaluations() || hasEvaluationMethod() || !getAssociatedShifts().isEmpty() || hasCourseReport() || hasAnyAttends() || (hasSite() && !getSite().isDeletable()) || (hasBoard() && !getBoard().isDeletable())) { throw new DomainException("error.execution.course.cant.delete"); } for (final Professorship professorship : getProfessorships()) { if (!professorship.canBeDeleted()) { throw new DomainException("error.execution.course.cant.delete"); } } for (ExecutionCourseForum forum : getForuns()) { if (forum.getConversationThreads().size() != 0) { throw new DomainException("error.execution.course.cant.delete"); } } return true; } private boolean hasOnlyFinalEvaluations() { for (final Evaluation evaluation : getAssociatedEvaluationsSet()) { if (!evaluation.isFinal()) { return false; } } return true; } public boolean teacherLecturesExecutionCourse(Teacher teacher) { for (Professorship professorship : this.getProfessorships()) { if (professorship.getTeacher() == teacher) { return true; } } return false; } public List getAssociatedProjects() { final List result = new ArrayList(); for (Evaluation evaluation : this.getAssociatedEvaluations()) { if (evaluation instanceof net.sourceforge.fenixedu.domain.Project) { result.add((net.sourceforge.fenixedu.domain.Project) evaluation); } } return result; } private int countAssociatedStudentsByEnrolmentNumber(int enrolmentNumber) { int executionCourseAssociatedStudents = 0; ExecutionSemester courseExecutionPeriod = getExecutionPeriod(); for (CurricularCourse curricularCourseFromExecutionCourseEntry : getAssociatedCurricularCourses()) { for (Enrolment enrolment : curricularCourseFromExecutionCourseEntry.getEnrolments()) { if (enrolment.getExecutionPeriod() == courseExecutionPeriod) { StudentCurricularPlan studentCurricularPlanEntry = enrolment.getStudentCurricularPlan(); int numberOfEnrolmentsForThatExecutionCourse = 0; for (Enrolment enrolmentsFromStudentCPEntry : studentCurricularPlanEntry.getEnrolments()) { if (enrolmentsFromStudentCPEntry.getCurricularCourse() == curricularCourseFromExecutionCourseEntry && (enrolmentsFromStudentCPEntry.getExecutionPeriod().compareTo(courseExecutionPeriod) <= 0)) { ++numberOfEnrolmentsForThatExecutionCourse; if (numberOfEnrolmentsForThatExecutionCourse > enrolmentNumber) { break; } } } if (numberOfEnrolmentsForThatExecutionCourse == enrolmentNumber) { executionCourseAssociatedStudents++; } } } } return executionCourseAssociatedStudents; } public Integer getTotalEnrolmentStudentNumber() { int executionCourseStudentNumber = 0; for (final CurricularCourse curricularCourseFromExecutionCourseEntry : getAssociatedCurricularCourses()) { for (final Enrolment enrolment : curricularCourseFromExecutionCourseEntry.getEnrolments()) { if (enrolment.getExecutionPeriod() == getExecutionPeriod()) { executionCourseStudentNumber++; } } } return executionCourseStudentNumber; } public Integer getFirstTimeEnrolmentStudentNumber() { return countAssociatedStudentsByEnrolmentNumber(1); } public Integer getSecondOrMoreTimeEnrolmentStudentNumber() { return getTotalEnrolmentStudentNumber() - getFirstTimeEnrolmentStudentNumber(); } public BigDecimal getAllShiftUnitHours(ShiftType shiftType) { BigDecimal totalTime = BigDecimal.ZERO; for (Shift shift : getAssociatedShifts()) { if (shift.containsType(shiftType)) { totalTime = totalTime.add(shift.getUnitHours()); } } return totalTime; } public BigDecimal getWeeklyCourseLoadTotalQuantityByShiftType(ShiftType type) { CourseLoad courseLoad = getCourseLoadByShiftType(type); return courseLoad != null ? courseLoad.getWeeklyHours() : BigDecimal.ZERO; } public Set getAssociatedShifts() { Set result = new HashSet(); for (CourseLoad courseLoad : getCourseLoadsSet()) { result.addAll(courseLoad.getShiftsSet()); } return result; } public Set getAssociatedLessonInstances() { Set result = new HashSet(); for (CourseLoad courseLoad : getCourseLoadsSet()) { result.addAll(courseLoad.getLessonInstances()); } return result; } public Double getStudentsNumberByShift(ShiftType shiftType) { int numShifts = getNumberOfShifts(shiftType); if (numShifts == 0) return 0.0; else return (double) getTotalEnrolmentStudentNumber() / numShifts; } public List getActiveEnrollments() { List results = new ArrayList(); for (CurricularCourse curricularCourse : this.getAssociatedCurricularCourses()) { List enrollments = curricularCourse.getActiveEnrollments(this.getExecutionPeriod()); results.addAll(enrollments); } return results; } public boolean areAllOptionalCurricularCoursesWithLessTenEnrolments() { int enrolments = 0; for (CurricularCourse curricularCourse : this.getAssociatedCurricularCourses()) { if (curricularCourse.getType() != null && curricularCourse.getType().equals(CurricularCourseType.OPTIONAL_COURSE)) { enrolments += curricularCourse.getEnrolmentsByExecutionPeriod(this.getExecutionPeriod()).size(); if (enrolments >= 10) { return false; } } else { return false; } } return true; } public static final Comparator EVALUATION_COMPARATOR = new Comparator() { public int compare(Evaluation evaluation1, Evaluation evaluation2) { final String evaluation1ComparisonString = evaluationComparisonString(evaluation1); final String evaluation2ComparisonString = evaluationComparisonString(evaluation2); return evaluation1ComparisonString.compareTo(evaluation2ComparisonString); } @Linkare(author = "Paulo Zenida", comments = "Added the FinalEvaluationByEvaluationType") private String evaluationComparisonString(final Evaluation evaluation) { final Date evaluationComparisonDate; final String evaluationTypeDistinguisher; if (evaluation instanceof AdHocEvaluation) { evaluationTypeDistinguisher = "0"; final AdHocEvaluation adHocEvaluation = (AdHocEvaluation) evaluation; evaluationComparisonDate = adHocEvaluation.getCreationDateTime().toDate(); } else if (evaluation instanceof OnlineTest) { evaluationTypeDistinguisher = "1"; final OnlineTest onlineTest = (OnlineTest) evaluation; evaluationComparisonDate = onlineTest.getDistributedTest().getBeginDateDate(); } else if (evaluation instanceof Project) { evaluationTypeDistinguisher = "2"; final Project project = (Project) evaluation; evaluationComparisonDate = project.getBegin(); } else if (evaluation instanceof WrittenEvaluation) { evaluationTypeDistinguisher = "3"; final WrittenEvaluation writtenEvaluation = (WrittenEvaluation) evaluation; evaluationComparisonDate = writtenEvaluation.getDayDate(); } else if (evaluation instanceof FinalEvaluation) { evaluationTypeDistinguisher = "4"; final ExecutionCourse executionCourse = evaluation.getAssociatedExecutionCourses().get(0); evaluationComparisonDate = executionCourse.getExecutionPeriod().getEndDate(); } else if (evaluation instanceof FinalEvaluationByEvaluationType) { evaluationTypeDistinguisher = "5"; final ExecutionCourse executionCourse = evaluation.getAssociatedExecutionCourses().get(0); evaluationComparisonDate = executionCourse.getExecutionPeriod().getEndDate(); } else { throw new DomainException("unknown.evaluation.type", evaluation.getClass().getName()); } return DateFormatUtil.format(evaluationTypeDistinguisher + "_yyyy/MM/dd", evaluationComparisonDate) + evaluation.getIdInternal(); } }; public List getOrderedAssociatedEvaluations() { final List orderedEvaluations = new ArrayList(getAssociatedEvaluations()); Collections.sort(orderedEvaluations, EVALUATION_COMPARATOR); return orderedEvaluations; } public Set getOrderedAttends() { final Set orderedAttends = new TreeSet(Attends.COMPARATOR_BY_STUDENT_NUMBER); orderedAttends.addAll(getAttends()); return orderedAttends; } private static class CurricularCourseExecutionCourseListener extends dml.runtime.RelationAdapter { @Override public void afterAdd(ExecutionCourse execution, CurricularCourse curricular) { for (final Enrolment enrolment : curricular.getEnrolments()) { if (enrolment.getExecutionPeriod().equals(execution.getExecutionPeriod())) { associateAttend(enrolment, execution); } } fillCourseLoads(execution, curricular); } @Override public void afterRemove(ExecutionCourse execution, CurricularCourse curricular) { if (execution != null) { for (Attends attends : execution.getAttends()) { if ((attends.getEnrolment() != null) && (attends.getEnrolment().getCurricularCourse().equals(curricular))) { attends.setEnrolment(null); } } } } private static void associateAttend(Enrolment enrolment, ExecutionCourse executionCourse) { if (!alreadyHasAttend(enrolment, executionCourse.getExecutionPeriod())) { Attends attends = executionCourse.getAttendsByStudent(enrolment.getStudentCurricularPlan().getRegistration()); if (attends == null) { attends = new Attends(enrolment.getStudentCurricularPlan().getRegistration(), executionCourse); } enrolment.addAttends(attends); } } private static boolean alreadyHasAttend(Enrolment enrolment, ExecutionSemester executionSemester) { for (Attends attends : enrolment.getAttends()) { if (attends.getExecutionCourse().getExecutionPeriod().equals(executionSemester)) { return true; } } return false; } private void fillCourseLoads(ExecutionCourse execution, CurricularCourse curricular) { for (ShiftType shiftType : ShiftType.values()) { BigDecimal totalHours = curricular.getTotalHoursByShiftType(shiftType, execution.getExecutionPeriod()); if (totalHours != null && totalHours.compareTo(BigDecimal.ZERO) == 1) { CourseLoad courseLoad = execution.getCourseLoadByShiftType(shiftType); if (courseLoad == null) { new CourseLoad(execution, shiftType, null, totalHours); } } } } } public class WeeklyWorkLoadView { final Interval executionPeriodInterval; final int numberOfWeeks; final Interval[] intervals; final int[] numberResponses; final int[] contactSum; final int[] autonomousStudySum; final int[] otherSum; final int[] totalSum; public WeeklyWorkLoadView(final Interval executionPeriodInterval) { this.executionPeriodInterval = executionPeriodInterval; final Period period = executionPeriodInterval.toPeriod(); int extraWeek = period.getDays() > 0 ? 1 : 0; numberOfWeeks = (period.getYears() * 12 + period.getMonths()) * 4 + period.getWeeks() + extraWeek + 1; intervals = new Interval[numberOfWeeks]; numberResponses = new int[numberOfWeeks]; contactSum = new int[numberOfWeeks]; autonomousStudySum = new int[numberOfWeeks]; otherSum = new int[numberOfWeeks]; totalSum = new int[numberOfWeeks]; for (int i = 0; i < numberOfWeeks; i++) { final DateTime start = executionPeriodInterval.getStart().plusWeeks(i); final DateTime end = start.plusWeeks(1); intervals[i] = new Interval(start, end); } } public void add(final Attends attends) { for (final WeeklyWorkLoad weeklyWorkLoad : attends.getWeeklyWorkLoads()) { final int weekIndex = weeklyWorkLoad.getWeekOffset(); if (consistentAnswers(attends, weekIndex)) { numberResponses[weekIndex]++; final Integer contact = weeklyWorkLoad.getContact(); contactSum[weekIndex] += contact != null ? contact.intValue() : 0; final Integer autounomousStudy = weeklyWorkLoad.getAutonomousStudy(); autonomousStudySum[weekIndex] += autounomousStudy != null ? autounomousStudy.intValue() : 0; final Integer other = weeklyWorkLoad.getOther(); otherSum[weekIndex] += other != null ? other.intValue() : 0; totalSum[weekIndex] = contactSum[weekIndex] + autonomousStudySum[weekIndex] + otherSum[weekIndex]; } } } private boolean consistentAnswers(final Attends attends, final int weekIndex) { int weeklyTotal = 0; for (final Attends someAttends : attends.getRegistration().getAssociatedAttends()) { for (final WeeklyWorkLoad weeklyWorkLoad : someAttends.getWeeklyWorkLoads()) { if (weeklyWorkLoad.getWeekOffset().intValue() == weekIndex) { weeklyTotal += weeklyWorkLoad.getTotal(); } } } return weeklyTotal <= 140; } public Interval[] getIntervals() { return intervals; } public Interval getExecutionPeriodInterval() { return executionPeriodInterval; } public int[] getContactSum() { return contactSum; } public int[] getAutonomousStudySum() { return autonomousStudySum; } public int[] getOtherSum() { return otherSum; } public int[] getNumberResponses() { return numberResponses; } public double[] getContactAverage() { return average(getContactSum(), getNumberResponses()); } public double[] getAutonomousStudyAverage() { return average(getAutonomousStudySum(), getNumberResponses()); } public double[] getOtherAverage() { return average(getOtherSum(), getNumberResponses()); } public double[] getTotalAverage() { final double[] valuesAverage = new double[numberOfWeeks]; for (int i = 0; i < numberOfWeeks; i++) { valuesAverage[i] = Math.round((0.0 + getContactSum()[i] + getAutonomousStudySum()[i] + getOtherSum()[i]) / getNumberResponses()[i]); } return valuesAverage; } private double[] average(final int[] values, final int[] divisor) { final double[] valuesAverage = new double[numberOfWeeks]; for (int i = 0; i < numberOfWeeks; i++) { valuesAverage[i] = Math.round((0.0 + values[i]) / divisor[i]); } return valuesAverage; } private double add(final double[] values) { double total = 0; for (int i = 0; i < values.length; i++) { total += values[i]; } return total; } public double getContactAverageTotal() { return add(getContactAverage()); } public double getAutonomousStudyAverageTotal() { return add(getAutonomousStudyAverage()); } public double getOtherAverageTotal() { return add(getOtherAverage()); } public double getTotalAverageTotal() { return add(getTotalAverage()); } public int getNumberResponsesTotal() { int total = 0; for (int i = 0; i < getNumberResponses().length; i++) { total += getNumberResponses()[i]; } return total; } private int getNumberWeeksForAverageCalculation() { if (!getAttendsSet().isEmpty()) { final Attends attends = findAttendsWithEnrolment(); if (attends != null) { int currentWeekOffset = attends.calculateCurrentWeekOffset(); if (currentWeekOffset > 0 && currentWeekOffset < numberOfWeeks) { return currentWeekOffset; } } } return numberOfWeeks; } public double getContactAverageTotalAverage() { final int numberOfWeeks = getNumberWeeksForAverageCalculation(); return numberOfWeeks > 0 ? Math.round(getContactAverageTotal() / numberOfWeeks) : 0; } public double getAutonomousStudyAverageTotalAverage() { final int numberOfWeeks = getNumberWeeksForAverageCalculation(); return numberOfWeeks > 0 ? Math.round(getAutonomousStudyAverageTotal() / getNumberWeeksForAverageCalculation()) : 0; } public double getOtherAverageTotalAverage() { final int numberOfWeeks = getNumberWeeksForAverageCalculation(); return numberOfWeeks > 0 ? Math.round(getOtherAverageTotal() / getNumberWeeksForAverageCalculation()) : 0; } public double getTotalAverageTotalAverage() { final int numberOfWeeks = getNumberWeeksForAverageCalculation(); return numberOfWeeks > 0 ? Math.round(getTotalAverageTotal() / getNumberWeeksForAverageCalculation()) : 0; } public double getNumberResponsesTotalAverage() { final int numberOfWeeks = getNumberWeeksForAverageCalculation(); return numberOfWeeks > 0 ? Math.round((0.0 + getNumberResponsesTotal()) / getNumberWeeksForAverageCalculation()) : 0; } } public Interval getInterval() { final ExecutionSemester executionSemester = getExecutionPeriod(); final DateTime beginningOfSemester = new DateTime(executionSemester.getBeginDateYearMonthDay()); final DateTime firstMonday = beginningOfSemester.withField(DateTimeFieldType.dayOfWeek(), 1); final DateTime endOfSemester = new DateTime(executionSemester.getEndDateYearMonthDay()); final DateTime nextLastMonday = endOfSemester.withField(DateTimeFieldType.dayOfWeek(), 1).plusWeeks(1); return new Interval(firstMonday, nextLastMonday); } public WeeklyWorkLoadView getWeeklyWorkLoadView() { final Attends attends = findAttendsWithEnrolment(); if (attends != null) { final Interval interval = attends.getWeeklyWorkLoadInterval(); final WeeklyWorkLoadView weeklyWorkLoadView = new WeeklyWorkLoadView(interval); for (final Attends attend : getAttends()) { weeklyWorkLoadView.add(attend); } return weeklyWorkLoadView; } else { return null; } } private Attends findAttendsWithEnrolment() { for (final Attends attends : getAttends()) { if (attends.getEnrolment() != null) { return attends; } } return null; } public boolean hasGrouping(final Grouping grouping) { for (final ExportGrouping exportGrouping : getExportGroupings()) { if (grouping == exportGrouping.getGrouping()) { return true; } } return false; } public Shift findShiftByName(final String shiftName) { for (final Shift shift : getAssociatedShifts()) { if (shift.getNome().equals(shiftName)) { return shift; } } return null; } public Set findShiftByType(final ShiftType shiftType) { final Set shifts = new HashSet(); for (final Shift shift : getAssociatedShifts()) { if (shift.containsType(shiftType)) { shifts.add(shift); } } return shifts; } public Set findSchoolClasses() { final Set schoolClasses = new HashSet(); for (final Shift shift : getAssociatedShifts()) { schoolClasses.addAll(shift.getAssociatedClasses()); } return schoolClasses; } public List readSummariesOfTeachersWithoutProfessorship() { List summaries = new ArrayList(); for (Summary summary : this.getAssociatedSummaries()) { if (!summary.hasProfessorship() && (summary.hasTeacher() || (summary.getTeacherName() != null && !summary.getTeacherName().equals("")))) { summaries.add(summary); } } return summaries; } public ExportGrouping getExportGrouping(final Grouping grouping) { for (final ExportGrouping exportGrouping : this.getExportGroupingsSet()) { if (exportGrouping.getGrouping() == grouping) { return exportGrouping; } } return null; } public boolean hasExportGrouping(final Grouping grouping) { return getExportGrouping(grouping) != null; } public boolean hasScopeInGivenSemesterAndCurricularYearInDCP(CurricularYear curricularYear, DegreeCurricularPlan degreeCurricularPlan) { for (CurricularCourse curricularCourse : this.getAssociatedCurricularCourses()) { if (curricularCourse.hasScopeInGivenSemesterAndCurricularYearInDCP(curricularYear, degreeCurricularPlan, getExecutionPeriod())) { return true; } } return false; } public Set findVisibleMetadata() { final Set visibleMetadata = new HashSet(); for (final Metadata metadata : getMetadatasSet()) { if (metadata.getVisibility() != null && metadata.getVisibility().booleanValue()) { visibleMetadata.add(metadata); } } return visibleMetadata; } public void createForum(MultiLanguageString name, MultiLanguageString description) { if (hasForumWithName(name)) { throw new DomainException("executionCourse.already.existing.forum"); } this.addForuns(new ExecutionCourseForum(name, description)); } public ExecutionCourseAnnouncementBoard createExecutionCourseAnnouncementBoard(final String name) { return new ExecutionCourseAnnouncementBoard(name, this, new ExecutionCourseTeachersGroup(this), null, new RoleTypeGroup( RoleType.MANAGER), ExecutionCourseBoardPermittedGroupType.ECB_EXECUTION_COURSE_TEACHERS, ExecutionCourseBoardPermittedGroupType.ECB_PUBLIC, ExecutionCourseBoardPermittedGroupType.ECB_MANAGER); } public boolean hasForumWithName(MultiLanguageString name) { return hasSite() && getForumByName(name) != null; } public ExecutionCourseForum getForumByName(MultiLanguageString name) { if (!hasSite()) { return null; } return getSite().getForumByName(name); } public void addForuns(ExecutionCourseForum forum) { if (!hasSite()) { throw new DomainException("error.cannot.add.forum.empty.site"); } getSite().addForum(forum); } public void checkIfCanAddForum(MultiLanguageString name) { if (!hasSite()) { throw new DomainException("error.cannot.add.forum.empty.site"); } if (hasForumWithName(name)) { throw new DomainException("executionCourse.already.existing.forum"); } } public SortedSet getDegreesSortedByDegreeName() { final SortedSet degrees = new TreeSet(Degree.COMPARATOR_BY_DEGREE_TYPE_AND_NAME_AND_ID); for (final CurricularCourse curricularCourse : getAssociatedCurricularCoursesSet()) { final DegreeCurricularPlan degreeCurricularPlan = curricularCourse.getDegreeCurricularPlan(); degrees.add(degreeCurricularPlan.getDegree()); } return degrees; } public SortedSet getCurricularCoursesSortedByDegreeAndCurricularCourseName() { final SortedSet curricularCourses = new TreeSet( CurricularCourse.CURRICULAR_COURSE_COMPARATOR_BY_DEGREE_AND_NAME); curricularCourses.addAll(getAssociatedCurricularCoursesSet()); return curricularCourses; } public Set getCompetenceCourses() { final Set competenceCourses = new HashSet(); for (final CurricularCourse curricularCourse : getAssociatedCurricularCoursesSet()) { final CompetenceCourse competenceCourse = curricularCourse.getCompetenceCourse(); if (competenceCourse != null) { competenceCourses.add(competenceCourse); } } return competenceCourses; } public Set getCompetenceCoursesInformations() { final Set competenceCourseInformations = new HashSet(); for (final CurricularCourse curricularCourse : getAssociatedCurricularCoursesSet()) { final CompetenceCourse competenceCourse = curricularCourse.getCompetenceCourse(); if (competenceCourse != null) { final CompetenceCourseInformation competenceCourseInformation = competenceCourse .findCompetenceCourseInformationForExecutionPeriod(getExecutionPeriod()); if (competenceCourseInformation != null) { competenceCourseInformations.add(competenceCourseInformation); } } } return competenceCourseInformations; } public List getCurricularCoursesWithDegreeType() { List result = new ArrayList(); for (CurricularCourse curricularCourse : this.getAssociatedCurricularCoursesSet()) { if (curricularCourse.getDegreeType().getAdministrativeOfficeType() == AdministrativeOfficeType.DEGREE) { result.add(curricularCourse); } } return result; } public boolean hasAnyDegreeGradeToSubmit(final ExecutionSemester period, final DegreeCurricularPlan degreeCurricularPlan) { for (final CurricularCourse curricularCourse : getCurricularCoursesWithDegreeType()) { if (degreeCurricularPlan == null || degreeCurricularPlan.equals(curricularCourse.getDegreeCurricularPlan())) { if (curricularCourse.hasAnyDegreeGradeToSubmit(period)) { return true; } } } return false; } public boolean hasAnyDegreeMarkSheetToConfirm(ExecutionSemester period, DegreeCurricularPlan degreeCurricularPlan) { for (final CurricularCourse curricularCourse : this.getCurricularCoursesWithDegreeType()) { if (degreeCurricularPlan == null || degreeCurricularPlan.equals(curricularCourse.getDegreeCurricularPlan())) { if (curricularCourse.hasAnyDegreeMarkSheetToConfirm(period)) { return true; } } } return false; } public String constructShiftName(final Shift shift, final int n) { final String number = n < 10 ? "0" + n : Integer.toString(n); StringBuilder typesName = new StringBuilder(); for (ShiftType shiftType : shift.getSortedTypes()) { typesName.append(shiftType.getSiglaTipoAula()); } return StringAppender.append(getSigla(), typesName.toString(), number); } public SortedSet getShiftsByTypeOrderedByShiftName(final ShiftType shiftType) { final SortedSet shifts = new TreeSet(Shift.SHIFT_COMPARATOR_BY_NAME); for (final Shift shift : getAssociatedShifts()) { if (shift.containsType(shiftType)) { shifts.add(shift); } } return shifts; } public void setShiftNames() { final SortedSet shifts = CollectionUtils.constructSortedSet(getAssociatedShifts(), Shift.SHIFT_COMPARATOR_BY_TYPE_AND_ORDERED_LESSONS); int counter = 0; for (final Shift shift : shifts) { final String name = constructShiftName(shift, ++counter); shift.setNome(name); } } public boolean hasProjectsWithOnlineSubmission() { for (Project project : getAssociatedProjects()) { if (project.getOnlineSubmissionsAllowed() == true) { return true; } } return false; } public List getProjectsWithOnlineSubmission() { List result = new ArrayList(); for (Project project : getAssociatedProjects()) { if (project.getOnlineSubmissionsAllowed() == true) { result.add(project); } } return result; } private Set getAllSchoolClassesOrBy(DegreeCurricularPlan degreeCurricularPlan) { final Set result = new HashSet(); for (final Shift shift : getAssociatedShifts()) { for (final SchoolClass schoolClass : shift.getAssociatedClassesSet()) { if (degreeCurricularPlan == null || schoolClass.getExecutionDegree().getDegreeCurricularPlan() == degreeCurricularPlan) { result.add(schoolClass); } } } return result; } public Set getSchoolClassesBy(DegreeCurricularPlan degreeCurricularPlan) { return getAllSchoolClassesOrBy(degreeCurricularPlan); } public Set getSchoolClasses() { return getAllSchoolClassesOrBy(null); } public boolean isLecturedIn(final ExecutionYear executionYear) { return getExecutionPeriod().getExecutionYear() == executionYear; } public boolean isLecturedIn(final ExecutionSemester executionSemester) { return getExecutionPeriod() == executionSemester; } public SortedSet getProfessorshipsSortedAlphabetically() { final SortedSet professorhips = new TreeSet(Professorship.COMPARATOR_BY_PERSON_NAME); professorhips.addAll(getProfessorshipsSet()); return professorhips; } public SummariesSearchBean getSummariesSearchBean() { return new SummariesSearchBean(this); } public Set getLessons() { final Set lessons = new HashSet(); for (final Shift shift : getAssociatedShifts()) { lessons.addAll(shift.getAssociatedLessonsSet()); } return lessons; } public SortedSet getWrittenEvaluations() { final SortedSet writtenEvaluations = new TreeSet( WrittenEvaluation.COMPARATOR_BY_BEGIN_DATE); for (final Evaluation evaluation : getAssociatedEvaluationsSet()) { if (evaluation instanceof WrittenEvaluation) { writtenEvaluations.add((WrittenEvaluation) evaluation); } } return writtenEvaluations; } public SortedSet getShiftsOrderedByLessons() { final SortedSet shifts = new TreeSet(Shift.SHIFT_COMPARATOR_BY_TYPE_AND_ORDERED_LESSONS); shifts.addAll(getAssociatedShifts()); return shifts; } public Map> getCurricularCoursesIndexedByCompetenceCourse() { final Map> curricularCourseMap = new HashMap>(); for (final CurricularCourse curricularCourse : getAssociatedCurricularCoursesSet()) { if (curricularCourse.isBolonhaDegree()) { final CompetenceCourse competenceCourse = curricularCourse.getCompetenceCourse(); final Set curricularCourses; if (curricularCourseMap.containsKey(competenceCourse)) { curricularCourses = curricularCourseMap.get(competenceCourse); } else { curricularCourses = new TreeSet( CurricularCourse.CURRICULAR_COURSE_COMPARATOR_BY_DEGREE_AND_NAME); curricularCourseMap.put(competenceCourse, curricularCourses); } curricularCourses.add(curricularCourse); } } return curricularCourseMap; } public boolean getHasAnySecondaryBibliographicReference() { return hasAnyBibliographicReferenceByBibliographicReferenceType(BibliographicReferenceType.SECONDARY); } public boolean getHasAnyMainBibliographicReference() { return hasAnyBibliographicReferenceByBibliographicReferenceType(BibliographicReferenceType.MAIN); } private boolean hasAnyBibliographicReferenceByBibliographicReferenceType(BibliographicReferenceType referenceType) { for (final BibliographicReference bibliographicReference : getAssociatedBibliographicReferencesSet()) { if ((referenceType.equals(BibliographicReferenceType.SECONDARY) && bibliographicReference.getOptional() .booleanValue()) || (referenceType.equals(BibliographicReferenceType.MAIN) && !bibliographicReference.getOptional() .booleanValue())) { return true; } } for (final CurricularCourse curricularCourse : getAssociatedCurricularCoursesSet()) { final CompetenceCourse competenceCourse = curricularCourse.getCompetenceCourse(); if (competenceCourse != null) { final CompetenceCourseInformation competenceCourseInformation = competenceCourse .findCompetenceCourseInformationForExecutionPeriod(getExecutionPeriod()); if (competenceCourseInformation != null) { final net.sourceforge.fenixedu.domain.degreeStructure.BibliographicReferences bibliographicReferences = competenceCourseInformation .getBibliographicReferences(); if (bibliographicReferences != null) { for (final net.sourceforge.fenixedu.domain.degreeStructure.BibliographicReferences.BibliographicReference bibliographicReference : bibliographicReferences .getBibliographicReferencesList()) { if (bibliographicReference.getType() == referenceType) { return true; } } } } } } return false; } public List getLessonPlanningsOrderedByOrder(ShiftType lessonType) { final List lessonPlannings = new ArrayList(); for (LessonPlanning planning : getLessonPlanningsSet()) { if (planning.getLessonType().equals(lessonType)) { lessonPlannings.add(planning); } } Collections.sort(lessonPlannings, LessonPlanning.COMPARATOR_BY_ORDER); return lessonPlannings; } public LessonPlanning getLessonPlanning(ShiftType lessonType, Integer order) { for (LessonPlanning planning : getLessonPlanningsSet()) { if (planning.getLessonType().equals(lessonType) && planning.getOrderOfPlanning().equals(order)) { return planning; } } return null; } public Set getShiftTypes() { Set shiftTypes = new TreeSet(); for (CourseLoad courseLoad : getCourseLoads()) { shiftTypes.add(courseLoad.getType()); } return shiftTypes; } public void copyLessonPlanningsFrom(ExecutionCourse executionCourseFrom) { Set shiftTypes = getShiftTypes(); for (ShiftType shiftType : executionCourseFrom.getShiftTypes()) { if (shiftTypes.contains(shiftType)) { List lessonPlanningsFrom = executionCourseFrom.getLessonPlanningsOrderedByOrder(shiftType); if (!lessonPlanningsFrom.isEmpty()) { for (LessonPlanning planning : lessonPlanningsFrom) { new LessonPlanning(planning.getTitle(), planning.getPlanning(), planning.getLessonType(), this); } } } } } public void createLessonPlanningsUsingSummariesFrom(Shift shift) { List summaries = new ArrayList(); summaries.addAll(shift.getAssociatedSummaries()); Collections.sort(summaries, new ReverseComparator(Summary.COMPARATOR_BY_DATE_AND_HOUR)); for (Summary summary : summaries) { for (ShiftType shiftType : shift.getTypes()) { new LessonPlanning(summary.getTitle(), summary.getSummaryText(), shiftType, this); } } } public void deleteLessonPlanningsByLessonType(ShiftType shiftType) { List lessonPlanningsOrderedByOrder = getLessonPlanningsOrderedByOrder(shiftType); for (LessonPlanning planning : lessonPlanningsOrderedByOrder) { planning.deleteWithoutReOrder(); } } public Integer getNumberOfShifts(ShiftType shiftType) { int numShifts = 0; for (Shift shiftEntry : getAssociatedShifts()) { if (shiftEntry.containsType(shiftType)) { numShifts++; } } return numShifts; } public Double getCurricularCourseEnrolmentsWeight(CurricularCourse curricularCourse) { Double totalEnrolmentStudentNumber = Double.valueOf(getTotalEnrolmentStudentNumber()); if (totalEnrolmentStudentNumber > 0d) { return curricularCourse.getTotalEnrolmentStudentNumber(getExecutionPeriod()) / totalEnrolmentStudentNumber; } else { return 0d; } } public Set getOldShiftTypesToEnrol() { final List validShiftTypes = Arrays.asList(new ShiftType[] { ShiftType.TEORICA, ShiftType.PRATICA, ShiftType.LABORATORIAL, ShiftType.TEORICO_PRATICA }); final Set result = new HashSet(4); for (final Shift shift : getAssociatedShifts()) { for (ShiftType shiftType : shift.getTypes()) { if (validShiftTypes.contains(shiftType)) { result.add(shiftType); break; } } } return result; } /** * Tells if all the associated Curricular Courses load are the same */ public String getEqualLoad() { for (final CurricularCourse curricularCourse : getAssociatedCurricularCourses()) { for (ShiftType type : ShiftType.values()) { if (!getEqualLoad(type, curricularCourse)) { return Boolean.FALSE.toString(); } } } return Boolean.TRUE.toString(); } public boolean getEqualLoad(ShiftType type, CurricularCourse curricularCourse) { if (type != null) { if (type.equals(ShiftType.DUVIDAS) || type.equals(ShiftType.RESERVA)) { return true; } BigDecimal ccTotalHours = curricularCourse.getTotalHoursByShiftType(type, getExecutionPeriod()); CourseLoad courseLoad = getCourseLoadByShiftType(type); if ((courseLoad == null && ccTotalHours == null) || (courseLoad == null && ccTotalHours != null && ccTotalHours.compareTo(BigDecimal.ZERO) == 0) || (courseLoad != null && ccTotalHours != null && courseLoad.getTotalQuantity().compareTo(ccTotalHours) == 0)) { return true; } } return false; } public List getSummariesByShiftType(ShiftType shiftType) { List summaries = new ArrayList(); for (Summary summary : getAssociatedSummariesSet()) { if (summary.getSummaryType() != null && summary.getSummaryType().equals(shiftType)) { summaries.add(summary); } } return summaries; } public List getSummariesWithoutProfessorshipButWithTeacher(Teacher teacher) { List summaries = new ArrayList(); if (teacher != null) { for (Summary summary : getAssociatedSummariesSet()) { if (summary.getTeacher() != null && summary.getTeacher().equals(teacher)) { summaries.add(summary); } } } return summaries; } public void moveSummariesFromTeacherToProfessorship(Teacher teacher, Professorship professorship) { List summaries = getSummariesWithoutProfessorshipButWithTeacher(teacher); for (Summary summary : summaries) { summary.moveFromTeacherToProfessorship(professorship); } } @Override public String getNome() { if (Language.getUserLanguage() == Language.en && hasAnyAssociatedCurricularCourses()) { final StringBuilder stringBuilder = new StringBuilder(); final Set names = new HashSet(); for (final CurricularCourse curricularCourse : getAssociatedCurricularCourses()) { if (!curricularCourse.getActiveDegreeModuleScopesInExecutionPeriod(getExecutionPeriod()).isEmpty()) { final String name = curricularCourse.getNameEn(); if (!names.contains(name)) { names.add(name); if (stringBuilder.length() > 0) { stringBuilder.append(" / "); } stringBuilder.append(name); } } } if (stringBuilder.length() > 0) { return stringBuilder.toString(); } boolean unique = true; final String nameEn = getAssociatedCurricularCourses().get(0).getNameEn(); for (final CurricularCourse curricularCourse : getAssociatedCurricularCourses()) { if (curricularCourse.getNameEn() == null || !curricularCourse.getNameEn().equals(nameEn)) { unique = false; break; } } if (unique) { return nameEn; } else { return super.getNome(); } } return super.getNome(); } public String getDegreePresentationString() { SortedSet degrees = this.getDegreesSortedByDegreeName(); String result = ""; int i = 0; for (Degree degree : degrees) { if (i > 0) result += ", "; result += degree.getSigla(); i++; } return result; } public boolean hasPublishedTestGroups() { return this.getPublishedTestGroupsCount() > 0; } public Integer getPublishedTestGroupsCount() { return this.getPublishedTestGroups().size(); } public boolean hasFinishedTestGroups() { return this.getFinishedTestGroupsCount() > 0; } public Integer getFinishedTestGroupsCount() { return this.getFinishedTestGroups().size(); } public List getPublishedTestGroups() { List testGroups = new ArrayList(); for (NewTestGroup testGroup : this.getTestGroups()) { if (testGroup.getStatus().equals(TestGroupStatus.PUBLISHED)) { testGroups.add(testGroup); } } return testGroups; } public List getFinishedTestGroups() { List testGroups = new ArrayList(); for (NewTestGroup testGroup : this.getTestGroups()) { if (testGroup.isCorrected()) { testGroups.add(testGroup); } } return testGroups; } public Registration getRegistration(Person person) { for (Registration registration : person.getStudents()) { for (StudentCurricularPlan studentCurricularPlan : registration.getStudentCurricularPlans()) { for (Enrolment enrolment : studentCurricularPlan.getEnrolments()) { for (ExecutionCourse course : enrolment.getExecutionCourses()) { if (course.equals(this)) { return registration; } } } } } return null; } public ExecutionYear getExecutionYear() { return getExecutionPeriod().getExecutionYear(); } public CurricularCourse getCurricularCourseFor(final DegreeCurricularPlan degreeCurricularPlan) { for (final CurricularCourse curricularCourse : getAssociatedCurricularCoursesSet()) { if (curricularCourse.getDegreeCurricularPlan() == degreeCurricularPlan) { return curricularCourse; } } return null; } public SortedSet getOrderedBibliographicReferences() { TreeSet references = new TreeSet( BibliographicReference.COMPARATOR_BY_ORDER); references.addAll(getAssociatedBibliographicReferences()); return references; } public void setBibliographicReferencesOrder(List references) { BIBLIOGRAPHIC_REFERENCE_ORDER_ADAPTER.updateOrder(this, references); } public List getMainBibliographicReferences() { List references = new ArrayList(); for (BibliographicReference reference : getAssociatedBibliographicReferences()) { if (!reference.isOptional()) { references.add(reference); } } return references; } public List getSecondaryBibliographicReferences() { List references = new ArrayList(); for (BibliographicReference reference : getAssociatedBibliographicReferences()) { if (reference.isOptional()) { references.add(reference); } } return references; } public boolean isCompentenceCourseMainBibliographyAvailable() { for (CompetenceCourseInformation information : getCompetenceCoursesInformations()) { BibliographicReferences bibliographicReferences = information.getBibliographicReferences(); if (bibliographicReferences != null && !bibliographicReferences.getMainBibliographicReferences().isEmpty()) { return true; } } return false; } public boolean isCompentenceCourseSecondaryBibliographyAvailable() { for (CompetenceCourseInformation information : getCompetenceCoursesInformations()) { BibliographicReferences bibliographicReferences = information.getBibliographicReferences(); if (bibliographicReferences != null && !bibliographicReferences.getSecondaryBibliographicReferences().isEmpty()) { return true; } } return false; } public Collection getCurriculums(final ExecutionYear executionYear) { final Collection result = new HashSet(); for (final CurricularCourse curricularCourse : getAssociatedCurricularCoursesSet()) { final Curriculum curriculum = executionYear == null ? curricularCourse.findLatestCurriculum() : curricularCourse .findLatestCurriculumModifiedBefore(executionYear.getEndDate()); if (curriculum != null) { result.add(curriculum); } } return result; } public boolean isInExamPeriod() { final YearMonthDay yearMonthDay = new YearMonthDay(); final ExecutionSemester executionSemester = getExecutionPeriod(); final ExecutionYear executionYear = getExecutionPeriod().getExecutionYear(); for (final CurricularCourse curricularCourse : getAssociatedCurricularCourses()) { final DegreeCurricularPlan degreeCurricularPlan = curricularCourse.getDegreeCurricularPlan(); final ExecutionDegree executionDegree = degreeCurricularPlan.getExecutionDegreeByYear(executionYear); final YearMonthDay startExamsPeriod; if (executionSemester.getSemester().intValue() == 1) { startExamsPeriod = executionDegree.getPeriodExamsFirstSemester().getStartYearMonthDay(); } else if (executionSemester.getSemester().intValue() == 2) { startExamsPeriod = executionDegree.getPeriodExamsSecondSemester().getStartYearMonthDay(); } else { throw new DomainException("unsupported.execution.period.semester"); } if (!startExamsPeriod.minusDays(2).isAfter(yearMonthDay)) { return true; } } return false; } public List getGroupingsToEnrol() { final List result = new ArrayList(); for (final Grouping grouping : getGroupings()) { if (checkPeriodEnrollmentFor(grouping)) { result.add(grouping); } } return result; } private boolean checkPeriodEnrollmentFor(final Grouping grouping) { final IGroupEnrolmentStrategyFactory enrolmentGroupPolicyStrategyFactory = GroupEnrolmentStrategyFactory.getInstance(); final IGroupEnrolmentStrategy strategy = enrolmentGroupPolicyStrategyFactory.getGroupEnrolmentStrategyInstance(grouping); return strategy.checkEnrolmentDate(grouping, Calendar.getInstance()); } public SortedSet getFirsExecutionDegreesByYearWithExecutionIn(ExecutionYear executionYear) { SortedSet result = new TreeSet(ExecutionDegree.EXECUTION_DEGREE_COMPARATORY_BY_YEAR); for (CurricularCourse curricularCourse : getAssociatedCurricularCourses()) { ExecutionDegree executionDegree = curricularCourse.getDegreeCurricularPlan().getExecutionDegreeByYear(executionYear); if (executionDegree != null) { result.add(executionDegree); } } return result; } @Override public Boolean getAvailableForInquiries() { if (super.getAvailableForInquiries() != null) { return super.getAvailableForInquiries(); } return Boolean.FALSE; } @Override public Boolean getAvailableGradeSubmission() { if (super.getAvailableGradeSubmission() != null) { return super.getAvailableGradeSubmission(); } return Boolean.TRUE; } public Set getDepartments() { final Set departments = new TreeSet(Department.COMPARATOR_BY_NAME); for (final CurricularCourse curricularCourse : getAssociatedCurricularCoursesSet()) { final CompetenceCourse competenceCourse = curricularCourse.getCompetenceCourse(); if (competenceCourse != null) { departments.addAll(competenceCourse.getDepartmentsSet()); } } return departments; } public GenericPair getMaxLessonsPeriod() { YearMonthDay minBeginDate = null, maxEndDate = null; Integer semester = getExecutionPeriod().getSemester(); for (final CurricularCourse curricularCourse : getAssociatedCurricularCoursesSet()) { final ExecutionDegree executionDegree = curricularCourse.getExecutionDegreeFor(getExecutionYear()); if (semester.intValue() == 1) { if (minBeginDate == null || minBeginDate.isAfter(executionDegree.getPeriodLessonsFirstSemester().getStartYearMonthDay())) { minBeginDate = executionDegree.getPeriodLessonsFirstSemester().getStartYearMonthDay(); } if (maxEndDate == null || maxEndDate.isBefore(executionDegree.getPeriodLessonsFirstSemester() .getEndYearMonthDayWithNextPeriods())) { maxEndDate = executionDegree.getPeriodLessonsFirstSemester().getEndYearMonthDayWithNextPeriods(); } } else { if (minBeginDate == null || minBeginDate.isAfter(executionDegree.getPeriodLessonsSecondSemester().getStartYearMonthDay())) { minBeginDate = executionDegree.getPeriodLessonsSecondSemester().getStartYearMonthDay(); } if (maxEndDate == null || maxEndDate.isBefore(executionDegree.getPeriodLessonsSecondSemester() .getEndYearMonthDayWithNextPeriods())) { maxEndDate = executionDegree.getPeriodLessonsSecondSemester().getEndYearMonthDayWithNextPeriods(); } } } if (minBeginDate != null && maxEndDate != null) { return new GenericPair(minBeginDate, maxEndDate); } return null; } public Map getCourseLoadsMap() { Map result = new HashMap(); List courseLoads = getCourseLoads(); for (CourseLoad courseLoad : courseLoads) { result.put(courseLoad.getType(), courseLoad); } return result; } public CourseLoad getCourseLoadByShiftType(ShiftType type) { if (type != null) { for (CourseLoad courseLoad : getCourseLoads()) { if (courseLoad.getType().equals(type)) { return courseLoad; } } } return null; } public boolean hasCourseLoadForType(ShiftType type) { CourseLoad courseLoad = getCourseLoadByShiftType(type); return courseLoad != null && !courseLoad.isEmpty(); } public boolean verifyNameEquality(String[] nameWords) { if (nameWords != null) { String courseName = getNome() + " " + getSigla(); if (courseName != null) { String[] courseNameWords = courseName.trim().split(" "); StringNormalizer.normalize(courseNameWords); int j, i; for (i = 0; i < nameWords.length; i++) { if (!nameWords[i].equals("")) { for (j = 0; j < courseNameWords.length; j++) { if (courseNameWords[j].equals(nameWords[i])) { break; } } if (j == courseNameWords.length) { return false; } } } if (i == nameWords.length) { return true; } } } return false; } public Set getAllRooms() { Set result = new HashSet(); Set lessons = getLessons(); for (Lesson lesson : lessons) { AllocatableSpace room = lesson.getSala(); if (room != null) { result.add(room); } } return result; } public String getEvaluationMethodText() { if (hasEvaluationMethod()) { final MultiLanguageString evaluationElements = getEvaluationMethod().getEvaluationElements(); return evaluationElements != null && evaluationElements.hasContent(Language.pt) ? evaluationElements .getContent(Language.pt) : !getCompetenceCourses().isEmpty() ? getCompetenceCourses().iterator().next() .getEvaluationMethod() : ""; } else { return !getCompetenceCourses().isEmpty() ? getCompetenceCourses().iterator().next().getEvaluationMethod() : ""; } } public String getEvaluationMethodTextEn() { if (hasEvaluationMethod()) { final MultiLanguageString evaluationElements = getEvaluationMethod().getEvaluationElements(); return evaluationElements != null && evaluationElements.hasContent(Language.en) ? evaluationElements .getContent(Language.en) : !getCompetenceCourses().isEmpty() ? getCompetenceCourses().iterator().next() .getEvaluationMethod() : ""; } else { return !getCompetenceCourses().isEmpty() ? getCompetenceCourses().iterator().next().getEvaluationMethod() : ""; } } public List getForuns() { if (hasSite()) { return new ArrayList(getSite().getForuns()); } else { return Collections.emptyList(); } } public AcademicInterval getAcademicInterval() { return getExecutionPeriod().getAcademicInterval(); } public static ExecutionCourse readBySiglaAndExecutionPeriod(final String sigla, ExecutionSemester executionSemester) { for (ExecutionCourse executionCourse : executionSemester.getAssociatedExecutionCoursesSet()) { if (sigla.equalsIgnoreCase(executionCourse.getSigla())) { return executionCourse; } } return null; } public static ExecutionCourse readLastByExecutionYearAndSigla(final String sigla, ExecutionYear executionYear) { SortedSet result = new TreeSet(EXECUTION_COURSE_EXECUTION_PERIOD_COMPARATOR); for (final ExecutionSemester executionSemester : executionYear.getExecutionPeriodsSet()) { for (ExecutionCourse executionCourse : executionSemester.getAssociatedExecutionCoursesSet()) { if (sigla.equalsIgnoreCase(executionCourse.getSigla())) { result.add(executionCourse); } } } return result.isEmpty() ? null : result.last(); } public static ExecutionCourse readLastBySigla(final String sigla) { SortedSet result = new TreeSet(EXECUTION_COURSE_EXECUTION_PERIOD_COMPARATOR); for (ExecutionCourse executionCourse : RootDomainObject.getInstance().getExecutionCourses()) { if (sigla.equalsIgnoreCase(executionCourse.getSigla())) { result.add(executionCourse); } } return result.isEmpty() ? null : result.last(); } public static ExecutionCourse readLastByExecutionIntervalAndSigla(final String sigla, ExecutionInterval executionInterval) { return executionInterval instanceof ExecutionSemester ? readBySiglaAndExecutionPeriod(sigla, (ExecutionSemester) executionInterval) : readLastByExecutionYearAndSigla(sigla, (ExecutionYear) executionInterval); } @Override public void setSigla(String sigla) { final String code = sigla.replace(' ', '_').replace('/', '-'); final String uniqueCode = findUniqueCode(code); super.setSigla(uniqueCode); } private String findUniqueCode(final String code) { if (!existsMatchingCode(code)) { return code; } int c; for (c = 0; existsMatchingCode(code + "-" + c); c++) ; return code + "-" + c; } private boolean existsMatchingCode(final String code) { for (final ExecutionCourse executionCourse : getExecutionPeriod().getAssociatedExecutionCoursesSet()) { if (executionCourse != this && executionCourse.getSigla().equalsIgnoreCase(code)) { return true; } } return false; } public Collection getAssociatedMarkSheets() { Collection markSheets = new HashSet(); for (CurricularCourse curricularCourse : getAssociatedCurricularCoursesSet()) { markSheets.addAll(curricularCourse.getMarkSheetsByPeriod(getExecutionPeriod())); } return markSheets; } public Set getPublishedExamsFor(final CurricularCourse curricularCourse) { final Set result = new HashSet(); for (final WrittenEvaluation eachEvaluation : getWrittenEvaluations()) { if (eachEvaluation.isExam()) { final Exam exam = (Exam) eachEvaluation; if (exam.isExamsMapPublished() && exam.contains(curricularCourse)) { result.add(exam); } } } return result; } public List getAssociatedAdHocEvaluations() { final List result = new ArrayList(); for (Evaluation evaluation : this.getAssociatedEvaluations()) { if (evaluation instanceof AdHocEvaluation) { result.add((AdHocEvaluation) evaluation); } } return result; } public List getOrderedAssociatedAdHocEvaluations() { List associatedAdHocEvaluations = getAssociatedAdHocEvaluations(); Collections.sort(associatedAdHocEvaluations, AdHocEvaluation.AD_HOC_EVALUATION_CREATION_DATE_COMPARATOR); return associatedAdHocEvaluations; } public boolean functionsAt(final Campus campus) { final ExecutionYear executionYear = getExecutionYear(); for (final CurricularCourse curricularCourse : getAssociatedCurricularCoursesSet()) { final DegreeCurricularPlan degreeCurricularPlan = curricularCourse.getDegreeCurricularPlan(); for (final ExecutionDegree executionDegree : degreeCurricularPlan.getExecutionDegreesSet()) { if (executionDegree.getCampus() == campus && executionDegree.getExecutionYear() == executionYear) { return true; } } } return false; } public Set getAttendsDegreeCurricularPlans() { final Set dcps = new HashSet(); for (final Attends attends : this.getAttendsSet()) { dcps.add(attends.getStudentCurricularPlanFromAttends().getDegreeCurricularPlan()); } return dcps; } @Checked("ExecutionCoursePredicates.executionCourseLecturingTeacherOrDegreeCoordinator") public void searchAttends(SearchExecutionCourseAttendsBean attendsBean) { final Predicate filter = attendsBean.getFilters(); final Collection validAttends = new HashSet(); final Map enrolmentNumberMap = new HashMap(); for (final Attends attends : getAttends()) { if (filter.eval(attends)) { validAttends.add(attends); addAttendsToEnrolmentNumberMap(attends, enrolmentNumberMap); } } attendsBean.setAttendsResult(validAttends); attendsBean.setEnrolmentsNumberMap(enrolmentNumberMap); } private void addAttendsToEnrolmentNumberMap(final Attends attends, Map enrolmentNumberMap) { Integer enrolmentsNumber; if (attends.getEnrolment() == null) { enrolmentsNumber = 0; } else { enrolmentsNumber = attends.getEnrolment().getNumberOfTotalEnrolmentsInThisCourse( attends.getEnrolment().getExecutionPeriod()); } Integer mapValue = enrolmentNumberMap.get(enrolmentsNumber); if (mapValue == null) { mapValue = 1; } else { mapValue += 1; } enrolmentNumberMap.put(enrolmentsNumber, mapValue); } public Collection getAssociatedDegreeCurricularPlans() { Collection result = new HashSet(); for (CurricularCourse curricularCourse : getAssociatedCurricularCoursesSet()) { result.add(curricularCourse.getDegreeCurricularPlan()); } return result; } public List getAssociatedWrittenEvaluationsForScopeAndContext(List curricularYears, DegreeCurricularPlan degreeCurricularPlan) { List result = new ArrayList(); for (WrittenEvaluation writtenEvaluation : getWrittenEvaluations()) { if (writtenEvaluation.hasScopeOrContextFor(curricularYears, degreeCurricularPlan)) { result.add(writtenEvaluation); } } return result; } public static List filterByAcademicIntervalAndDegreeCurricularPlanAndCurricularYearAndName( AcademicInterval academicInterval, DegreeCurricularPlan degreeCurricularPlan, CurricularYear curricularYear, String name) { // FIXME (PERIODS) must be changed when ExecutionCourse is linked to // ExecutionInterval ExecutionSemester executionSemester = (ExecutionSemester) ExecutionInterval.getExecutionInterval(academicInterval); return executionSemester.getExecutionCoursesByDegreeCurricularPlanAndSemesterAndCurricularYearAndName( degreeCurricularPlan, curricularYear, name); } public static List filterByAcademicInterval(AcademicInterval academicInterval) { // FIXME (PERIODS) must be changed when ExecutionCourse is linked to // ExecutionInterval ExecutionSemester executionSemester = (ExecutionSemester) ExecutionInterval.getExecutionInterval(academicInterval); return executionSemester.getAssociatedExecutionCourses(); } public static ExecutionCourse getExecutionCourseByInitials(AcademicInterval academicInterval, String courseInitials) { // FIXME (PERIODS) must be changed when ExecutionCourse is linked to // ExecutionInterval ExecutionSemester executionSemester = (ExecutionSemester) ExecutionInterval.getExecutionInterval(academicInterval); return executionSemester.getExecutionCourseByInitials(courseInitials); } public static List searchByAcademicIntervalAndExecutionDegreeYearAndName(AcademicInterval academicInterval, ExecutionDegree executionDegree, CurricularYear curricularYear, String name) { // FIXME (PERIODS) must be changed when ExecutionCourse is linked to // ExecutionInterval ExecutionSemester executionSemester = (ExecutionSemester) ExecutionInterval.getExecutionInterval(academicInterval); return executionSemester.getExecutionCoursesByDegreeCurricularPlanAndSemesterAndCurricularYearAndName(executionDegree .getDegreeCurricularPlan(), curricularYear, name); } public StudentInquiriesCourseResult getStudentInquiriesCourseResult(ExecutionDegree executionDegree) { for (StudentInquiriesCourseResult studentInquiriesCourseResult : getStudentInquiriesCourseResults()) { if (studentInquiriesCourseResult.getExecutionDegree() == executionDegree) { return studentInquiriesCourseResult; } } return null; } public int getAnsweredTeachingInquiriesCount() { int answeredTeachingInquiries = 0; for (Professorship professorship : getProfessorships()) { if (professorship.hasTeachingInquiry()) { answeredTeachingInquiries++; } } return answeredTeachingInquiries; } public TeachingInquiry getResponsibleTeachingInquiry() { for (Professorship professorship : getProfessorships()) { if (professorship.isResponsibleFor()) { return professorship.getTeachingInquiry(); } } return null; } @Linkare(author = "Paulo Zenida") public static ExecutionCourse readLastByName(final String name) { SortedSet result = new TreeSet(EXECUTION_COURSE_EXECUTION_PERIOD_COMPARATOR); for (ExecutionCourse executionCourse : RootDomainObject.getInstance().getExecutionCourses()) { if (name.equalsIgnoreCase(executionCourse.getNome())) { result.add(executionCourse); } } return result.isEmpty() ? null : result.last(); } @Linkare(author = "Paulo Zenida") public static ExecutionCourse readLastByExecutionIntervalAndName(final String name, ExecutionInterval executionInterval) { if (executionInterval instanceof ExecutionSemester) { return readByNameAndExecutionPeriod(name, (ExecutionSemester) executionInterval); } else { return readLastByExecutionYearAndName(name, (ExecutionYear) executionInterval); } } /** * Copy of readBySiglaAndExecutionPeriod() - dangerous method * * @param name * @param executionSemester * @return */ @Linkare(author = "Paulo Zenida") public static ExecutionCourse readByNameAndExecutionPeriod(final String name, ExecutionSemester executionSemester) { for (ExecutionCourse executionCourse : executionSemester.getAssociatedExecutionCoursesSet()) { if (name.equalsIgnoreCase(executionCourse.getNome())) { return executionCourse; } } return null; } @Linkare(author = "Paulo Zenida") public static ExecutionCourse readLastByExecutionYearAndName(final String name, ExecutionYear executionYear) { SortedSet result = new TreeSet(EXECUTION_COURSE_EXECUTION_PERIOD_COMPARATOR); for (final ExecutionSemester executionSemester : executionYear.getExecutionPeriodsSet()) { for (ExecutionCourse executionCourse : executionSemester.getAssociatedExecutionCoursesSet()) { if (name.equalsIgnoreCase(executionCourse.getNome())) { result.add(executionCourse); } } } return result.isEmpty() ? null : result.last(); } @Linkare(author = "Paulo Zenida") public static ExecutionCourse readByCurricularCourseAndExecutionPeriod(final CurricularCourse curricularCourse, final ExecutionSemester executionSemester) { for (ExecutionCourse executionCourse : executionSemester.getAssociatedExecutionCoursesSet()) { for (final CurricularCourse cc : executionCourse.getAssociatedCurricularCourses()) { if (cc == curricularCourse) { return executionCourse; } } } return null; } @Linkare(author = "Paulo Zenida") public void merge(final ExecutionCourse executionCourseTo) { final ExecutionCourse executionCourseFrom = this; if (!isMergeAllowed(executionCourseFrom, executionCourseTo)) { throw new DomainException("merge.is.not.allowed"); } if (haveShiftsWithSameName(executionCourseFrom, executionCourseTo)) { throw new DomainException("duplicate.shift.name.for.executioncourses"); } copyShifts(executionCourseFrom, executionCourseTo); copyLessonsInstances(executionCourseFrom, executionCourseTo); copyProfessorships(executionCourseFrom, executionCourseTo); copyAttends(executionCourseFrom, executionCourseTo); copyBibliographicReference(executionCourseFrom, executionCourseTo); if (executionCourseFrom.getEvaluationMethod() != null) { executionCourseFrom.getEvaluationMethod().delete(); } if (executionCourseFrom.getCourseReport() != null) { executionCourseFrom.getCourseReport().delete(); } copySummaries(executionCourseFrom, executionCourseTo); copyGroupPropertiesExecutionCourse(executionCourseFrom, executionCourseTo); copySite(executionCourseFrom, executionCourseTo); removeEvaluations(executionCourseFrom, executionCourseTo); copyForuns(executionCourseFrom, executionCourseTo); copyBoard(executionCourseFrom, executionCourseTo); copyInquiries(executionCourseFrom, executionCourseTo); copyDistributedTestStuff(executionCourseFrom, executionCourseTo); executionCourseTo.getAssociatedCurricularCourses().addAll(executionCourseFrom.getAssociatedCurricularCourses()); executionCourseTo.copyLessonPlanningsFrom(executionCourseFrom); executionCourseFrom.delete(); } @Linkare(author = "Paulo Zenida") private void copyDistributedTestStuff(final ExecutionCourse executionCourseFrom, final ExecutionCourse executionCourseTo) { for (final Metadata metadata : executionCourseFrom.getMetadatasSet()) { metadata.setExecutionCourse(executionCourseTo); } List distributedTests = TestScope.readDistributedTestsByTestScope(executionCourseFrom.getClass(), executionCourseFrom.getIdInternal()); for (final DistributedTest distributedTest : distributedTests) { final TestScope testScope = distributedTest.getTestScope(); testScope.setDomainObject(executionCourseTo); testScope.setKeyClass(executionCourseTo.getIdInternal()); } } @Linkare(author = "Paulo Zenida") private void copyInquiries(final ExecutionCourse executionCourseFrom, final ExecutionCourse executionCourseTo) { for (final InquiriesCourse inquiriesCourse : executionCourseFrom.getAssociatedInquiriesCoursesSet()) { inquiriesCourse.setExecutionCourse(executionCourseTo); } for (final InquiriesRegistry inquiriesRegistry : executionCourseFrom.getAssociatedInquiriesRegistries()) { inquiriesRegistry.setExecutionCourse(executionCourseTo); } } @Linkare(author = "Paulo Zenida") private void copyBoard(ExecutionCourse executionCourseFrom, ExecutionCourse executionCourseTo) { final ExecutionCourseAnnouncementBoard executionCourseAnnouncementBoardFrom = executionCourseFrom.getBoard(); final ExecutionCourseAnnouncementBoard executionCourseAnnouncementBoardTo = executionCourseTo.getBoard(); for (final Iterator iterator = executionCourseAnnouncementBoardFrom.getBookmarkOwnerSet().iterator(); iterator .hasNext(); iterator.remove()) { final Person bookmarkOwner = iterator.next(); executionCourseAnnouncementBoardTo.addBookmarkOwner(bookmarkOwner); } for (final Announcement announcement : executionCourseAnnouncementBoardFrom.getAnnouncements()) { executionCourseAnnouncementBoardTo.addAnnouncements(announcement); } executionCourseAnnouncementBoardFrom.delete(); } @Linkare(author = "Paulo Zenida") private boolean haveShiftsWithSameName(final ExecutionCourse executionCourseFrom, final ExecutionCourse executionCourseTo) { final Set shiftNames = new HashSet(); for (final Shift shift : executionCourseFrom.getAssociatedShifts()) { shiftNames.add(shift.getNome()); } for (final Shift shift : executionCourseTo.getAssociatedShifts()) { if (shiftNames.contains(shift.getNome())) { return true; } } return false; } @Linkare(author = "Paulo Zenida") private boolean isMergeAllowed(final ExecutionCourse executionCourseFrom, final ExecutionCourse executionCourseTo) { return executionCourseTo != null && executionCourseFrom != null && executionCourseFrom.getExecutionPeriod().equals(executionCourseTo.getExecutionPeriod()) && executionCourseFrom != executionCourseTo; } @Linkare(author = "Paulo Zenida") private void copySummaries(final ExecutionCourse executionCourseFrom, final ExecutionCourse executionCourseTo) { final List associatedSummaries = new ArrayList(); associatedSummaries.addAll(executionCourseFrom.getAssociatedSummaries()); for (final Summary summary : associatedSummaries) { summary.setExecutionCourse(executionCourseTo); } } @Linkare(author = "Paulo Zenida") private void copyGroupPropertiesExecutionCourse(final ExecutionCourse executionCourseFrom, final ExecutionCourse executionCourseTo) { final List associatedGroupPropertiesExecutionCourse = new ArrayList(); associatedGroupPropertiesExecutionCourse.addAll(executionCourseFrom.getExportGroupings()); for (final ExportGrouping groupPropertiesExecutionCourse : associatedGroupPropertiesExecutionCourse) { if (executionCourseTo.hasGrouping(groupPropertiesExecutionCourse.getGrouping())) { groupPropertiesExecutionCourse.delete(); } else { groupPropertiesExecutionCourse.setExecutionCourse(executionCourseTo); } } } @Linkare(author = "Paulo Zenida") private void removeEvaluations(final ExecutionCourse executionCourseFrom, final ExecutionCourse executionCourseTo) { while (!executionCourseFrom.getAssociatedEvaluations().isEmpty()) { final Evaluation evaluation = executionCourseFrom.getAssociatedEvaluations().get(0); if (evaluation instanceof FinalEvaluation) { final FinalEvaluation finalEvaluationFrom = (FinalEvaluation) evaluation; if (finalEvaluationFrom.hasAnyMarks()) { throw new DomainException("Cannot merge execution courses: marks exist for final evaluation."); } else { finalEvaluationFrom.delete(); } } else { executionCourseTo.getAssociatedEvaluations().add(evaluation); executionCourseFrom.getAssociatedEvaluations().remove(evaluation); } } } @Linkare(author = "Paulo Zenida") private void copyBibliographicReference(final ExecutionCourse executionCourseFrom, final ExecutionCourse executionCourseTo) { for (; !executionCourseFrom.getAssociatedBibliographicReferences().isEmpty(); executionCourseTo .getAssociatedBibliographicReferences().add(executionCourseFrom.getAssociatedBibliographicReferences().get(0))) ; } @Linkare(author = "Paulo Zenida") private void copyShifts(final ExecutionCourse executionCourseFrom, final ExecutionCourse executionCourseTo) { final List associatedShifts = new ArrayList(executionCourseFrom.getAssociatedShifts()); for (final Shift shift : associatedShifts) { List courseLoadsFrom = new ArrayList(shift.getCourseLoads()); for (Iterator iter = courseLoadsFrom.iterator(); iter.hasNext();) { CourseLoad courseLoadFrom = iter.next(); CourseLoad courseLoadTo = executionCourseTo.getCourseLoadByShiftType(courseLoadFrom.getType()); if (courseLoadTo == null) { courseLoadTo = new CourseLoad(executionCourseTo, courseLoadFrom.getType(), courseLoadFrom.getUnitQuantity(), courseLoadFrom.getTotalQuantity()); } iter.remove(); shift.removeCourseLoads(courseLoadFrom); shift.addCourseLoads(courseLoadTo); } } } @Linkare(author = "Paulo Zenida") private void copyLessonsInstances(ExecutionCourse executionCourseFrom, ExecutionCourse executionCourseTo) { final List associatedLessons = new ArrayList(executionCourseFrom .getAssociatedLessonInstances()); for (final LessonInstance lessonInstance : associatedLessons) { CourseLoad courseLoadFrom = lessonInstance.getCourseLoad(); CourseLoad courseLoadTo = executionCourseTo.getCourseLoadByShiftType(courseLoadFrom.getType()); if (courseLoadTo == null) { courseLoadTo = new CourseLoad(executionCourseTo, courseLoadFrom.getType(), courseLoadFrom.getUnitQuantity(), courseLoadFrom.getTotalQuantity()); } lessonInstance.setCourseLoad(courseLoadTo); } } @Linkare(author = "Paulo Zenida") private void copyAttends(final ExecutionCourse executionCourseFrom, final ExecutionCourse executionCourseTo) { while (!executionCourseFrom.getAttends().isEmpty()) { final Attends attends = executionCourseFrom.getAttends().get(0); final Attends otherAttends = executionCourseTo.getAttendsByStudent(attends.getRegistration()); if (otherAttends == null) { attends.setDisciplinaExecucao(executionCourseTo); } else { if (attends.hasEnrolment() && !otherAttends.hasEnrolment()) { otherAttends.setEnrolment(attends.getEnrolment()); } else if (otherAttends.hasEnrolment() && !attends.hasEnrolment()) { // do nothing. } else if (otherAttends.hasEnrolment() && attends.hasEnrolment()) { throw new DomainException("Unable to merge execution courses. Registration " + attends.getRegistration().getNumber() + " has an enrolment in both."); } for (; !attends.getAssociatedMarks().isEmpty(); otherAttends.addAssociatedMarks(attends.getAssociatedMarks().get( 0))) ; for (; !attends.getAllStudentGroups().isEmpty(); otherAttends.addStudentGroups(attends.getAllStudentGroups().get( 0))) ; attends.delete(); } } final Iterator associatedAttendsFromDestination = executionCourseTo.getAttendsIterator(); final Map alreadyAttendingDestination = new HashMap(); while (associatedAttendsFromDestination.hasNext()) { Attends attend = associatedAttendsFromDestination.next(); Registration registration = attend.getRegistration(); if (registration == null) { // !!! Yup it's true this actually happens!!! attend.delete(); } else { Integer number = registration.getNumber(); alreadyAttendingDestination.put(number.toString(), attend); } } final List associatedAttendsFromSource = new ArrayList(); associatedAttendsFromSource.addAll(executionCourseFrom.getAttends()); for (final Attends attend : associatedAttendsFromSource) { if (!alreadyAttendingDestination.containsKey(attend.getRegistration().getNumber().toString())) { attend.setDisciplinaExecucao(executionCourseTo); } } } @Linkare(author = "Paulo Zenida") private void copySite(final ExecutionCourse executionCourseFrom, final ExecutionCourse executionCourseTo) { final Site siteFrom = executionCourseFrom.getSite(); final Site siteTo = executionCourseTo.getSite(); if (siteFrom != null) { copyContents(executionCourseTo, siteTo, siteFrom.getOrderedDirectChildren()); siteFrom.delete(); } } @Linkare(author = "Paulo Zenida") private void copyContents(final ExecutionCourse executionCourseTo, final Container parentTo, final Collection nodes) { final Set transferedContents = new HashSet(); for (final Node node : nodes) { final Content content = node.getChild(); final ExplicitOrderNode explicitOrderNode = new ExplicitOrderNode(parentTo, content); if (node instanceof ExplicitOrderNode) { explicitOrderNode.setNodeOrder(((ExplicitOrderNode) node).getNodeOrder()); } explicitOrderNode.setVisible(node.getVisible()); node.delete(); changeGroups(executionCourseTo, content, transferedContents); } if (transferedContents.size() > 0) { final Set bccs = createListOfEmailAddresses(executionCourseTo); final StringBuilder message = new StringBuilder(); message.append(RenderUtils.getResourceString("GLOBAL_RESOURCES", "mergeExecutionCourses.email.body")); for (final Content content : transferedContents) { message.append("\n\t"); message.append(content.getName()); } message.append(RenderUtils.getResourceString("GLOBAL_RESOURCES", "mergeExecutionCourses.email.greetings")); SystemSender systemSender = RootDomainObject.getInstance().getSystemSender(); new Message(systemSender, systemSender.getConcreteReplyTos(), Collections.EMPTY_LIST, RenderUtils.getResourceString( "GLOBAL_RESOURCES", "mergeExecutionCourses.email.subject", new Object[] { executionCourseTo.getNome() }), message.toString(), bccs); } } @Linkare(author = "Paulo Zenida") private void changeGroups(final ExecutionCourse executionCourseTo, final Content content, final Set transferedContents) { if (content.getAvailabilityPolicy() != null) { content.getAvailabilityPolicy().delete(); final Group group = createExecutionCourseResponsibleTeachersGroup(executionCourseTo); if (group != null) { new GroupAvailability(content, group); } transferedContents.add(content); } if (content.isContainer()) { final Container container = (Container) content; for (final Node node : container.getOrderedDirectChildren()) { changeGroups(executionCourseTo, node.getChild(), transferedContents); } } if (content instanceof Attachment) { Attachment attachment = (Attachment) content; FileContent file = attachment.getFile(); if (file.getPermittedGroup() != null && !(file.getPermittedGroup() instanceof EveryoneGroup)) { file.setPermittedGroup(createExecutionCourseResponsibleTeachersGroup(executionCourseTo)); } } } @Linkare(author = "Paulo Zenida") private Set createListOfEmailAddresses(final ExecutionCourse executionCourseTo) { final Set emails = new HashSet(); for (final Professorship professorship : executionCourseTo.getProfessorshipsSet()) { emails.add(professorship.getPerson().getEmail()); } return emails; } @Linkare(author = "Paulo Zenida") private Group createExecutionCourseResponsibleTeachersGroup(final ExecutionCourse executionCourseTo) { final Set groups = new HashSet(); for (final Professorship professorship : executionCourseTo.getProfessorshipsSet()) { if (professorship.isResponsibleFor()) { groups.add(new PersonGroup(professorship.getPerson())); } } return groups.isEmpty() ? null : new GroupUnion(groups); } @Linkare(author = "Paulo Zenida") private void copyProfessorships(final ExecutionCourse executionCourseFrom, final ExecutionCourse executionCourseTo) { for (; !executionCourseFrom.getProfessorships().isEmpty();) { final Professorship professorship = executionCourseFrom.getProfessorships().get(0); final Professorship otherProfessorship = findProfessorShip(executionCourseTo, professorship.getTeacher()); if (otherProfessorship == null) { professorship.setExecutionCourse(executionCourseTo); } else { for (; !professorship.getAssociatedSummaries().isEmpty(); otherProfessorship.addAssociatedSummaries(professorship .getAssociatedSummaries().get(0))) ; for (; !professorship.getAssociatedShiftProfessorship().isEmpty(); otherProfessorship .addAssociatedShiftProfessorship(professorship.getAssociatedShiftProfessorship().get(0))) ; for (; !professorship.getSupportLessons().isEmpty(); otherProfessorship.addSupportLessons(professorship .getSupportLessons().get(0))) ; for (; !professorship.getDegreeTeachingServices().isEmpty(); otherProfessorship .addDegreeTeachingServices(professorship.getDegreeTeachingServices().get(0))) ; for (; !professorship.getTeacherMasterDegreeServices().isEmpty(); otherProfessorship .addTeacherMasterDegreeServices(professorship.getTeacherMasterDegreeServices().get(0))) ; professorship.delete(); } } } @Linkare(author = "Paulo Zenida") private Professorship findProfessorShip(final ExecutionCourse executionCourseTo, final Teacher teacher) { for (final Professorship professorship : executionCourseTo.getProfessorships()) { if (professorship.getTeacher() == teacher) { return professorship; } } return null; } @Linkare(author = "Paulo Zenida") private void copyForuns(final ExecutionCourse executionCourseFrom, final ExecutionCourse executionCourseTo) { if (!executionCourseTo.hasSite()) { throw new DomainException("Unable to copy foruns, destination doesn't have site"); } while (!executionCourseFrom.getForuns().isEmpty()) { ExecutionCourseForum sourceForum = executionCourseFrom.getForuns().get(0); MultiLanguageString forumName = sourceForum.getName(); ExecutionCourseForum targetForum = executionCourseTo.getForumByName(forumName); if (targetForum == null) { Node childNode = executionCourseFrom.getSite().getChildNode(sourceForum); childNode.setParent(executionCourseTo.getSite()); } else { copyForumSubscriptions(sourceForum, targetForum); copyThreads(sourceForum, targetForum); executionCourseFrom.getSite().removeForum(sourceForum); sourceForum.delete(); } } } @Linkare(author = "Paulo Zenida") private void copyForumSubscriptions(ExecutionCourseForum sourceForum, ExecutionCourseForum targetForum) { while (!sourceForum.getForumSubscriptions().isEmpty()) { ForumSubscription sourceForumSubscription = sourceForum.getForumSubscriptions().get(0); Person sourceForumSubscriber = sourceForumSubscription.getPerson(); ForumSubscription targetForumSubscription = targetForum.getPersonSubscription(sourceForumSubscriber); if (targetForumSubscription == null) { sourceForumSubscription.setForum(targetForum); } else { if (sourceForumSubscription.getReceivePostsByEmail() == true) { targetForumSubscription.setReceivePostsByEmail(true); } if (sourceForumSubscription.getFavorite() == true) { targetForumSubscription.setFavorite(true); } sourceForum.removeForumSubscriptions(sourceForumSubscription); sourceForumSubscription.delete(); } } } @Linkare(author = "Paulo Zenida") private void copyThreads(ExecutionCourseForum sourceForum, ExecutionCourseForum targetForum) { while (!sourceForum.getConversationThreads().isEmpty()) { ConversationThread sourceConversationThread = sourceForum.getConversationThreads().get(0); if (!targetForum.hasConversationThreadWithSubject(sourceConversationThread.getTitle())) { sourceConversationThread.setForum(targetForum); } else { ConversationThread targetConversionThread = targetForum.getConversationThreadBySubject(sourceConversationThread .getTitle()); for (Node child : sourceConversationThread.getChildren()) { child.setParent(targetConversionThread); } sourceForum.removeConversationThreads(sourceConversationThread); sourceConversationThread.delete(); } } } @Linkare(author = "Paulo Zenida") @Override public String getShortDescription() { return getExecutionPeriod().getShortDescription() + " - " + getNome(); } public List getAssociatedFinalEvaluationByEvaluationTypes() { final List result = new ArrayList(); for (final Evaluation evaluation : getAssociatedEvaluations()) { if (evaluation instanceof FinalEvaluationByEvaluationType) { result.add((FinalEvaluationByEvaluationType) evaluation); } } return result; } @Linkare(author = "Paulo Zenida") public boolean hasEvaluationByType(final EnrolmentEvaluationType enrolmentEvaluationType) { for (final FinalEvaluationByEvaluationType evaluation : getAssociatedFinalEvaluationByEvaluationTypes()) { if (evaluation.getEnrolmentEvaluationType() == enrolmentEvaluationType) { return true; } } return false; } }