package net.sourceforge.fenixedu.domain.curricularPeriod; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import com.linkare.commons.metainfo.Linkare; import net.sourceforge.fenixedu.dataTransferObject.CurricularPeriodInfoDTO; import net.sourceforge.fenixedu.domain.CurricularCourse; import net.sourceforge.fenixedu.domain.ExecutionSemester; import net.sourceforge.fenixedu.domain.RootDomainObject; import net.sourceforge.fenixedu.domain.degreeStructure.Context; import net.sourceforge.fenixedu.domain.degreeStructure.DegreeModule; import net.sourceforge.fenixedu.domain.exceptions.DomainException; import net.sourceforge.fenixedu.domain.time.calendarStructure.AcademicPeriod; import net.sourceforge.fenixedu.util.CurricularPeriodLabelFormatter; /** * * @author - Shezad Anavarali (shezad@ist.utl.pt) * * */ public class CurricularPeriod extends CurricularPeriod_Base implements Comparable { static { CurricularPeriodParentChilds.addListener(new CurricularPeriodParentChildsListener()); } public CurricularPeriod(AcademicPeriod academicPeriod) { super(); setRootDomainObject(RootDomainObject.getInstance()); setAcademicPeriod(academicPeriod); } public CurricularPeriod(AcademicPeriod academicPeriod, Integer order, CurricularPeriod parent) { this(academicPeriod); setChildOrder(order); setParent(parent); } public List getSortedChilds() { List sortedChilds = new ArrayList(); sortedChilds.addAll(getChilds()); Collections.sort(sortedChilds); return sortedChilds; } public CurricularPeriod getChildByOrder(Integer order) { for (CurricularPeriod curricularPeriod : getChilds()) { if (curricularPeriod.getChildOrder().equals(order)) { return curricularPeriod; } } return null; } private CurricularPeriod findChild(AcademicPeriod academicPeriod, Integer order) { for (CurricularPeriod curricularPeriod : getChilds()) { if (curricularPeriod.getChildOrder().equals(order) && curricularPeriod.getAcademicPeriod().equals(academicPeriod)) { return curricularPeriod; } } return null; } public CurricularPeriod getCurricularPeriod(CurricularPeriodInfoDTO... curricularPeriodsPaths) { validatePath(curricularPeriodsPaths); CurricularPeriod curricularPeriod = this; for (CurricularPeriodInfoDTO path : curricularPeriodsPaths) { curricularPeriod = (CurricularPeriod) curricularPeriod.findChild(path.getPeriodType(), path.getOrder()); if (curricularPeriod == null) { return null; } } return curricularPeriod; } public CurricularPeriod addCurricularPeriod(CurricularPeriodInfoDTO... curricularPeriodsPaths) { validatePath(curricularPeriodsPaths); CurricularPeriod curricularPeriod = null; CurricularPeriod curricularPeriodParent = this; for (CurricularPeriodInfoDTO path : curricularPeriodsPaths) { curricularPeriod = (CurricularPeriod) curricularPeriodParent.findChild(path.getPeriodType(), path.getOrder()); if (curricularPeriod == null) { curricularPeriod = new CurricularPeriod(path.getPeriodType(), path.getOrder(), curricularPeriodParent); } curricularPeriodParent = curricularPeriod; } return curricularPeriod; } public Integer getOrderByType(AcademicPeriod academicPeriod) { Integer resultOrder = null; if (this.getAcademicPeriod().equals(academicPeriod)) { resultOrder = this.getChildOrder(); } else if (this.getParent() != null && this.getParent().getAcademicPeriod().getWeight() > this.getAcademicPeriod().getWeight()) { resultOrder = ((CurricularPeriod) this.getParent()).getOrderByType(academicPeriod); } return resultOrder; } private void validatePath(CurricularPeriodInfoDTO... curricularPeriodsPaths) { Arrays.sort(curricularPeriodsPaths, new Comparator() { public int compare(CurricularPeriodInfoDTO c1, CurricularPeriodInfoDTO c2) { if (c1.getPeriodType().getWeight() > c2.getPeriodType().getWeight()) { return -1; } else if (c1.getPeriodType().getWeight() < c2.getPeriodType().getWeight()) { return 1; } throw new DomainException("error.pathShouldNotHaveSameTypePeriods"); } }); } @Linkare(author = "Paulo Zenida", comments = "Fixed delete method") public void delete() { getContexts().clear(); removeDegreeCurricularPlan(); while(!getChilds().isEmpty()) { getChilds().get(0).delete(); } removeRootDomainObject(); deleteDomainObject(); } public String getLabel() { return CurricularPeriodLabelFormatter.getLabel(this, false); } public String getFullLabel() { return CurricularPeriodLabelFormatter.getFullLabel(this, false); } public int compareTo(CurricularPeriod o) { return this.getFullWeight().compareTo(o.getFullWeight()); } private Float getWeight() { float periodTypeWeight = (this.getAcademicPeriod() == null) ? 0 : this.getAcademicPeriod().getWeight(); float periodOrder = (this.getChildOrder() == null) ? 0 : this.getChildOrder(); return periodTypeWeight * periodOrder; } private Float getFullWeight() { return this.getWeight() + this.collectParentsWeight(this); } private Float collectParentsWeight(CurricularPeriod period) { Float result = Float.valueOf(0); if (period.hasParent()) { result = period.getParent().getWeight() + collectParentsWeight(period.getParent()); } return result; } private static class CurricularPeriodParentChildsListener extends dml.runtime.RelationAdapter { @Override public void beforeAdd(CurricularPeriod parent, CurricularPeriod child) { if (parent == null) { return; } if (child.getAcademicPeriod().getWeight() >= parent.getAcademicPeriod().getWeight()) { throw new DomainException("error.childTypeGreaterThanParentType"); } float childsWeight = child.getAcademicPeriod().getWeight(); for (CurricularPeriod period : parent.getChilds()) { childsWeight += period.getAcademicPeriod().getWeight(); } if (childsWeight > parent.getAcademicPeriod().getWeight()) { throw new DomainException("error.childWeightOutOfLimit"); } // re-order childs Integer order = child.getChildOrder(); if (order == null) { child.setChildOrder(parent.getChildsCount() + 1); } else { if (parent.getChildByOrder(order) != null) { throw new DomainException("error.childAlreadyExists"); } } } } public Integer getParentOrder() { if (this.getParent() != null) { return this.getParent().getChildOrder(); } return null; } public CurricularPeriod getNext() { List brothers = this.getParent().getSortedChilds(); for (Iterator iterator = brothers.iterator(); iterator.hasNext();) { CurricularPeriod brother = iterator.next(); if (brother.getChildOrder().equals(this.getChildOrder()) && iterator.hasNext()) { return iterator.next(); } } return null; } public CurricularPeriod contains(AcademicPeriod academicPeriod, Integer order) { if (this.getAcademicPeriod().equals(academicPeriod) && this.getChildOrder().equals(order)) { return this; } for (CurricularPeriod curricularPeriod : getChilds()) { CurricularPeriod period = curricularPeriod.contains(academicPeriod, order); if (period != null) { return period; } } return null; } public boolean hasCurricularPeriod(AcademicPeriod academicPeriod, Integer order) { if (this.getAcademicPeriod().equals(academicPeriod) && this.getChildOrder().equals(order)) { return true; } if (getParent() != null) { return getParent().hasCurricularPeriod(academicPeriod, order); } else { return false; } } @Deprecated public Integer getOrder() { return super.getChildOrder(); } @Deprecated public void setOrder(Integer order) { super.setChildOrder(order); } @Linkare(author = "Paulo Zenida", comments = "Added the checking for the getParent() in the first if clause so that we don't end up with a NullPointerException when fetching the parent.") public int getAbsoluteOrderOfChild() { if (getChildOrder() == null || getParent() == null) { return 1; } else { final CurricularPeriod parentCurricularPeriod = getParent(); final int absoluteOrderOfParent = parentCurricularPeriod.getAbsoluteOrderOfChild(); final int numberOfBrothersAndSisters = parentCurricularPeriod.getChildsCount(); return (absoluteOrderOfParent - 1) * numberOfBrothersAndSisters + getChildOrder().intValue(); } } public List getContextsWithCurricularCourses() { return getContextsWithCurricularCourses(null); } public List getContextsWithCurricularCourses(final ExecutionSemester executionSemester) { return getChildContexts(CurricularCourse.class, executionSemester); } public List getChildContexts(final Class clazz, final ExecutionSemester executionSemester) { final List result = new ArrayList(); for (final Context context : super.getContextsSet()) { if ((clazz == null || clazz.isAssignableFrom(context.getChildDegreeModule().getClass())) && (executionSemester == null || context.isValid(executionSemester))) { result.add(context); } } return result; } public boolean hasChildOrder() { return getChildOrder() != null; } public boolean hasChildOrderValue(final Integer order) { return hasChildOrder() && getChildOrder().equals(order); } }