Subversion Repositories bacoAlunos

Rev

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

package pt.estgp.estgweb.services.sigesimports;

import jomm.dao.impl.AbstractDao;
import org.apache.log4j.Logger;
import pt.estgp.estgweb.Globals;
import pt.estgp.estgweb.domain.*;
import pt.estgp.estgweb.domain.dao.DaoFactory;
import pt.estgp.estgweb.domain.views.CourseView;
import pt.estgp.estgweb.services.courses.CoursesService;
import pt.estgp.estgweb.services.email.SendEmailService;
import pt.estgp.estgweb.services.expceptions.ServiceException;
import pt.estgp.estgweb.services.jobs.ServiceJob;
import pt.estgp.estgweb.services.logresults.ILogMessages;
import pt.estgp.estgweb.services.logresults.LogMessageTypeEnum;
import pt.estgp.estgweb.services.logresults.impl.DefaultLogMessage;
import pt.estgp.estgweb.services.logresults.impl.DefaultLogMessages;
import pt.estgp.estgweb.services.sigesimports.oracle.dao.DisciplinaDao;
import pt.estgp.estgweb.services.sigesimports.oracle.dao.connection.ConnectionManager;
import pt.estgp.estgweb.services.sigesimports.oracle.domain.Disciplina;
import pt.estgp.estgweb.services.sigesimports.oracle.domain.TipologiasHorario;
import pt.estgp.estgweb.services.sigesimports.oracle.domain.TipologiasSumario;
import pt.estgp.estgweb.services.sigesimports.oracle.domain.TipologiasTurma;
import pt.estgp.estgweb.utils.ConfigProperties;
import pt.estgp.estgweb.utils.Email;
import pt.utl.ist.berserk.logic.serviceManager.IService;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;

/**
 * @author Jorge Machado
 */

public class ImportCourseService extends ServiceJob implements IService
{
    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(ImportCourseService.class);

    private CoursesService coursesService = new CoursesService();

    int newUnits = 0;
    int newCourses = 0;
    int unitsRepeated = 0;
    int unitsAtualizadas = 0;
    int turmasSeparadasComInconsistencias = 0;
    int turmasSeparadasTratadasOk = 0;
    int erroGraveAObterTipologias = 0;
    static Map<String,Boolean> courseYearTurmasPolicy = new HashMap<String, Boolean>();

    public static void resetCourseYearTurmaPolicy()
    {
        courseYearTurmasPolicy.clear();
    }

