Subversion Repositories bacoAlunos

Rev

Rev 1554 | Rev 1622 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package pt.estgp.estgweb.domain;

import com.owlike.genson.Genson;
import com.owlike.genson.TransformationException;
import org.apache.log4j.Logger;
import pt.estgp.estgweb.Globals;
import pt.estgp.estgweb.domain.dao.DaoFactory;
import pt.estgp.estgweb.domain.enums.CourseUnitContentsGrants;
import pt.estgp.estgweb.domain.test.TestCourseUnit;
import pt.estgp.estgweb.domain.utils.SimpleClearanceRuledSupport;
import pt.utl.ist.berserk.logic.serviceManager.IServiceManager;
import pt.utl.ist.berserk.logic.serviceManager.ServiceManager;

import java.io.IOException;
import java.io.Serializable;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: Jorge Machado
 * Date: 7/Mai/2008
 * Time: 20:21:15
 * To change this template use File | Settings | File Templates.
 */

public class CourseUnitImpl extends CourseUnit implements ICanManage, ClearanceRuled
{

    private static final 1.5.0/docs/api/java/util/logging/Logger.html">Logger logger = 1.5.0/docs/api/java/util/logging/Logger.html">Logger.getLogger(CourseUnitImpl.class);

    CourseUnitContentsGrants courseUnitContentsGrants = null;

    public 1.5.0/docs/api/java/io/Serializable.html">Serializable getSerializable()
    {
        return getId();
    }


    public CourseUnitContentsGrants getCourseUnitContentsGrants() {
        if(courseUnitContentsGrants == null)
            courseUnitContentsGrants = CourseUnitContentsGrants.parse(super.getContentsGrants());
        return courseUnitContentsGrants;
    }

    public void setCourseUnitContentsGrants(CourseUnitContentsGrants courseUnitContentsGrants) {
        super.setContentsGrants(courseUnitContentsGrants.name());
        this.courseUnitContentsGrants = courseUnitContentsGrants;
    }