    public ILogMessages run(1.5.0/docs/api/java/lang/String.html">String year,int institutionCode) throws ServiceException
    {
        1.5.0/docs/api/java/lang/String.html">String msgS = "STARTING COURSES IMPORT SERVICE FOR YEAR: " + year + " " + institutionCode;
        serviceLogInfo(msgS);
        logger.info(msgS);

        newUnits = 0;
        newCourses = 0;
        unitsRepeated = 0;
        unitsAtualizadas = 0;
        turmasSeparadasComInconsistencias = 0;
        turmasSeparadasTratadasOk = 0;
        erroGraveAObterTipologias=0;
        resetCourseYearTurmaPolicy();

        DefaultLogMessages logMessages = new DefaultLogMessages();
        try
        {
            logMessages.addMessage(new DefaultLogMessage("import.semestre.separated", LogMessageTypeEnum.INFO, "instituicao " + institutionCode));
            serviceLogInfo(logMessages.getLastMessage());

            HashMap<String, Disciplina> disciplinasMap = new HashMap<String, Disciplina>();
            HashMap<String, Disciplina> disciplinasMapS1 = new HashMap<String, Disciplina>();
            HashMap<String, Disciplina> disciplinasMapS2 = new HashMap<String, Disciplina>();
            HashMap<String, Disciplina> disciplinasMapA = new HashMap<String, Disciplina>();
            HashMap<String, Disciplina> disciplinasMapT1 = new HashMap<String, Disciplina>();
            HashMap<String, Disciplina> disciplinasMapT2 = new HashMap<String, Disciplina>();
            HashMap<String, Disciplina> disciplinasMapT3 = new HashMap<String, Disciplina>();
            HashMap<String, Disciplina> disciplinasMapT4 = new HashMap<String, Disciplina>();
            HashMap<String, Disciplina> cursosMap = new HashMap<String, Disciplina>();

            /**
             * Build Course Units Maps
             */

            /*SiGesWEB service;
            String WSDL = DaoFactory.getConfigurationDaoImpl().getSigesWebServicesWsdl();
            try
            {
                serviceLogInfo("STARTING WEB SERVICE AT " + WSDL);
                service = new SiGesWEB(new URL(WSDL), new QName(Globals.SIGES_WEBSERVICE_TARGET_NAMESPACE, "SiGesWEB"));
            }
            catch (MalformedURLException e)
            {
                logger.fatal(e, e);
                logMessages.addMessage(new DefaultLogMessage("import.error",e.toString(),"erro na configuracao do WEB Service", LogMessageTypeEnum.INFO));
                serviceLogError(logMessages.getLastMessage(), e);
                return logMessages;
            }
            */

            DisciplinaDao service = DisciplinaDao.getInstance();
            1.5.0/docs/api/java/sql/Connection.html">Connection conn = ConnectionManager.openConnection();

            importUnitsSemestre(service,conn, "S1", year,institutionCode, disciplinasMap, disciplinasMapS1, cursosMap, logMessages);
            importUnitsSemestre(service,conn, "S2", year,institutionCode, disciplinasMap, disciplinasMapS2, cursosMap, logMessages);
            importUnitsSemestre(service,conn, "A", year,institutionCode, disciplinasMap, disciplinasMapA, cursosMap, logMessages);
            importUnitsSemestre(service,conn, "T1", year,institutionCode, disciplinasMap, disciplinasMapT1, cursosMap, logMessages);
            importUnitsSemestre(service,conn, "T2", year,institutionCode, disciplinasMap, disciplinasMapT2, cursosMap, logMessages);
            importUnitsSemestre(service,conn, "T3", year,institutionCode, disciplinasMap, disciplinasMapT3, cursosMap, logMessages);
            importUnitsSemestre(service,conn, "T4", year,institutionCode, disciplinasMap, disciplinasMapT4, cursosMap, logMessages);

            /**
             * Import Courses
             */

            logMessages.addMessage(new DefaultLogMessage("import.semestre.updating.courses", LogMessageTypeEnum.INFO));
            serviceLogInfo("updating courses");
            logger.info("updating courses");
            Set<Map.Entry<String, Disciplina>> set2 = cursosMap.entrySet();
            for (1.5.0/docs/api/java/util/Map.html">Map.Entry<String, Disciplina> entry : set2)
            {
                Disciplina d = entry.getValue();
                CourseView c = coursesService.loadCourseByCode("" + d.getCodigoCurso().intValue(),false);

//                Course c = DaoFactory.getCourseDaoImpl().findCourseByCode("" + d.getCodigoCurso());
                if (c == null)
                {
                    c = new CourseView();
                    newCourses++;
                    serviceLogInfo("New Course Found: (" +  d.getCodigoCurso() + ") " + d.getNomeCurso());
//                    DaoFactory.getCourseDaoImpl().save(c);
                }
                c.setName(d.getNomeCurso());
                if(d.getGrauCurso() == null || d.getGrauCurso().trim().length() == 0)
                    d.setGrauCurso("unknown");
                1.5.0/docs/api/java/lang/String.html">String grauBaco = ConfigProperties.getProperty("siges.degree."+d.getGrauCurso());

                c.setDegree(grauBaco);
                c.setCode("" + d.getCodigoCurso().intValue());
                c.setImportYear(year);
                c.setInstitutionalCode("" + d.getCodigoInstituicao().intValue());
                coursesService.submitCourse(c,null,null,0,null,null);
            }

            /**
             * Update Course Units
             */

            updateCourseUnits(disciplinasMapS1, "S1",logMessages,year,institutionCode,service,conn);
            updateCourseUnits(disciplinasMapS2, "S2",logMessages,year,institutionCode,service,conn);
            updateCourseUnits(disciplinasMapA, "A",logMessages,year,institutionCode,service,conn);
            updateCourseUnits(disciplinasMapT1, "T1",logMessages,year,institutionCode,service,conn);
            updateCourseUnits(disciplinasMapT2, "T2",logMessages,year,institutionCode,service,conn);
            updateCourseUnits(disciplinasMapT3, "T3",logMessages,year,institutionCode,service,conn);
            updateCourseUnits(disciplinasMapT4, "T4",logMessages,year,institutionCode,service,conn);

            conn.close();

            serviceLogInfo("######################################");
            serviceLogInfo("######################################");
            serviceLogInfo("#Courses Imported:" + cursosMap.size());
            serviceLogInfo("#Units Imported S1:" + disciplinasMapS1.size());
            serviceLogInfo("#Units Imported S2:" + disciplinasMapS2.size());
            serviceLogInfo("#Units Imported A:" + disciplinasMapA.size());
            serviceLogInfo("#Units Imported T1:" + disciplinasMapT1.size());
            serviceLogInfo("#Units Imported T2:" + disciplinasMapT2.size());
            serviceLogInfo("#Units Imported T3:" + disciplinasMapT3.size());
            serviceLogInfo("#Units Imported T4:" + disciplinasMapT4.size());
            serviceLogInfo("#New Courses Found:" + newCourses);
            serviceLogInfo("#New Units Found:" + newUnits);
            serviceLogInfo("#Regular Updated Units:" + unitsAtualizadas);
            serviceLogInfo("#Unidades Repetidas (A mesma para o conjunto (Codigo,Curso,Ano,Semestre)):" + unitsRepeated);
            serviceLogInfo("#Turmas Separadas Tratadas com sucesso:" + turmasSeparadasTratadasOk);
            if(turmasSeparadasComInconsistencias > 0)
            {
                serviceLogInfo("!!!CHECK IN LOG######Units with Courses with Turmas Separadas with problems:" + turmasSeparadasComInconsistencias);
            }
            if(erroGraveAObterTipologias > 0)
            {
                serviceLogInfo("!!!Na trasnformacao do JSON em class nas tipologias:" + erroGraveAObterTipologias);
            }

            logger.info("######################################");
            logger.info("######################################");
            logger.info("#Courses Imported:" + cursosMap.size());
            logger.info("#Units Imported S1:" + disciplinasMapS1.size());
            logger.info("#Units Imported S2:" + disciplinasMapS2.size());
            logger.info("#Units Imported A:" + disciplinasMapA.size());
            logger.info("#Units Imported T1:" + disciplinasMapT1.size());
            logger.info("#Units Imported T2:" + disciplinasMapT2.size());
            logger.info("#Units Imported T3:" + disciplinasMapT3.size());
            logger.info("#Units Imported T4:" + disciplinasMapT4.size());
            logger.info("#New Courses Found:" + newCourses);
            logger.info("#New Units Found:" + newUnits);
            logger.info("#Regular Updated Units:" + unitsAtualizadas);
            logger.info("#Unidades Repetidas (A mesma para o conjunto (Codigo,Curso,Ano,Semestre)):" + unitsRepeated);
            logger.info("#Turmas Separadas Tratadas com sucesso:" + turmasSeparadasTratadasOk);
            if(turmasSeparadasComInconsistencias > 0)
            {
                logger.info("!!!CHECK IN LOG######Units with Courses with Turmas Separadas with problems:" + turmasSeparadasComInconsistencias);
            }
            if(erroGraveAObterTipologias > 0)
            {
                logger.info("!!!Na trasnformacao do JSON em class nas tipologias:" + erroGraveAObterTipologias);
            }


        }
        catch (1.5.0/docs/api/java/lang/Throwable.html">Throwable e)
        {
            logger.error(e,e);
            logMessages.addMessage(new DefaultLogMessage("import.error",e.toString(), "see log for details", LogMessageTypeEnum.ERROR));
            serviceLogError(logMessages.getLastMessage(), e);
            1.5.0/docs/api/java/lang/String.html">String cause = e.getCause() == null ? "" : e.getCause().toString();
            sendNotificationAdmin("Erro na importacao de sumarios",cause);
        }
        logger.info("terminating course import");
        serviceLogInfo("terminating course import");
        logMessages.addMessage(new DefaultLogMessage("import.course.terminating", LogMessageTypeEnum.INFO));
        setProgress(100);
        return logMessages;
    }

    /**
     * Envio de Notificação aos operadores do CI
     * @param subject
     * @param cause
     */

    private void sendNotificationAdmin(1.5.0/docs/api/java/lang/String.html">String subject, 1.5.0/docs/api/java/lang/String.html">String cause)
    {


        List<String> emails = ConfigProperties.getListValues("admin.email");
        for(1.5.0/docs/api/java/lang/String.html">String email:emails)
        {
            serviceLogWarn(">>>>>>>>ENVIANDO NOTIFICACAO A ADMINISTRACAO: " + email);
            logger.warn(">>>>>>>>ENVIANDO NOTIFICACAO A ADMINISTRACAO: " + email);
        }
        List<String> arguments = new ArrayList<String>();
        arguments.add(cause.replace("\n","<br/>"));
        Email email = new Email(subject,emails,Globals.SYSTEM_EMAIL_BOX,"messageToAdmin_pt.txt",arguments);
        email.setHtml(true);
        try {
            new SendEmailService().sendEmail(email);
        } catch (ServiceException e) {
            e.printStackTrace();
        }

    }



    /**
     * This method loads turmas separated policy from CourseYear
     * uses the cache courseYearTurmasPolicy
     * @param codigoDoCurso
     * @param year
     * @param logMessages
     * @return
     */

    public static boolean loadCourseYearTurmasPolicy(int codigoDoCurso,1.5.0/docs/api/java/lang/String.html">String year,DefaultLogMessages logMessages,ServiceJob service) {
        return loadCourseYearTurmasPolicy("" + codigoDoCurso,year,logMessages,service);
    }
    public static boolean loadCourseYearTurmasPolicy(1.5.0/docs/api/java/lang/String.html">String codigoDoCurso,1.5.0/docs/api/java/lang/String.html">String year,DefaultLogMessages logMessages,ServiceJob service) {

        1.5.0/docs/api/java/lang/Boolean.html">Boolean turmasSeparated = courseYearTurmasPolicy.get(codigoDoCurso + "-" + year);
        if(turmasSeparated != null)
            return turmasSeparated;

        List<CourseYear> courseYears = DaoFactory.getCourseYearDaoImpl().findCourseYear(""+codigoDoCurso,year);
        if(courseYears == null || courseYears.size() == 0)
        {
            checkOrCreateCourseYear(logMessages, year, "" + codigoDoCurso, service);
            courseYears = DaoFactory.getCourseYearDaoImpl().findCourseYear(""+codigoDoCurso,year);
        }
        if(courseYears != null && courseYears.size() > 0)
        {
            CourseYear cY = courseYears.get(0);
            courseYearTurmasPolicy.put(codigoDoCurso + "-" + year,cY.isSeparatedTurmas());
            return cY.isSeparatedTurmas();
        }
        return false;
    }

    private void importUnitsSemestre(DisciplinaDao service,
                                     1.5.0/docs/api/java/sql/Connection.html">Connection conn,
                                     1.5.0/docs/api/java/lang/String.html">String semestre,
                                     1.5.0/docs/api/java/lang/String.html">String year,
                                     int institutionCode,
                                     HashMap<String, Disciplina> disciplinasMap,
                                     HashMap<String, Disciplina> disciplinasMapSemestre,
                                     HashMap<String, Disciplina> cursosMap,
                                     DefaultLogMessages logMessages) throws 1.5.0/docs/api/java/sql/SQLException.html">SQLException {


        logMessages.addMessage(new DefaultLogMessage("import.semestre.course.units." + semestre, LogMessageTypeEnum.INFO));
        serviceLogInfo("importing " + semestre + " course units");
        logger.info("importing " + semestre + " course units");
        List<Disciplina> disciplinas = service.loadDisciplinas(institutionCode, year, semestre,conn);

        for (Disciplina d : disciplinas)
        {
            if(ImportStudentsService.isCursoFicticio(d.getCodigoCurso()))
                continue;

            boolean turmasSeparatedPolicy = loadCourseYearTurmasPolicy(d.getCodigoCurso(),year,logMessages,this);
            Disciplina inCache = disciplinasMap.get(getDisciplinaUniqueRef(d,year,logMessages));

            if (inCache != null
               // && !turmasSeparatedPolicy // Com politica de turmas separadas no curso a repeticao NÃO é normal
                    //A disciplina em cache significa que já foi importada da lista do SIGES uma disciplina
                    //com o mesmo código unico
                    //No caso dos cursos normais onde se encontram varias turmas é normal aparecerem aqui repetições
                    // nesses casos apenas uma vai para o Mapa, o que acontece é que precisamos de uma entrada por turma
                    //para os casos dos cursos de turmas separadas
            )
            {
                logMessages.addMessage(new DefaultLogMessage("import.semestre." + semestre, LogMessageTypeEnum.INFO,"Other turma for a unit in " + semestre + ":" + d.getCodigo().intValue() + " -> " + d.getCdTurma()));
                serviceLogInfo("Other turma for a unit in " + semestre + ":" + d.getCodigo().intValue() + " -> " + d.getCdTurma());
                logger.info("Other turma for unit in " + semestre + ":" + d.getCodigo().intValue()  + " -> " + d.getCdTurma());
            }

            //se houver mais que uma ocorrencia de turmas na disciplina sobrepoe, nao importa se forem de turmas juntas
            //So vai ser criada uma de qualquer maneira e a turma nao é usada neste caso. Apenas depois na imortação de alunos
            //para escolher a turma
            disciplinasMap.put(getDisciplinaUniqueRef(d,year,logMessages), d);
            disciplinasMapSemestre.put(getDisciplinaUniqueRef(d, year, logMessages), d);
            //para o caso do serviço ser chamado para varios anos
            cursosMap.put(d.getCodigoCurso().intValue()+":"+year, d);
        }
    }

    private 1.5.0/docs/api/java/lang/String.html">String getDisciplinaUniqueRef(Disciplina d,1.5.0/docs/api/java/lang/String.html">String year,DefaultLogMessages logMessages)
    {
        boolean turmasSeparatedPolicy = loadCourseYearTurmasPolicy(d.getCodigoCurso(),year,logMessages,this);
        if(turmasSeparatedPolicy)
            return d.getCodigo().intValue() + ":" + d.getCodigoCurso() + ":" + d.getCdDuracao() + ":" + d.getCdTurma();
        else
            return d.getCodigo().intValue() + ":" + d.getCodigoCurso() + ":" + d.getCdDuracao();
    }

    public static final int SIGES_CODIGO_TIPO_DISCIPLINA_EXTRA_CURRICULAR = ConfigProperties.getIntProperty("siges.codigo.tipo.disciplina.extra.curricular");
    private void updateCourseUnits(HashMap<String, Disciplina> disciplinasMapS, 1.5.0/docs/api/java/lang/String.html">String semestre, DefaultLogMessages logMessages, 1.5.0/docs/api/java/lang/String.html">String year,int institutionCode, DisciplinaDao service,1.5.0/docs/api/java/sql/Connection.html">Connection conn)
    {
        logMessages.addMessage(new DefaultLogMessage("import.semestre.updating.course.units." + semestre, LogMessageTypeEnum.INFO));


        logger.info("updating " + semestre + " course units");
        serviceLogInfo("updating " + semestre + " course units");
        Set<Map.Entry<String, Disciplina>> set = disciplinasMapS.entrySet();
        for (1.5.0/docs/api/java/util/Map.html">Map.Entry<String, Disciplina> entry : set)
        {
            Disciplina d = entry.getValue();
            //TIPO 6 é uma EXTRA CURRICULAR
            if(ImportStudentsService.isCursoFicticio(d.getCodigoCurso()))
            {
                logMessages.addMessage(new DefaultLogMessage("import.error","Ignorando disciplina com codigo de curso ficticio - codigo: " + d.getCodigoCurso(), " see log for details", LogMessageTypeEnum.WARNING));
                logger.warn(logMessages.getLastMessage());
                serviceLogWarn(logMessages.getLastMessage());

                continue;
            }
            //CourseUnit c = null;
            List<CourseUnit> cus = null;

            cus = DaoFactory.getCourseUnitDaoImpl().loadBySigesCodeUnique("" + d.getCodigo(), "" + d.getCodigoCurso(), semestre, year);

            //NOVO NOVO NOVO
            //Politica de separação de turmas em unidades independentes neste curso
            boolean separateTurmas = ImportCourseService.loadCourseYearTurmasPolicy(d.getCodigoCurso(),year,logMessages,this);
            //NOVO NOVO NOVO
            if(separateTurmas)
            {
                /***logging*****/
                logMessages.addMessage(new DefaultLogMessage("import.semestre.updating.course.units." + semestre, LogMessageTypeEnum.INFO,"Unidade de curso com turmas separadas encontrada siges: " + d.getCodigo() + " para curso:" + d.getCodigoCurso() + " turma:" + d.getCdTurma()));
                logger.info(logMessages.getLastMessage());
                serviceLogInfo(logMessages.getLastMessage());
                /**
                 * Este metodo aplicado apenas a cursos de turma separada
                 * vai retirar da lista de cus todas as que não tenham a turma em questão no campo cdTurma
                 * Caso haja inconsistencias ete metodo informa no LOG e tenta corrigir a situação
                 * O objectivo do metodo e econtrar a undade da turma em causa que obtemos
                 * da disciplina
                 * Relembrar que as disciplinas sao colocadas no mapa segundo o seu tipo
                 * se forem de turmasSeparada é colocada uma por turma, portanto
                 * vao vir para aqui as multiplas todas com as varias turmas
                 * e assim vamos filtrar todas as que vem na lista que nao sao da turma
                 * em tratamento neste momento, ou dar a turma a uma no caso de
                 * haver alguma sem turma, se nao houver nenhuma o metodo limpa todas
                 * e seguidamente vamos ter de a criar
                 */

                consistirUnidadesEmCursosTurmasSeparadas(semestre, logMessages, d, cus);
            }//NOVO NOVO NOVO




            if(cus != null && cus.size() > 1 )
            {
                unitsRepeated++;
                logMessages.addMessage(new DefaultLogMessage("import.warning","Unidade Repetida: (" + d.getCodigo() + ") curso: " + d.getCodigoCurso() + " " + semestre + " " + year, "see log for details, vai atualizar as duas", LogMessageTypeEnum.WARNING));
                logger.fatal(logMessages.getLastMessage());
                serviceLogWarn(logMessages.getLastMessage());
            }
            else if(cus != null && cus.size() == 1)
            {
                unitsAtualizadas++;
                1.5.0/docs/api/java/lang/String.html">String msg = "Regular unit update: " + "(" + d.getCodigo() + ") curso: " + d.getCodigoCurso() + " " + semestre + " " + year;
                logger.info(msg);
                serviceLogInfo(msg);
            }


            if (cus == null || cus.size() == 0)
            {
                CourseUnitImpl c = DomainObjectFactory.createCourseUnitImpl();
                if(separateTurmas)
                    c.setCdTurma(d.getCdTurma());
                else
                    c.setCdTurma("");
                DaoFactory.getCourseUnitDaoImpl().save(c);
                logMessages.addMessage(new DefaultLogMessage("import.error", "New Unit Found: (" +  d.getCodigo() + ") " + d.getNome() + " - curso (" + d.getNomeCurso() + ") " + d.getNomeCurso() + " turma(" + d.getCdTurma() + ")", "see log for details", LogMessageTypeEnum.INFO));
                logger.info(logMessages.getLastMessage());
                serviceLogInfo(logMessages.getLastMessage());
                newUnits++;
                cus = new ArrayList<CourseUnit>();
                cus.add(c);
            }
            //NOVO

            for(CourseUnit c: cus)
            {

                if(separateTurmas)
                    c.setCdTurma(d.getCdTurma());
                else
                    c.setCdTurma("");
                c.setName(d.getNome());
                c.setInstitutionCode("" + d.getCodigoInstituicao());//MUDADO AQUI
                c.setCode("" + d.getCodigo().intValue());
                c.setCourseCode("" + d.getCodigoCurso());
                c.setCourseName("" + d.getNomeCurso());
                c.setSemestre(semestre);
                c.setImportYear(year);
                Course course = DaoFactory.getCourseDaoImpl().findCourseByCode(c.getCourseCode());
                c.setCourse(course);
                checkOrCreateCourseYear(logMessages, year, c.getCourseCode(), this);
                //Obter as tipologias de sumarios e aulas e colocar na unidade
                fillTipologias(d, (CourseUnitImpl) c);
            }
        }
    }

    private void fillTipologias(Disciplina d, CourseUnitImpl c) {
        try {
            CourseUnitImpl.Tipologias t = c.getTipologiasClass();
            if(t == null)
                t = new CourseUnitImpl.Tipologias();

            t.setTipologiasTdocTurma(new ArrayList<CourseUnitImpl.Tipologia>());
            for(TipologiasTurma.TipologiaTurma tipologiaTurma : d.getTipologiasTdocTurma().getTipologias())
            {
                CourseUnitImpl.Tipologia tipoSum = new CourseUnitImpl.Tipologia();
                tipoSum.setOcorrencias(1);
                tipoSum.setDsTipologia("Aulas");
                tipoSum.setCdTurma(tipologiaTurma.getCdTurma());
                tipoSum.setCdDocente("" + tipologiaTurma.getCdDocente());
                tipoSum.setCdTipologia("1");
                tipoSum.setTdocturma(true);
                t.getTipologiasTdocTurma().add(tipoSum);
            }
            t.setTipologiasSumarios(new ArrayList<CourseUnitImpl.Tipologia>());
            for(TipologiasSumario.TipologiaSumario tipologiaSumario : d.getTipologiasSumario().getTipologias())
            {
                CourseUnitImpl.Tipologia tipoSum = new CourseUnitImpl.Tipologia();
                tipoSum.setOcorrencias(tipologiaSumario.getNumeroOcorrencias());
                tipoSum.setDsTipologia(ConfigProperties.getProperty("netpa.tipo.aula." + tipologiaSumario.getCdTipoAula()));
                tipoSum.setCdTurma(tipologiaSumario.getCdTurma());
                tipoSum.setCdDocente("" + tipologiaSumario.getCdDocente());
                tipoSum.setCdTipologia(""+tipologiaSumario.getCdTipoAula());
                t.getTipologiasSumarios().add(tipoSum);
            }
            t.setTipologiasHorarioReferencia(new ArrayList<CourseUnitImpl.Tipologia>());
            for(TipologiasHorario.TipologiaHorario tipologiaHorario : d.getTipologiasHorario().getTipologias())
            {
                CourseUnitImpl.Tipologia tipoSum = new CourseUnitImpl.Tipologia();
                1.5.0/docs/api/java/lang/String.html">String codigoCorrespondenteTipoAula =
                        ConfigProperties.getProperty("netpa.code.ocup." + tipologiaHorario.getCdTipoOcupacao() + ".tipo.aula");
                if(codigoCorrespondenteTipoAula != null && codigoCorrespondenteTipoAula.length() > 0)
                {
                    tipoSum.setOcorrencias(null);
                    tipoSum.setDsTipologia(ConfigProperties.getProperty("netpa.tipo.aula." + codigoCorrespondenteTipoAula));
                    tipoSum.setCdTipologia("" + codigoCorrespondenteTipoAula);
                    tipoSum.setCdTurma(tipologiaHorario.getCdTurma());
                    tipoSum.setCdDocente("" + tipologiaHorario.getCdDocente());
                    t.getTipologiasHorarioReferencia().add(tipoSum);
                }
                else
                {
                    1.5.0/docs/api/java/lang/System.html">System.out.println("Tipologia: cd tipo ocup ignorado:" + tipologiaHorario.getCdTipoOcupacao());
                }

            }
            for(TipologiasSumario.TipologiaSumario tipologiaHorarioTrabalho : d.getTipologiasHorarioTrabalho().getTipologias())
            {
                CourseUnitImpl.Tipologia tipoSum = new CourseUnitImpl.Tipologia();
                1.5.0/docs/api/java/lang/String.html">String codigoCorrespondenteTipoAula =
                        ConfigProperties.getProperty("netpa.code.ocup." + tipologiaHorarioTrabalho.getCdTipoAula() + ".tipo.aula");
                if(codigoCorrespondenteTipoAula != null && codigoCorrespondenteTipoAula.length() > 0)
                {
                    tipoSum.setOcorrencias(null);
                    tipoSum.setDsTipologia(ConfigProperties.getProperty("netpa.tipo.aula." + codigoCorrespondenteTipoAula));
                    tipoSum.setCdTipologia("" + codigoCorrespondenteTipoAula);
                    tipoSum.setCdTurma(tipologiaHorarioTrabalho.getCdTurma());
                    tipoSum.setCdDocente("" + tipologiaHorarioTrabalho.getCdDocente());
                    if(!t.getTipologiasHorarioReferencia().contains(tipoSum))
                        t.getTipologiasHorarioReferencia().add(tipoSum);
                }
                else
                {
                    1.5.0/docs/api/java/lang/System.html">System.out.println("Tipologia: cd tipo ocup ignorado:" + tipologiaHorarioTrabalho.getCdTipoAula());
                }

            }
            c.setTipologiasClass(t);
        } catch (1.5.0/docs/api/java/lang/Exception.html">Exception e) {
            logger.error(e, e);
            erroGraveAObterTipologias++;
        }
    }

    private void consistirUnidadesEmCursosTurmasSeparadas(1.5.0/docs/api/java/lang/String.html">String semestre, DefaultLogMessages logMessages, Disciplina d, List<CourseUnit> cus) {
        Iterator<CourseUnit> iterUnits = cus.iterator();
        //Retira todas as unidades com código de turma preenchido e diferente
        //sobram apenas cadeiras com o NOSSO código de TURMA ou cadeiras sem codigo de turma NENHUM
        while(iterUnits.hasNext())
        {
            CourseUnit cu = iterUnits.next();
            if(cu.getCdTurma() != null && cu.getCdTurma().trim().length() > 0 && !cu.getCdTurma().trim().equals(d.getCdTurma().trim()))
            {
                iterUnits.remove();
            }
        }
        if(cus.size() == 0)
        {
            /***logging*****/
            logMessages.addMessage(new DefaultLogMessage("import.semestre.updating.course.units." + semestre, LogMessageTypeEnum.INFO,"Sem unidade para a turma separada: " + d.getCdTurma()));
            logger.info(logMessages.getLastMessage());
            serviceLogInfo(logMessages.getLastMessage());
            //turma ainda nao existe vai ser criada
            turmasSeparadasTratadasOk++;
            /***logging*****/
        }
        else if(cus.size() == 1 && (cus.get(0).getCdTurma() == null || cus.get(0).getCdTurma().trim().length() == 0))
        {
            /***logging*****/
            logMessages.addMessage(new DefaultLogMessage("import.semestre.updating.course.units." + semestre, LogMessageTypeEnum.INFO,"Ja existe unidade mas sem turma vai ser alocada à a turma separada: " + d.getCdTurma()));
            logger.info(logMessages.getLastMessage());
            serviceLogInfo(logMessages.getLastMessage());
            //Ja existia nao tinha codigo de turma vamos colocar no lugar do codigo unico
            //que so serve para este controlo
            turmasSeparadasTratadasOk++;
            /****logging*****/

            cus.get(0).setCdTurma(d.getCdTurma());
        }
        else if(cus.size() == 1 && cus.get(0).getCdTurma() != null && cus.get(0).getCdTurma().trim().equals(d.getCdTurma().trim()))
        {
            /***logging*****/
            logMessages.addMessage(new DefaultLogMessage("import.semestre.updating.course.units." + semestre, LogMessageTypeEnum.INFO,"Encontrada a unidade para a turma separada: " + d.getCdTurma()));
            logger.info(logMessages.getLastMessage());
            serviceLogInfo(logMessages.getLastMessage());
            turmasSeparadasTratadasOk++;
            //ok e' a turma certa nao se faz mais nada
        }
        else if(cus.size() > 1)
        {
            turmasSeparadasComInconsistencias++;
            /*****logging*******/
            logMessages.addMessage(new DefaultLogMessage("import.semestre.updating.course.units." + semestre, LogMessageTypeEnum.ERROR,"Problema grave nas importações de unidades com turmas separadas para o codigo siges " + d.getCodigo() + ", mais que uma unidade sem turma ou com varias turmas iguais com o mesmo codigo siges, vamos tentar corrigir e reportar de seguida"));
            logger.error(logMessages.getLastMessage());
            serviceLogError(logMessages.getLastMessage());
            //Isto e' um problema muito grave, nao devera acontecer haver mais que uma unidade
            //repetida e ainda por cima com mais que um código de turma igual ou nosso ou a vazio
            //vamos remover todos os vazio, se não sobrar nenhum metemos a nossa turma num deles
            //se encontrarmos o nosso usamo-lo, se for mais que um usamos um e colocamos as turmas nos outros a vazio
            Iterator<CourseUnit> iter = cus.iterator();
            CourseUnit last = null;
            while(iter.hasNext())
            {
                last = iter.next();
                if(last.getCdTurma()==null || last.getCdTurma().trim().length() == 0)
                {
                    logMessages.addMessage(new DefaultLogMessage("import.units" + semestre, LogMessageTypeEnum.INFO,"removendo unidade da lista com turma vazia baco id:" + last.getId()));
                    logger.info(logMessages.getLastMessage());
                    serviceLogInfo(logMessages.getLastMessage());
                    iter.remove();
                }
            }

            if(cus.size() > 0)
            {
                logMessages.addMessage(new DefaultLogMessage("import.units" + semestre, LogMessageTypeEnum.INFO,"Sobraram unidades com o nosso código de turma:" + d.getCdTurma() + " vamos remover todas excepto a primeira"));
                logger.info(logMessages.getLastMessage());
                serviceLogInfo(logMessages.getLastMessage());
                //vamos deixar apenas uma com a nossa turma
                while(cus.size() > 1)
                {
                    logMessages.addMessage(new DefaultLogMessage("import.units" + semestre, LogMessageTypeEnum.INFO,"removendo baco id:" + cus.get(1).getId() + " e colocando a turma a vazio "));
                    logger.info(logMessages.getLastMessage());
                    serviceLogInfo(logMessages.getLastMessage());
                    cus.get(1).setCdTurma("");
                    cus.remove(1);
                }
            }
            else if(cus.size() == 0)
            {
                logMessages.addMessage(new DefaultLogMessage("import.units" + semestre, LogMessageTypeEnum.INFO,"ficamos sem unidades para usar, nenhuma tinha a nossa turma " + d.getCdTurma() + ", vamos usar a ultima com baco id:" + last.getId() + " e colocando a turma a " + d.getCdTurma()));
                logger.info(logMessages.getLastMessage());
                serviceLogInfo(logMessages.getLastMessage());
                cus.add(last);
                last.setCdTurma(d.getCdTurma());
            }
        }
    }

    /**
     * This method finds or create a courseYear for a courseUnit
     * @param logMessages
     * @param year
     * @param c
     * @param course
     * @return
     */

    private static Map<String,Boolean> courseYearServiceCache = new HashMap<String, Boolean>();
    protected static void checkOrCreateCourseYear(DefaultLogMessages logMessages, 1.5.0/docs/api/java/lang/String.html">String year, 1.5.0/docs/api/java/lang/String.html">String code, ServiceJob service) {
        if(courseYearServiceCache.get(code + "-" + year) != null)
        {
            return;
        }
        List<CourseYear> cYs = DaoFactory.getCourseYearDaoImpl().findCourseYear(code,year);
        CourseYear cY;
        if(cYs == null || cYs.size() == 0)
        {

            Course course = DaoFactory.getCourseDaoImpl().findCourseByCode(code);
            if(course == null)
                return; //does not exist yet
            /*****logging******/
            logMessages.addMessage(new DefaultLogMessage("import.ok", "Creating new CourseYear  course(" +  code + ") year" + year + ")", "see log for details", LogMessageTypeEnum.INFO));
            logger.info(logMessages.getLastMessage());
            service.serviceLogInfo(logMessages.getLastMessage());
            /*****logging******/
            if(course.getCourseYears() == null)
                course.setCourseYears(new HashSet<CourseYear>());
            cY = DomainObjectFactory.createCourseYearImpl();
            cY.setImportYear(year);
            cY.setSeparatedTurmas(false);
            DaoFactory.getCourseYearDaoImpl().save(cY);
            course.getCourseYears().add(cY); //adiciona só de um lado
        }
        else if(cYs.size() > 1)
        {
            /*****logging******/
            logMessages.addMessage(new DefaultLogMessage("import.error", "CourseYear more than one ocurrence course(" +  code + ") year" + year + ")", "see log for details", LogMessageTypeEnum.ERROR));
            logger.error(logMessages.getLastMessage());
            service.serviceLogError(logMessages.getLastMessage());
            /*****logging******/
            //Never happen while year are created only here
        }
        courseYearServiceCache.put(code + "-" + year,true);
    }


    @1.5.0/docs/api/java/lang/Override.html">Override
    protected ILogMessages runJobServiceTask() throws 1.5.0/docs/api/java/lang/Throwable.html">Throwable {

        1.5.0/docs/api/java/lang/String.html">String importYear = getParametersMap().get(JOB_importYear_KEY).getObject();
        1.5.0/docs/api/java/lang/String.html">String institutionCode = getParametersMap().get(JOB_institution_KEY).getObject();
        ILogMessages messages = run(importYear,1.5.0/docs/api/java/lang/Integer.html">Integer.parseInt(institutionCode));
        return messages;

    }


    public static void main(1.5.0/docs/api/java/lang/String.html">String[] args) throws ServiceException
    {
        1.5.0/docs/api/java/lang/String.html">String year = DaoFactory.getConfigurationDaoImpl().getImportsDefaultImportYearCreateTransaction();
        int institutionCode = 3;// DaoFactory.getConfigurationDaoImpl().getInstitutionCodeCreateTransaction();
        if(args != null && args.length > 0)
            year = args[0];
        if(args != null && args.length > 1)
            institutionCode = 1.5.0/docs/api/java/lang/Integer.html">Integer.parseInt(args[1]);
        AbstractDao.getCurrentSession().beginTransaction();
        new ImportCourseService().run(year,institutionCode);
        AbstractDao.getCurrentSession().getTransaction().commit();
    }


}