    public boolean isValid()
    {
        return true;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public boolean isOwnedBy(GenericUser u)
    {
        return isOwnedBy(u, false);
    }

    public boolean isOwnedBy(GenericUser u, boolean transaction)
    {
        return u != null && u instanceof TeacherImpl && ((TeacherImpl)u).hasCourseUnit(getId(),transaction);
    }

    /**
     * Not implemented can be variuous teachers
     * @return null
     * use isOwnedBy in this class
     */

    public GenericUser getOwner()
    {
        return null;
    }
    /**
     * Not implemented
     * @return
     */

    public List<String> getOwnerRoles()
    {
        return null;
    }

    /**
     * Not implemented
     * @return
     */

    public 1.5.0/docs/api/java/lang/String.html">String getChoosedOwnerRole()
    {
        return null;
    }

    public boolean isInternal()
    {
        return true;
    }

    public CourseUnitBlogImpl getUnitBlog()
    {
        if(getBlogs()!=null && getBlogs().size() > 0)
            return (CourseUnitBlogImpl) getBlogs().iterator().next();
        return null;
    }


    public boolean equalsSiges(5+0%2Fdocs%2Fapi+Object">Object anotherInstance,boolean turmasSeparadas)
    {
        if(anotherInstance instanceof CourseUnitImpl)
        {
            CourseUnitImpl anCourseUnit = (CourseUnitImpl) anotherInstance;
            if(turmasSeparadas)
            {
                boolean turmaVazia = getCdTurma() == null || getCdTurma().trim().length() == 0;
                boolean anotherTurmaVazia = anCourseUnit.getCdTurma() == null || anCourseUnit.getCdTurma().trim().length() == 0;
                boolean turmasIguais = (turmaVazia && anotherTurmaVazia) || (!turmaVazia && !anotherTurmaVazia && getCdTurma().equals(anCourseUnit.getCdTurma()));
                return equalsIgnoringTurma(anotherInstance)
                &&
                turmasIguais;
            }
            else
                return equalsIgnoringTurma(anotherInstance);
        }
        return false;

    }

    public boolean equalsIgnoringTurma(5+0%2Fdocs%2Fapi+Object">Object anotherInstance)
    {
        if(anotherInstance instanceof CourseUnitImpl)
        {
            CourseUnitImpl anCourseUnit = (CourseUnitImpl) anotherInstance;

            return anCourseUnit.getCode() != null && getCode() != null && getCode().equals(anCourseUnit.getCode()) &&
                    anCourseUnit.getCourseCode() != null && getCourseCode() != null && getCourseCode().equals(anCourseUnit.getCourseCode()) &&
                    anCourseUnit.getSemestre() != null && getSemestre() != null && getSemestre().equals(anCourseUnit.getSemestre()) &&
                    anCourseUnit.getImportYear() != null && getImportYear() != null && getImportYear().equals(anCourseUnit.getImportYear());
        }
        return false;

    }

    /**
     * Means that is teacher os responsable teacher or from course commission
     * Only works in open transaction
     *
     * Needs Course and Responsable Teacher loaded
     */

    public boolean isFromCourseUnitCommission(UserSession userSession)
    {
        return userSession.getUser()!= null &&
                (((UserImpl) userSession.getUser()).isTeacherOfCourseUnit(getId(), true)
                        || (getResponsableTeacher() != null && getResponsableTeacher().getId() == userSession.getUser().getId())
                        || ((CourseImpl)getCourse()).isFromCourseCommission(userSession)
                );
    }

    public boolean isFromCourseCommission(UserSession userSession)
    {
        return userSession.getUser()!= null &&
                userSession.getUser().hasRole(getCourse().getValidationRole());
    }


    public 1.5.0/docs/api/java/lang/String.html">String getSummariosPathIntranet()
    {
        return Globals.FTP_IONLINE_START_PATH + "/" + getPathIntranet() + "/" + Globals.INTRANET_DTP + "/" + Globals.INTRANET_DTP_Sumarios;
    }

    public 1.5.0/docs/api/java/lang/String.html">String getInqueritosPedagogicosPathIntranet()
    {
        return Globals.FTP_IONLINE_START_PATH + getPathIntranet() + "/" + Globals.INTRANET_DTP + "/" + Globals.INTRANET_DTP_InqueritoPedagogico;
    }


    public 1.5.0/docs/api/java/lang/String.html">String getSummariosPathFileIntranet()
    {
        return getSummariosPathIntranet() + "/" + getSummariosFileNameIntranet();
    }

    public 1.5.0/docs/api/java/lang/String.html">String getSummariosFileNameIntranet(){
        return getCode() + "_" + getNormalizedName() + "_sumarios.pdf";
    }


    public 1.5.0/docs/api/java/lang/String.html">String getSigesUniqueIdentifiers()
    {
        return "SIGES:" + getCode() + ", COURSE: " + getCourseCode() +
                ", " + getSemestre() + " of " + getImportYear() + " - " + getName() + " Turma - " + getCdTurma();
    }

    public int studentsSize()
    {
        if(getStudents() !=null)
            return getStudents().size();
        return 0;
    }

    public int studentsTurmaSize()
    {
        int countTotalStudentsTurmas = 0;
        if(getTurmas() == null)
            return 0;
        for(CourseUnitTurma turma: getTurmas())
        {
            if(turma.getStudents() != null)
                countTotalStudentsTurmas+=turma.getStudents().size();
        }
        return countTotalStudentsTurmas;
    }


    public boolean hasStudent(long studentId, boolean transaction)
    {
        Set<StudentImpl> students;
        if(transaction)
            students = getStudents();
        else
        {
            IServiceManager sm;
            try {
                sm = ServiceManager.getInstance();
                1.5.0/docs/api/java/lang/String.html">String[] names = new 1.5.0/docs/api/java/lang/String.html">String[]{"serializable"};
                5+0%2Fdocs%2Fapi+Object">Object[] args = new 5+0%2Fdocs%2Fapi+Object">Object[]{getId()};
                students = (Set<StudentImpl>) sm.execute(null, "LoadCourseUnitStudents", args, names);
            } catch (1.5.0/docs/api/java/lang/Throwable.html">Throwable e) {
                logger.error(e,e);
                return false;
            }
        }
        if(students == null)
            return false;
        for(Student s: students)
        {
            if(s.getId() == studentId)
                return true;
        }
        return false;
    }

    public boolean hasTeacher(long teacherId, boolean transaction)
    {
        Set<TeacherImpl> teachers;
        if(transaction)
            teachers = getTeachers();
        else
        {
            IServiceManager sm;
            try {
                sm = ServiceManager.getInstance();
                1.5.0/docs/api/java/lang/String.html">String[] names = new 1.5.0/docs/api/java/lang/String.html">String[]{"serializable"};
                5+0%2Fdocs%2Fapi+Object">Object[] args = new 5+0%2Fdocs%2Fapi+Object">Object[]{getId()};
                teachers = (Set<TeacherImpl>) sm.execute(null, "LoadCourseUnitTeachers", args, names);
            } catch (1.5.0/docs/api/java/lang/Throwable.html">Throwable e) {
                logger.error(e,e);
                return false;
            }
        }
        if(teachers == null)
            return false;
        for(Teacher t: teachers)
        {
            if(t.getId() == teacherId)
                return true;
        }
        return false;
    }

    public boolean isResponsibleTeacher(long teacherId, boolean transaction)
    {
        Teacher t;
        if(transaction)
            t = getResponsableTeacher();
        else
        {
            IServiceManager sm;
            try {
                sm = ServiceManager.getInstance();
                1.5.0/docs/api/java/lang/String.html">String[] names = new 1.5.0/docs/api/java/lang/String.html">String[]{"serializable"};
                5+0%2Fdocs%2Fapi+Object">Object[] args = new 5+0%2Fdocs%2Fapi+Object">Object[]{getId()};
                t = (Teacher) sm.execute(null, "LoadCourseUnitResponsibleTeacher", args, names);
            } catch (1.5.0/docs/api/java/lang/Throwable.html">Throwable e) {
                logger.error(e,e);
                return false;
            }
        }
        if(t == null)
            return false;
        if(t.getId() == teacherId)
            return true;
        return false;
    }

    SimpleClearanceRuledSupport clearanceRuledSupport = null;

    public SimpleClearanceRuledSupport getClearanceRuledSupport() {
        return clearanceRuledSupport;
    }

    public void setClearanceRuledSupport(SimpleClearanceRuledSupport clearanceRuledSupport) {
        this.clearanceRuledSupport = clearanceRuledSupport;
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public boolean isClearanceInitialized(UserSessionImpl u) {
        return clearanceRuledSupport == null ? false :
         clearanceRuledSupport.isClearanceInitialized(u);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public boolean isClear(UserSessionImpl u, 1.5.0/docs/api/java/lang/String.html">String OP) {

        if(clearanceRuledSupport == null) return false;
        if(OP.startsWith("EVALUATION") && !OP.startsWith("EVALUATION_INFO")
                && clearanceRuledSupport.isClear(u,CourseUnitClearancesOperation.EVALUATION_ALL.name()))
            return true;
        return clearanceRuledSupport.isClear(u, OP);
    }

    @1.5.0/docs/api/java/lang/Override.html">Override
    public void initClearances(UserSessionImpl usession,boolean force)
    {
        CourseUnitImpl c = this;
        1.5.0/docs/api/java/lang/String.html">String activeYear = DaoFactory.getConfigurationDaoImpl().getCourseUnitEvaluationActiveYear();
        List<String> activeDegrees = DaoFactory.getConfigurationDaoImpl().getCourseUnitEvaluationActiveDegrees();
        List<Long> activeCourseIds = DaoFactory.getConfigurationDaoImpl().getCourseUnitEvaluationActiveCourseIds();

        boolean isActiveYear = activeYear != null && c.getImportYear().equals(activeYear);
        boolean isActiveDegree = activeDegrees!=null && activeDegrees.contains(c.getCourse().getDegree());
        boolean isActiveCourseId = activeCourseIds!=null && activeCourseIds.contains(c.getCourse().getId());

        boolean activePeriod = (isActiveYear && (isActiveCourseId || isActiveDegree));
        boolean active = activePeriod || c.isEvaluationOpenByAdmin();

        boolean isComplete = c.getCourseUnitEvaluation() != null && c.getCourseUnitEvaluation().isTeacherComplete() && !c.getCourseUnitEvaluation().isClosed();
        boolean isClosed = c.getCourseUnitEvaluation() != null && c.getCourseUnitEvaluation().isClosed();
        boolean isEdit = !isClosed && !isComplete;


        SimpleClearanceRuledSupport s = new SimpleClearanceRuledSupport();
        s.setDirty();

        if(isEdit)
            s.addClearance(CourseUnitClearancesOperation.EVALUATION_INFO_STATE_EDIT.name(),usession);
        else if(isComplete)
            s.addClearance(CourseUnitClearancesOperation.EVALUATION_INFO_STATE_COMPLETE.name(),usession);
        else if(isClosed)
            s.addClearance(CourseUnitClearancesOperation.EVALUATION_INFO_STATE_CLOSED.name(),usession);

        if(activePeriod)
        {
            s.addClearance(CourseUnitClearancesOperation.EVALUATION_INFO_ACTIVE.name(),usession);
            s.addClearance(CourseUnitClearancesOperation.EVALUATION_INFO_ACTIVE_REGULAR_PERIOD.name(),usession);
        }
        if(c.isEvaluationOpenByAdmin())
        {
            s.addClearance(CourseUnitClearancesOperation.EVALUATION_INFO_ACTIVE.name(),usession);
            s.addClearance(CourseUnitClearancesOperation.EVALUATION_INFO_ACTIVE_SPECIAL_ADMIN.name(),usession);
        }


        if(usession.getUser() != null && (usession.getUser().isSuperuserOrAdmin() || usession.getUser().hasRole(Globals.SERVICES_PROGRAMS_ROLE)))
        {
            s.addClearance(CourseUnitClearancesOperation.STATISTICS_CAN_VIEW.name(),usession);
            s.addClearance(CourseUnitClearancesOperation.EVALUATION_ALL.name(),usession);
            s.addClearance(CourseUnitClearancesOperation.PROGRAM_EDIT_PROGRAM.name(), usession);
            s.addClearance(CourseUnitClearancesOperation.PROGRAM_CAN_VALIDATE.name(),usession);
            s.addClearance(CourseUnitClearancesOperation.PROGRAM_TEACHER_PART.name(),usession);
            s.addClearance(CourseUnitClearancesOperation.PROGRAM_COORDINATOR_PART.name(),usession);
        }

        if(usession.getUser() != null && usession.getUser() instanceof Teacher)
        {
            Teacher t = ((Teacher)(usession.getUser()));
            boolean teacher = ((Teacher)(usession.getUser())).isTeacherOfCourseUnit(c.getId(),true);
            boolean responsable = c.getResponsableTeacher()!=null && usession.getUser().getId() == c.getResponsableTeacher().getId();
            boolean isCoordinator = ((CourseImpl) DaoFactory.getCourseDaoImpl().narrow(c.getCourse())).isFromCourseCommission(t);

            if(teacher)
            {
                s.addClearance(CourseUnitClearancesOperation.EVALUATION_INFO_USER_TEACHER.name(), usession);
            }
            if(responsable)
            {
                s.addClearance(CourseUnitClearancesOperation.EVALUATION_INFO_USER_RESP_TEACHER.name(), usession);
            }
            if(teacher || responsable)
            {
                s.addClearance(CourseUnitClearancesOperation.STATISTICS_CAN_VIEW.name(),usession);
                //s.addClearance(CourseUnitClearancesOperation.EVALUATION_INFO_USER_TEACHER.name(), usession);
                s.addClearance(CourseUnitClearancesOperation.EVALUATION_EDITION.name(),usession);
                if(active && isEdit)
                {
                    s.addClearance(CourseUnitClearancesOperation.EVALUATION_EDITSAVE.name(),usession);
                    s.addClearance(CourseUnitClearancesOperation.EVALUATION_PERSIST_TEACHER_PART.name(),usession);
                    s.addClearance(CourseUnitClearancesOperation.EVALUATION_TRANSITATE_TO_COMPLETE.name(),usession);
                }
            }

            if(isCoordinator)
            {
                s.addClearance(CourseUnitClearancesOperation.STATISTICS_CAN_VIEW.name(),usession);
                s.addClearance(CourseUnitClearancesOperation.PROGRAM_CAN_VALIDATE.name(),usession);
                s.addClearance(CourseUnitClearancesOperation.EVALUATION_INFO_USER_COMMISSION.name(), usession);
                s.addClearance(CourseUnitClearancesOperation.EVALUATION_EDITION.name(), usession);
                if(active && isEdit)
                {
                    s.addClearance(CourseUnitClearancesOperation.EVALUATION_EDITSAVE.name(),usession);
                    s.addClearance(CourseUnitClearancesOperation.EVALUATION_PERSIST_TEACHER_PART.name(),usession);
                    s.addClearance(CourseUnitClearancesOperation.EVALUATION_PERSIST_COMISSION_PART.name(),usession);
                    s.addClearance(CourseUnitClearancesOperation.EVALUATION_TRANSITATE_TO_COMPLETE.name(),usession);
                    s.addClearance(CourseUnitClearancesOperation.EVALUATION_TRANSITATE_TO_CLOSE.name(),usession);
                }
                else if(active && isComplete)
                {
                    s.addClearance(CourseUnitClearancesOperation.EVALUATION_EDITSAVE.name(),usession);
                    s.addClearance(CourseUnitClearancesOperation.EVALUATION_PERSIST_TEACHER_PART.name(),usession);
                    s.addClearance(CourseUnitClearancesOperation.EVALUATION_PERSIST_COMISSION_PART.name(),usession);
                    s.addClearance(CourseUnitClearancesOperation.EVALUATION_TRANSITATE_TO_CLOSE.name(),usession);
                    s.addClearance(CourseUnitClearancesOperation.EVALUATION_TRANSITATE_TO_EDIT.name(),usession);
                }
                else if(active && isClosed)
                {
                    s.addClearance(CourseUnitClearancesOperation.EVALUATION_TRANSITATE_TO_EDIT.name(),usession);
                }
            }


            if(!c.isValidProgram())
            {
                if(teacher)
                {
                    s.addClearance(CourseUnitClearancesOperation.PROGRAM_EDIT_PROGRAM.name(), usession);
                    s.addClearance(CourseUnitClearancesOperation.PROGRAM_TEACHER_PART.name(), usession);
                }
                if(isCoordinator)
                {
                    s.addClearance(CourseUnitClearancesOperation.PROGRAM_EDIT_PROGRAM.name(), usession);
                    s.addClearance(CourseUnitClearancesOperation.PROGRAM_TEACHER_PART.name(), usession);
                    s.addClearance(CourseUnitClearancesOperation.PROGRAM_COORDINATOR_PART.name(), usession);
                }
            }
            else
            {
                s.addClearance(CourseUnitClearancesOperation.PROGRAM_INFO_VALID_NOT_ACTIVE.name(), usession);
            }

        }

        c.setClearanceRuledSupport(s);
    }

    public static enum CourseUnitClearancesOperation
    {
        EVALUATION_ALL, //SPECIAL OPERATION FOR DENY AND PERMIT REPLACE FULL CONTROL

        //COURSE UNIT EVALUATION
        EVALUATION_PERSIST_TEACHER_PART, //SERVICE PERSIST THIS PART
        EVALUATION_PERSIST_COMISSION_PART, //SERVICE PERSIST THIS PART

        EVALUATION_EDITION, //CAN SEE EDITION SCREEN
        EVALUATION_EDITSAVE, //CAN PRESS SAVE
        EVALUATION_TRANSITATE_TO_COMPLETE, //CAN_TRANSITATE
        EVALUATION_TRANSITATE_TO_CLOSE, //CAN CLOSE
        EVALUATION_TRANSITATE_TO_EDIT, //CAN REVERT

        EVALUATION_INFO_ACTIVE, //INFO CLEARANCE WHEN ACTIVE
        EVALUATION_INFO_ACTIVE_SPECIAL_ADMIN, //INFO CLEARANCE REASON OF BEING ACTIVE
        EVALUATION_INFO_ACTIVE_REGULAR_PERIOD, //INFO CLEARANCE REASON OF BEING ACTIVE

        EVALUATION_INFO_STATE_EDIT, //INFO CLEARANCE
        EVALUATION_INFO_STATE_COMPLETE, //INFO CLEARANCE
        EVALUATION_INFO_STATE_CLOSED, //INFO CLEARANCE

        EVALUATION_INFO_USER_TEACHER, //INFO CLEARANCE
        EVALUATION_INFO_USER_RESP_TEACHER, //INFO CLEARANCE
        EVALUATION_INFO_USER_COMMISSION, //INFO CLEARANCE


        PROGRAM_EDIT_PROGRAM,
        PROGRAM_COORDINATOR_PART,
        PROGRAM_TEACHER_PART,

        PROGRAM_CAN_VALIDATE,
        PROGRAM_INFO_VALID_NOT_ACTIVE,

        STATISTICS_CAN_VIEW,


        ;

        public static CourseUnitClearancesOperation parse(1.5.0/docs/api/java/lang/String.html">String clearance)
        {
            if(clearance == null)
                return null;
            for(CourseUnitClearancesOperation op: CourseUnitClearancesOperation.values())
            {
                if(op.name().equals(clearance))
                    return op;
            }
            return null;
        }
    }


    public Tipologias getTipologiasClass() throws 1.5.0/docs/api/java/io/IOException.html">IOException, TransformationException
    {
        return Tipologias.deserialize(getTipologias());
    }

    public void setTipologiasClass(Tipologias tipologias) throws 1.5.0/docs/api/java/io/IOException.html">IOException, TransformationException
    {
        if(tipologias != null)
            setTipologias(tipologias.serialize());
    }

    public static class TipologiaLoadExeption extends 1.5.0/docs/api/java/lang/Exception.html">Exception
    {
        boolean teacherFail = false;
        boolean turmaFail = false;

        public TipologiaLoadExeption(boolean teacherFail, boolean turmaFail) {
            this.teacherFail = teacherFail;
            this.turmaFail = turmaFail;
        }

        public boolean isTeacherFail() {
            return teacherFail;
        }

        public boolean isTurmaFail() {
            return turmaFail;
        }

        @1.5.0/docs/api/java/lang/Override.html">Override
        public 1.5.0/docs/api/java/lang/String.html">String getMessage() {
            return "Professor: " + (teacherFail? "Falhou" : "OK") + " Turma: " + (turmaFail? "Falhou" : "OK");
        }
    }
    /**
     *
     * @param myTipo
     * @return
     */

    public TipologiaPersistent loadPersistent(Tipologia myTipo) throws TipologiaLoadExeption
    {
        TipologiaPersistent tipologiaPersistent = new TipologiaPersistent();
        tipologiaPersistent.setHorRef(myTipo.isHorRef());
        tipologiaPersistent.setExtra(myTipo.isExtra());
        tipologiaPersistent.setTeacher(DaoFactory.getTeacherDaoImpl().loadBySigesCode(1.5.0/docs/api/java/lang/Integer.html">Integer.parseInt(myTipo.getCdDocente())));
        tipologiaPersistent.setCdTipologia(myTipo.getCdTipologia());
        tipologiaPersistent.setOcorrencias(myTipo.getOcorrencias());
        tipologiaPersistent.setMarkWarning(myTipo.isMarkWarning());
        tipologiaPersistent.setUse(myTipo.isUse());

        tipologiaPersistent.setCourseUnitTurma(findTurma(myTipo.getCdTurma()));
        if(tipologiaPersistent.getCourseUnitTurma() == null || tipologiaPersistent.getTeacher() == null)
        {
            logger.error("Turma ou professor nao encontrados enquanto fazia uma tipologia persistente: turma:" + myTipo.getCdTurma() + " teacher code: " + myTipo.getCdDocente());
            throw new TipologiaLoadExeption(tipologiaPersistent.getTeacher() == null,tipologiaPersistent.getCourseUnitTurma() == null);
        }
        return tipologiaPersistent;
    }

    public CourseUnitTurma findTurma(1.5.0/docs/api/java/lang/String.html">String turma)
    {
        if(getTurmas() == null)
            return null;
        for(CourseUnitTurma t: getTurmas())
        {
            if(t.getTurma().equals(turma))
                return t;
        }
        return null;
    }


    public static class TipologiaPersistent
    {
        private Teacher teacher;
        private CourseUnitTurma courseUnitTurma;
        private 1.5.0/docs/api/java/lang/String.html">String cdTipologia;
        private 1.5.0/docs/api/java/lang/Integer.html">Integer ocorrencias = 0;
        protected boolean extra;
        protected boolean horRef;
        protected boolean use;   //campo auxiliar para marcar se vai ser ou não usada  nas afetacoes especificas
        //por omissão apenas as que têm sumários
        protected boolean markWarning; //camp

        public boolean isUse() {
            return use;
        }

        public void setUse(boolean use) {
            this.use = use;
        }

        public boolean isMarkWarning() {
            return markWarning;
        }

        public void setMarkWarning(boolean markWarning) {
            this.markWarning = markWarning;
        }

        public boolean isExtra() {
            return extra;
        }

        public boolean isHorRef() {
            return horRef;
        }

        public boolean isSumario() {
            return ocorrencias != null && ocorrencias > 0;
        }

        public void setExtra(boolean extra) {
            this.extra = extra;
        }

        public void setHorRef(boolean horRef) {
            this.horRef = horRef;
        }

        public Teacher getTeacher() {
            return teacher;
        }

        public void setTeacher(Teacher teacher) {
            this.teacher = teacher;
        }

        public CourseUnitTurma getCourseUnitTurma() {
            return courseUnitTurma;
        }

        public void setCourseUnitTurma(CourseUnitTurma courseUnitTurma) {
            this.courseUnitTurma = courseUnitTurma;
        }

        public 1.5.0/docs/api/java/lang/String.html">String getCdTipologia() {
            return cdTipologia;
        }

        public void setCdTipologia(1.5.0/docs/api/java/lang/String.html">String cdTipologia) {
            this.cdTipologia = cdTipologia;
        }

        public 1.5.0/docs/api/java/lang/Integer.html">Integer getOcorrencias() {
            return ocorrencias == null ? 0:ocorrencias;
        }

        public void setOcorrencias(1.5.0/docs/api/java/lang/Integer.html">Integer ocorrencias) {
            this.ocorrencias = ocorrencias;
        }
    }
    /**
     * Os codigos de tipologia devem ser limitados a T TP OT etc
     */

    public static class Tipologia
    {
        protected 1.5.0/docs/api/java/lang/String.html">String cdDocente;
        protected 1.5.0/docs/api/java/lang/String.html">String cdTurma;
        protected 1.5.0/docs/api/java/lang/String.html">String cdTipologia;
        protected 1.5.0/docs/api/java/lang/String.html">String dsTipologia;
        protected 1.5.0/docs/api/java/lang/Integer.html">Integer ocorrencias = 0; // apenas faz sentido nos sumarios. no horario ref nao.

        protected boolean use;   //campo auxiliar para marcar se vai ser ou não usada  nas afetacoes especificas
                                //por omissão apenas as que têm sumários
        protected boolean markWarning; //campo auxiliar para marcar se vai ser ou não usada  nas afetacoes especificas

        protected boolean extra;
        protected boolean horRef;
        protected boolean tdocturma = false;

        public boolean isTdocturma() {
            return tdocturma;
        }

        public void setTdocturma(boolean tdocturma) {
            this.tdocturma = tdocturma;
        }

        public boolean isUse() {
            return use;
        }

        public void setUse(boolean use) {
            this.use = use;
        }

        public boolean isMarkWarning() {
            return markWarning;
        }

        public void setMarkWarning(boolean markWarning) {
            this.markWarning = markWarning;
        }

        public 1.5.0/docs/api/java/lang/Integer.html">Integer getOcorrencias() {
            return ocorrencias == null ? 0:ocorrencias;
        }

        public boolean hasOcorrencias() {
            return ocorrencias != null && ocorrencias > 0;
        }

        public void setOcorrencias(1.5.0/docs/api/java/lang/Integer.html">Integer ocorrencias) {
            this.ocorrencias = ocorrencias;
        }

        public 1.5.0/docs/api/java/lang/String.html">String getCdDocente() {
            return cdDocente;
        }

        public void setCdDocente(1.5.0/docs/api/java/lang/String.html">String cdDocente) {
            this.cdDocente = cdDocente;
        }

        public 1.5.0/docs/api/java/lang/String.html">String getCdTurma() {
            return cdTurma;
        }

        public void setCdTurma(1.5.0/docs/api/java/lang/String.html">String cdTurma) {
            this.cdTurma = cdTurma;
        }

        public 1.5.0/docs/api/java/lang/String.html">String getCdTipologia() {
            return cdTipologia;
        }

        public void setCdTipologia(1.5.0/docs/api/java/lang/String.html">String cdTipologia) {
            this.cdTipologia = cdTipologia;
        }

        public 1.5.0/docs/api/java/lang/String.html">String getDsTipologia() {
            return dsTipologia;
        }

        public void setDsTipologia(1.5.0/docs/api/java/lang/String.html">String dsTipologia) {
            this.dsTipologia = dsTipologia;
        }

        public boolean isExtra() {
            return extra;
        }

        public boolean isSumario() {
            return ocorrencias != null && ocorrencias > 0;
        }

        public boolean isHorRef() {
            return horRef;
        }



        @1.5.0/docs/api/java/lang/Override.html">Override
        public boolean equals(5+0%2Fdocs%2Fapi+Object">Object o)
        {
            return o instanceof Tipologia &&
                    ((((Tipologia)o).getCdTurma() == null && getCdTurma() == null)
                            ||
                     (((Tipologia)o).getCdTurma().equals(getCdTurma())))
                    &&

                    (
                     (((Tipologia)o).getCdDocente() == null && getCdDocente() == null)
                            ||
                     (((Tipologia)o).getCdDocente().equals(getCdDocente())))
                    &&

                    (
                     (((Tipologia)o).getCdTipologia() == null && getCdTipologia() == null)
                                    ||
                     (((Tipologia)o).getCdTipologia().equals(getCdTipologia())));
        }

        public boolean equalsIncDsFields(5+0%2Fdocs%2Fapi+Object">Object o)
        {
            return o instanceof Tipologia &&
                    equals(o)
                    &&
                    (
                            (((Tipologia)o).getDsTipologia() == null && getDsTipologia() == null)
                                    ||
                                    (((Tipologia)o).getDsTipologia().equals(getDsTipologia())))
                    &&

                    (
                            (((Tipologia)o).getOcorrencias() == null && getOcorrencias() == null)
                                    ||
                                    (((Tipologia)o).getOcorrencias().equals(getOcorrencias())))
                    ;
        }
    }

    public static class MergedTipologias
    {
        ArrayList<Tipologia> tipologiasWithMarkedAndUsed = new ArrayList<Tipologia>();

        public ArrayList<Tipologia> getTipologiasWithMarkedAndUsed() {
            return tipologiasWithMarkedAndUsed;
        }

        public void setTipologiasWithMarkedAndUsed(ArrayList<Tipologia> tipologiasWithMarkedAndUsed) {
            this.tipologiasWithMarkedAndUsed = tipologiasWithMarkedAndUsed;
        }
    }
    public static class Tipologias
    {
        ArrayList<Tipologia> tipologiasHorarioReferencia = new ArrayList<Tipologia>();
        ArrayList<Tipologia> tipologiasSumarios = new ArrayList<Tipologia>();
        ArrayList<Tipologia> tipologiasExtraAdicionadas = new ArrayList<Tipologia>();
        ArrayList<Tipologia> tipologiasUsadas = new ArrayList<Tipologia>();
        ArrayList<Tipologia> tipologiasMarcadas = new ArrayList<Tipologia>();
        ArrayList<Tipologia> tipologiasTdocTurma = new ArrayList<Tipologia>();

        public ArrayList<Tipologia> getTipologiasTdocTurma() {
            return tipologiasTdocTurma == null ? new ArrayList<Tipologia>() : tipologiasTdocTurma;
        }

        public void setTipologiasTdocTurma(ArrayList<Tipologia> tipologiasTdocTurma) { this.tipologiasTdocTurma = tipologiasTdocTurma; }

        public ArrayList<Tipologia> getTipologiasHorarioReferencia() {

            return tipologiasHorarioReferencia == null ? new ArrayList<Tipologia>() : tipologiasHorarioReferencia;

        }

        public void setTipologiasHorarioReferencia(ArrayList<Tipologia> tipologiasHorarioReferencia) {
            this.tipologiasHorarioReferencia = tipologiasHorarioReferencia;
        }

        public ArrayList<Tipologia> getTipologiasSumarios() {
            return tipologiasSumarios == null ? new ArrayList<Tipologia>() : tipologiasSumarios;
        }

        public void setTipologiasSumarios(ArrayList<Tipologia> tipologiasSumarios) {
            this.tipologiasSumarios = tipologiasSumarios;
        }

        public ArrayList<Tipologia> getTipologiasExtraAdicionadas() {
            return tipologiasExtraAdicionadas == null ? new ArrayList<Tipologia>() : tipologiasExtraAdicionadas;
        }

        public void setTipologiasExtraAdicionadas(ArrayList<Tipologia> tipologiasExtraAdicionadas) {
            this.tipologiasExtraAdicionadas = tipologiasExtraAdicionadas;
        }

        public ArrayList<Tipologia> getTipologiasUsadas() {
            return tipologiasUsadas == null ? new ArrayList<Tipologia>() : tipologiasUsadas;
        }

        public void setTipologiasUsadas(ArrayList<Tipologia> tipologiasUsadas) { this.tipologiasUsadas = tipologiasUsadas; }

        public ArrayList<Tipologia> getTipologiasMarcadas() {
            return tipologiasMarcadas == null ? new ArrayList<Tipologia>() : tipologiasMarcadas;
        }

        public void setTipologiasMarcadas(ArrayList<Tipologia> tipologiasMarcadas) { this.tipologiasMarcadas = tipologiasMarcadas; }

        private static Genson getGenson(){
            Genson genson = new Genson.Builder()
                    .exclude(5+0%2Fdocs%2Fapi+Object">Object.class)
                    .include("tipologiasExtraAdicionadas", Tipologias.class)
                    .include("tipologiasSumarios", Tipologias.class)
                    .include("tipologiasHorarioReferencia", Tipologias.class)
                    .include("tipologiasUsadas", Tipologias.class)
                    .include("tipologiasMarcadas", Tipologias.class)
                    .include("tipologiasTdocTurma", Tipologias.class)
                    .include("cdTipologia", Tipologia.class)
                    .include("cdDocente", Tipologia.class)
                    .include("cdTurma", Tipologia.class)
                    .include("dsTipologia",Tipologia.class)
                    .include("ocorrencias", Tipologia.class)
                    .include("tdocturma", Tipologia.class)
                    .create();
            return genson;
        }

        private static Genson getGensonMergedTipologiasComplete(){
            Genson genson = new Genson.Builder()
                    .exclude(5+0%2Fdocs%2Fapi+Object">Object.class)

                    .include("tipologiasWithMarkedAndUsed", MergedTipologias.class)
                    .include("cdTipologia", Tipologia.class)
                    .include("cdDocente", Tipologia.class)
                    .include("cdTurma", Tipologia.class)
                    .include("dsTipologia",Tipologia.class)
                    .include("ocorrencias", Tipologia.class)
                    .include("horRef", Tipologia.class)
                    .include("extra", Tipologia.class)
                    .include("use", Tipologia.class)
                    .include("tdocturma", Tipologia.class)
                    .include("markWarning", Tipologia.class)
                    .create();
            return genson;
        }

        public 1.5.0/docs/api/java/lang/String.html">String serialize() throws 1.5.0/docs/api/java/io/IOException.html">IOException, TransformationException
        {
            Genson genson = getGenson();
            try {
                return genson.serialize(this);
            } catch (TransformationException e) {
                throw e;
            } catch (1.5.0/docs/api/java/io/IOException.html">IOException e) {
                throw e;
            }
        }
        public static Tipologias deserialize(1.5.0/docs/api/java/lang/String.html">String serial) throws 1.5.0/docs/api/java/io/IOException.html">IOException, TransformationException
        {
            if(serial == null)
                return new Tipologias();
            try {
                return getGenson().deserialize(serial, Tipologias.class);
            } catch (TransformationException e) {
                throw e;
            } catch (1.5.0/docs/api/java/io/IOException.html">IOException e) {
                throw e;
            }
        }

        public static void main(1.5.0/docs/api/java/lang/String.html">String [] args)
        {
            new TestCourseUnit().testTipologias();
        }

        public static 1.5.0/docs/api/java/lang/String.html">String serializeMergedList(ArrayList<Tipologia> tipologias) throws 1.5.0/docs/api/java/io/IOException.html">IOException, TransformationException
        {
            MergedTipologias mergedTipologias = new MergedTipologias();
            if(tipologias != null)
            {
                mergedTipologias.setTipologiasWithMarkedAndUsed(tipologias);
            }
            Genson genson = getGensonMergedTipologiasComplete();
            try {
                return genson.serialize(mergedTipologias);
            } catch (TransformationException e) {
                throw e;
            } catch (1.5.0/docs/api/java/io/IOException.html">IOException e) {
                throw e;
            }
        }
        public static ArrayList<Tipologia> deserializeMergedTipologias(1.5.0/docs/api/java/lang/String.html">String serial) throws 1.5.0/docs/api/java/io/IOException.html">IOException, TransformationException
        {
            if(serial == null)
                return new ArrayList<Tipologia>();
            try {
                MergedTipologias mergedTipologias = getGensonMergedTipologiasComplete().deserialize(serial, MergedTipologias.class);
                if(mergedTipologias.getTipologiasWithMarkedAndUsed() == null)
                    return new ArrayList<Tipologia>();
                return mergedTipologias.getTipologiasWithMarkedAndUsed();
            } catch (TransformationException e) {
                throw e;
            } catch (1.5.0/docs/api/java/io/IOException.html">IOException e) {
                throw e;
            }
        }
        public 1.5.0/docs/api/java/lang/String.html">String obtainMergeTipologiasSerialized() throws 1.5.0/docs/api/java/io/IOException.html">IOException, TransformationException
        {
            return serializeMergedList(obtainMergeTipologias());
        }


        /**
         * Junta todas as tipologias obtidas dos sumarios, horario(ref+trab) + extra
         * e coloca todas numa lista de unicas
         * Marca-as com isHorario, isSumario, isExtra
         * @return
         */


        public ArrayList<Tipologia> obtainMergeTipologias()
        {
            ArrayList<Tipologia> merge = new ArrayList<Tipologia>();
            if(getTipologiasSumarios() != null)
                merge.addAll(getTipologiasSumarios());

            if(getTipologiasHorarioReferencia() != null)
                for(Tipologia tipo: getTipologiasHorarioReferencia())
                {
                    if(!merge.contains(tipo))
                    {
                        merge.add(tipo);
                    }
                }
            if(getTipologiasExtraAdicionadas() != null)
                for(Tipologia tipo: getTipologiasExtraAdicionadas())
                {
                    if(!merge.contains(tipo))
                    {
                        merge.add(tipo);
                    }
                }
            for(Tipologia tipo: merge)
            {
                tipo.setMarkWarning(false);
                tipo.setUse(false);
                if(getTipologiasHorarioReferencia() != null && getTipologiasHorarioReferencia().contains(tipo))
                {
                    tipo.horRef = true;
                }

                if(getTipologiasExtraAdicionadas() != null && getTipologiasExtraAdicionadas().contains(tipo))
                {
                    tipo.extra = true;
                }
            }

            if(getTipologiasMarcadas() != null)
                for(Tipologia t: getTipologiasMarcadas())
                {
                    for(Tipologia tMerge: merge)
                    {
                        if(tMerge.equals(t))
                        {
                            tMerge.setMarkWarning(true);
                            break;
                        }
                    }
                }
            if(getTipologiasUsadas() != null)
                for(Tipologia t: getTipologiasUsadas())
                {
                    for(Tipologia tMerge: merge)
                    {
                        if(tMerge.equals(t))
                        {
                            tMerge.setUse(true);
                            break;
                        }
                    }
                }
            if(getTipologiasTdocTurma() != null)
                for(Tipologia t: getTipologiasTdocTurma())
                {
                    for(Tipologia tMerge: merge)
                    {
                        if(tMerge.equals(t))
                        {
                            tMerge.setUse(true);
                            break;
                        }
                    }
                }
            return merge;
        }

        /**
         *
         *
         * @param courseUnit
         * @return
         */

        public ArrayList<Tipologia> obtainTipologiasSimples(CourseUnit courseUnit)
        {
            ArrayList<Tipologia> merge = new ArrayList<Tipologia>();

            Map<String,Map<String,Tipologia>> docenteTurmas = new HashMap<String,Map<String,Tipologia>>();

            fullfillTipologiasSimples(getTipologiasSumarios(), docenteTurmas);
            fullfillTipologiasSimples(getTipologiasExtraAdicionadas(), docenteTurmas);
            fullfillTipologiasSimples(getTipologiasHorarioReferencia(), docenteTurmas);
            fullfillTipologiasSimples(getTipologiasMarcadas(), docenteTurmas);
            fullfillTipologiasSimples(getTipologiasUsadas(), docenteTurmas);
            fullfillTipologiasSimples(getTipologiasTdocTurma(), docenteTurmas);


            if(docenteTurmas.size() == 0)
            {
                //NAO Há sumários vamos associar todos os docentes a todas as turmas
                if(courseUnit.getTurmas() != null && courseUnit.getTeachers() != null)
                {
                    for(CourseUnitTurma turma: courseUnit.getTurmas())
                    {
                        for(Teacher t : courseUnit.getTeachers())
                        {
                            Tipologia simples = new Tipologia();
                            simples.setMarkWarning(true);
                            //simples.setUse(true);
                            simples.setCdDocente(""+t.getSigesCode());
                            simples.setCdTurma(turma.getTurma());
                            simples.setCdTipologia(Globals.BACO_TIPOLOGIA_SIMPLES_VIRTUAL_CODE);
                            simples.setDsTipologia(Globals.BACO_TIPOLOGIA_SIMPLES_DS);
                            merge.add(simples);
                        }
                    }
                }
            }
            else
            {
                for(1.5.0/docs/api/java/util/Map.html">Map.Entry<String,Map<String,Tipologia>> docentes: docenteTurmas.entrySet())
                {
                    for(Tipologia tipologia: docentes.getValue().values())
                    {
                        merge.add(tipologia);
                    }
                }
            }
            return merge;
        }

        /**
         * Cria uma tipologia Simples para cada par Docente-Turma nesta cadeira olhando para
         * todas as tipologias existentes, uma vez que o Baco não guarda associações entre
         * Docentes e Turmas isso será retirado das tipologias importadas
         *
         * @param tipologias
         * @param docenteTurmas
         */

        private void fullfillTipologiasSimples(ArrayList<Tipologia> tipologias, Map<String, Map<String, Tipologia>> docenteTurmas) {
            if(tipologias != null)
                for(Tipologia tipo: tipologias)
                {
                    Map<String,Tipologia> turmasDocente = docenteTurmas.get(tipo.getCdDocente());
                    if(turmasDocente == null)
                        turmasDocente = new HashMap<String,Tipologia>();
                    docenteTurmas.put(tipo.getCdDocente(),turmasDocente);
                    Tipologia simples = turmasDocente.get(tipo.getCdTurma());
                    if(simples==null)
                    {
                        simples = new Tipologia();
                        simples.setCdDocente(tipo.getCdDocente());
                        simples.setCdTurma(tipo.getCdTurma());
                        simples.setCdTipologia(Globals.BACO_TIPOLOGIA_SIMPLES_VIRTUAL_CODE);
                        simples.setDsTipologia(Globals.BACO_TIPOLOGIA_SIMPLES_DS);
                        //simples.setUse(true);//TODAS USADAS
                        if(tipo.hasOcorrencias())
                        {
                            simples.setOcorrencias(tipo.getOcorrencias());
                        }
                        turmasDocente.put(tipo.getCdTurma(),simples);
                        if(tipo.isTdocturma())
                            simples.setTdocturma(true);
                    }
                    else if(tipo.hasOcorrencias())
                    {
                        if(simples.getOcorrencias() == null)
                            simples.setOcorrencias(0);
                        simples.setOcorrencias(simples.getOcorrencias()+tipo.getOcorrencias());
                        if(tipo.isTdocturma())
                            simples.setTdocturma(true);
                    }

                }
        }


    }


    /**Services**/

    /**
     * Require Open Transaction
     * @return 1, 2, 3, 4
     */

    public int getAnoPlanoFromStudiesPlan()
    {
        CourseImpl courseImpl = (CourseImpl) DaoFactory.getCourseDaoImpl().narrow(getCourse());
        return courseImpl.getUnidadeAnoPlano(getSemestre(),getCode());
    }

    /**
     * Require Open Transaction
     * @return S1, .., S8, T1 .. T8, A1 .. A4
     */

    public 1.5.0/docs/api/java/lang/String.html">String getPeriodoPlanoFromStudiesPlan()
    {
        CourseImpl courseImpl = (CourseImpl) DaoFactory.getCourseDaoImpl().narrow(getCourse());
        return courseImpl.getUnidadePeriodoPlano(getSemestre(), getCode());
    }

    /**
     * Require Open Transaction
     * @return  S1 = 1, S2 = 2,S3 = 3,S4 = 4 ...T1 e T2 = 1, T2 e T3 = 2, T4 e T5 = 3 ...
     */

    public int getSemestrePlanoConvertido()
    {
        CourseImpl courseImpl = (CourseImpl) DaoFactory.getCourseDaoImpl().narrow(getCourse());
        return courseImpl.getUnidadeSemestrePlanoConvertido(getSemestre(), getCode());
    }

    /**
     * Require Open Transaction
     * @return S1 = 1, S2 = 2, S3 = 1, S4 = 2 ... T1 e T2 = 1,  T2 e T3 = 2, T4 e T5 = 1, T6 e T7 = 2
     */

    public int getSemestrePlanoAbsoluto()
    {
        1.5.0/docs/api/java/lang/String.html">String id = getSemestre();
        if(id.equals("S1"))
            return 1;
        else if(id.equals("S2"))
            return 2;
        else if(id.equals("A"))
            return -1;

        else if(id.equals("T1"))
            return 1;
        else if(id.equals("T2"))
            return 1;
        else if(id.equals("T3"))
            return 2;
        else if(id.equals("T4"))
            return 2;


        return -1;

    }


}