Subversion Repositories bacoAlunos

Rev

Rev 1814 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package pt.estgp.estgweb.services.courses;

import com.owlike.genson.Genson;
import com.owlike.genson.GensonBuilder;
import com.owlike.genson.reflect.VisibilityFilter;
import jomm.dao.impl.AbstractDao;
import jomm.utils.BytesUtils;
import jomm.utils.FilesUtils;
import jomm.utils.StreamsUtils;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import pt.estgp.estgweb.utils.Globals;
import pt.estgp.estgweb.domain.*;
import pt.estgp.estgweb.domain.dao.DaoFactory;
import pt.estgp.estgweb.domain.views.CourseView;
import pt.estgp.estgweb.filters.chains.ResourceAccessControlEnum;
import pt.estgp.estgweb.filters.exceptions.AccessDeniedException;
import pt.estgp.estgweb.services.courses.xsd.*;
import pt.estgp.estgweb.services.data.IRepositoryFile;
import pt.estgp.estgweb.services.data.RepositoryService;
import pt.estgp.estgweb.services.expceptions.AlreadyExistsException;
import pt.estgp.estgweb.services.expceptions.ServiceException;
import pt.estgp.estgweb.services.users.ReplaceRoleResult;
import pt.estgp.estgweb.services.users.UserRoleConfigService;
import pt.estgp.estgweb.utils.ConfigProperties;
import pt.estgp.estgweb.utils.Dom4jUtil;
import pt.estgp.estgweb.utils.StringsUtils;
import pt.utl.ist.berserk.logic.serviceManager.IService;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.*;
import java.net.URL;
import java.util.*;

/*
 * @author Goncalo Luiz gedl [AT] rnl [DOT] ist [DOT] utl [DOT] pt
 *
 *
 * Created at 17/Out/2003 , 23:45:24
 *
 */

/**
 * @author Jorge Machado
 *
 *
 * Created at 17/Out/2003 , 23:45:24
 *
 */

public class CoursesService 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(CoursesService.class);

    RepositoryService repositoryService = new RepositoryService();



    /**
     * Servico e subservico para termos acesso as variaveis de controlo
     * @param id
     * @param initUnits
     * @return
     * @throws ServiceException
     */

    public CourseView loadCourse(long id, boolean initUnits)
            throws ServiceException
    {
        return loadCourse(id,initUnits,false);
    }
    public CourseView loadCourseAndStudiesPlans(long id, boolean initUnits)
            throws ServiceException
    {
        return loadCourse(id,initUnits,true);
    }


    private CourseView loadCourse(long id, boolean initUnits,boolean loadStudiesPlans) throws ServiceException
    {
        Course c = DaoFactory.getCourseDaoImpl().get(id);

        if(c != null)
        {
            return getCourseView(initUnits, c,loadStudiesPlans);
        }
        return null;
    }

    /**
     * Servico e subservico para termos acesso as variaveis de controlo
     * @param code
     * @param initUnits
     * @return
     * @throws ServiceException
     */


    public CourseView loadCourseByCode(1.5.0/docs/api/java/lang/String.html">String code, boolean initUnits) throws ServiceException
    {
        return loadCourseByCode(code,initUnits,false);
    }
    public CourseView loadCourseByCodeAndStudiesPlans(1.5.0/docs/api/java/lang/String.html">String code, boolean initUnits) throws ServiceException
    {
        return loadCourseByCode(code,initUnits,true);
    }


    private CourseView loadCourseByCode(1.5.0/docs/api/java/lang/String.html">String code, boolean initUnits,boolean loadStudiesPlans) throws ServiceException
    {
        try{
            Course c = DaoFactory.getCourseDaoImpl().findCourseByCode(code);
            if(c != null)
            {
                return getCourseView(initUnits, c, loadStudiesPlans);
            }
        }
        catch(1.5.0/docs/api/java/lang/Throwable.html">Throwable e)
        {
            logger.error(e + " loading code:" + code,e);
            throw new ServiceException("loading code: " + code  + " - " + e.toString(),e);
        }
        return null;
    }

    /**
     * Carrega efetivamente o curso nos servicos load e load by code
     * @param initUnits
     * @param c
     * @return
     */


    private CourseView getCourseView(boolean initUnits, Course c,boolean loadStudiesPlans) {
        CourseView cV = new CourseView(c,initUnits);
            /*
            * todo Parte antig antigo XML do plano de estudos para remover futuramente*/

        if(c.getStudiesPlan() != null)
        {
            RepositoryFileImpl repositoryFile = repositoryService.loadView(c.getStudiesPlan());
            cV.setStudiesPlan(repositoryFile);
        }
        if(loadStudiesPlans && c.getStudiesPlans() != null && c.getStudiesPlans().size() > 0)
        {
            for(CourseStudiesPlan sp : c.getStudiesPlans())
            {
                sp.getVersion();
                cV.getCourseStudiesPlans().add(sp);
            }
        }

        return cV;
    }

    public List<String> loadImportYears(UserSession userSession) throws ServiceException
    {
        List<String> importYears = DaoFactory.getCourseDaoImpl().loadImportYears();
        List<String> imStrings = new ArrayList<String>();
        for(1.5.0/docs/api/java/lang/String.html">String importYear: importYears)
        {
            imStrings.add(importYear);
        }
        return imStrings;
    }



    public CourseView submitCourse(CourseView courseView,
                                   5+0%2Fdocs%2Fapi+InputStream">InputStream stream,
                                   1.5.0/docs/api/java/lang/String.html">String name,
                                   int size,
                                   1.5.0/docs/api/java/lang/String.html">String contentType,
                                   UserSession userSession) throws ServiceException, JAXBException, 1.5.0/docs/api/java/io/IOException.html">IOException {
        Course c;
        if(courseView.getId() > 0)
        {
            c = DaoFactory.getCourseDaoImpl().get(courseView.getId());
        }
        else
        {
            c = DaoFactory.getCourseDaoImpl().findCourseByCodeAndYear(courseView.getCode(),courseView.getImportYear());
            if(c != null)
                throw new AlreadyExistsException(AlreadyExistsException.ALREADY_EXISTS_COURSE);      
            c = DomainObjectFactory.createCourseImpl();
            DaoFactory.getCourseDaoImpl().save(c);
        }

        1.5.0/docs/api/java/lang/String.html">String htmlTrasformationResult = null;

        //Stream que pode vir do upload da UIde Admin de Cursos
        htmlTrasformationResult = uploadStudiesPlan(stream, name, size, contentType, userSession, c,false,null);
        courseView.persistViewInObject(c);
        CourseView cv = loadCourse(c.getId(),false);
        cv.setHtmlResult(htmlTrasformationResult);

        /**
         * New## generating course json
         */

        generateCourseJson(c);

        return cv;
    }

    private 1.5.0/docs/api/java/lang/String.html">String uploadStudiesPlan(5+0%2Fdocs%2Fapi+InputStream">InputStream stream, 1.5.0/docs/api/java/lang/String.html">String name, int size, 1.5.0/docs/api/java/lang/String.html">String contentType, UserSession userSession, Course c,boolean forceUrlFichas, 1.5.0/docs/api/java/lang/String.html">String systemUrl) throws JAXBException {
        1.5.0/docs/api/java/lang/String.html">String htmlTrasformationResult = null;
        //APENAS NO CASO DO AMDIN FAZER UPLOAD DE UM XML
        if(stream != null && size > 0)
        {
            1.5.0/docs/api/java/lang/String.html">String extension = FilesUtils.getExtension(name);
            if(c.getStudiesPlan() == null)
            {
                1.5.0/docs/api/java/lang/String.html">String identifier = repositoryService.storeRepositoryFile(stream, contentType, extension, size, name, "course.studies.plan " + c.getName(), ResourceAccessControlEnum.publicDomain, null, userSession);
                c.setStudiesPlan(identifier);
            }
            else
            {
                repositoryService.updateRepositoryFile(c.getStudiesPlan(), stream, contentType, extension, size, name, "course.studies.plan " + c.getName(), ResourceAccessControlEnum.publicDomain);
            }
            htmlTrasformationResult = generateHtmlCache(userSession, c);
            //####New#### Generating XML with JaxB
            //ISTO SO É CHAMADO NO CASO DE SE FAZER UPLOAD DE UM NOVO PLANO PELO MECANISMO ANTIGO
            generateXmlJaxbStudiesPlanVersionFromRepositoryOldPlanStream(userSession, c, forceUrlFichas, systemUrl);
        }
        return htmlTrasformationResult;
    }



    private void generateCourseJson(Course cAux) throws 1.5.0/docs/api/java/io/IOException.html">IOException {
        CourseImpl c = (CourseImpl) DaoFactory.getCourseDaoImpl().narrow(cAux);

        if(c.getValidationRole() != null && c.getValidationRole().trim().length() > 0)
        {
            List<Teacher> courseComissionProxys = DaoFactory.getUserDaoImpl().loadRoleTeachers(c.getValidationRole());
            List<Teacher> courseComission = new ArrayList<Teacher>();
            for(Teacher t: courseComissionProxys)
            {
                courseComission.add(DaoFactory.getTeacherDaoImpl().narrow(t));
            }
            c.setCourseComission(courseComission);
        }
        //Getting Coordinator from proxy
        Teacher t = c.getCoordinator();
        if(t != null)
            t.getName();
        else
        {
            logger.warn("Course does not have coordinator");
        }

        1.5.0/docs/api/java/lang/String.html">String jsonCourse = getGensonCourse().serialize(c);
        c.setJson(jsonCourse);
    }

    private 1.5.0/docs/api/java/lang/String.html">String generateHtmlCache(UserSession userSession, Course c) {
        1.5.0/docs/api/java/lang/String.html">String htmlTrasformationResult = null;
        5+0%2Fdocs%2Fapi+InputStream">InputStream stream;IRepositoryFile repositoryFile = repositoryService.load(c.getStudiesPlan(),userSession);
        stream = repositoryFile.getInput();
        try
        {
            5+0%2Fdocs%2Fapi+Document">Document dom = Dom4jUtil.parse(stream);
            Map<String,Object> parameters = new HashMap<String,Object>();
            parameters.put("COURSE_SIGES_CODE",c.getCode());
            1.5.0/docs/api/java/lang/String.html">String html = Dom4jUtil.styleDocument(dom, Globals.TEMPLATE_COURSE_XSL_PATH,parameters);
            c.setCacheWebDocument(html);
        }
        catch (1.5.0/docs/api/java/lang/Exception.html">Exception e)
        {
            1.5.0/docs/api/java/io/StringWriter.html">StringWriter writer = new 1.5.0/docs/api/java/io/StringWriter.html">StringWriter();
            1.5.0/docs/api/java/io/PrintWriter.html">PrintWriter printWriter = new 1.5.0/docs/api/java/io/PrintWriter.html">PrintWriter(writer);
            e.printStackTrace(printWriter);
            htmlTrasformationResult = "<div class=\"error\"><pre>" + e.toString() + "\n" + printWriter.toString() + "</pre></div>";
            printWriter.close();
        }
        try
        {
            stream.close();
        }
        catch (1.5.0/docs/api/java/io/IOException.html">IOException e)
        {
            logger.error(e,e);
        }
        return htmlTrasformationResult;
    }

    /**
     * ##NEW METHOD###
     * Gera o XML normalizado para o JAXB a partir do XML importado do XML do plano XML quese usou no upload
     * para garantir que está bem formado
     * @param userSession
     * @param c
     * @return
     * @throws JAXBException if XML is not weel formed
     */

    private void generateXmlJaxbStudiesPlanVersionFromRepositoryOldPlanStream(UserSession userSession, Course c, boolean forceFichaCurricularUrlSet, 1.5.0/docs/api/java/lang/String.html">String systemUrlForUnitPrograms) throws JAXBException
    {
        CourseStudiesPlan courseStudiesPlan;
        if(c.getStudiesPlan() == null || c.getStudiesPlan().trim().length() == 0)
        {
            //ESTE É O STREAM DO PLANO DE UPLOAD
            logger.warn("Course does not have studies plan XML file stream to use in update");
            return;
        }

        if(c.getStudiesPlans() == null || c.getStudiesPlans().size() == 0)
        {
            logger.info("Generating first study plan");
            courseStudiesPlan = DomainObjectFactory.createCourseStudiesPlanImpl();
            courseStudiesPlan.setVersion(1);
            courseStudiesPlan.setVersionDescription("Auto gerado durante a importação de um XML com o plano de estudos a " + new 5+0%2Fdocs%2Fapi+Date">Date().toString());
            courseStudiesPlan.setCourse(c);
            if(c.getStudiesPlans() == null)
                c.setStudiesPlans(new HashSet<CourseStudiesPlan>());
            c.getStudiesPlans().add(courseStudiesPlan);
            DaoFactory.getCourseStudiesPlanDaoImpl().save(courseStudiesPlan);
        }
        else
        {
            courseStudiesPlan = c.getStudiesPlans().iterator().next();
            logger.info("Updating Study Plan version " + courseStudiesPlan.getVersion());
        }

        5+0%2Fdocs%2Fapi+InputStream">InputStream stream;
        IRepositoryFile repositoryFile = repositoryService.load(c.getStudiesPlan(),userSession);
        long lastVersion = repositoryService.loadView(c.getStudiesPlan()).getLastVersion().getId();
        //stream = repositoryFile.getInput();
        //TODO TIRAR
        //JUST FOR DEBUG
       /* try {
            System.out.println(StreamsUtils.readString(stream));
            stream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }*/

        repositoryFile = repositoryService.load(c.getStudiesPlan(),userSession);
        stream = repositoryFile.getInput();

        try {
            JAXBContext jc = JAXBContext.newInstance(Curso.class);
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            //Just in case lets update SigesCode
            Curso curso = (Curso) unmarshaller.unmarshal(stream);
            curso.setSiges(c.getCode());
            curso.setNome(c.getName());
            curso.setDep(c.getArea());

            //##NOVO PARA GERAR LINK SE NAO EXISTIR
            generateAutoUrlFichasCurriculares(curso,systemUrlForUnitPrograms,forceFichaCurricularUrlSet);

            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            1.5.0/docs/api/java/io/StringWriter.html">StringWriter sw = new 1.5.0/docs/api/java/io/StringWriter.html">StringWriter();
            marshaller.marshal(curso, sw);
            //SETTING XML in COURSE STUDIES PLAN
            courseStudiesPlan.setXml(sw.toString());


            1.5.0/docs/api/java/lang/String.html">String json = CursoImpl.getGensonPlanoEstudosParaApiJsonWS().serialize(curso);
            //SETTING JSON in COURSE STUDIES PLAN
            courseStudiesPlan.setJson(json);

        } catch (JAXBException e) {
            logger.error(e,e);
            1.5.0/docs/api/java/lang/System.html">System.out.print("check XML for possible errors for repositoryStream:" + c.getStudiesPlan() + " file version: " + lastVersion);
            throw e;
        }
        try
        {
            stream.close();
        }
        catch (1.5.0/docs/api/java/io/IOException.html">IOException e)
        {
            logger.error(e,e);
        }
    }


    /**
     * Apenas é chamado quando se tenta injectar um programa a partir de um upload que foi feito
     * pelo user ou pela sincronização remota
     * @param curso
     * @param systemUrl
     * @param force
     */

    private void generateAutoUrlFichasCurriculares(Curso curso,1.5.0/docs/api/java/lang/String.html">String systemUrl,boolean force)
    {
        for(Curso.Semestre s :curso.getSemestre())
        {
            for(Curso.Semestre.Perfil p :s.getPerfil())
            {
                for(UnidadeType unidadeType : p.getUnidade())
                {
                    generateAutoUrlUnidade(unidadeType,systemUrl,curso,s,force);
                }
            }
            for(UnidadeType unidadeType : s.getUnidade())
            {
                generateAutoUrlUnidade(unidadeType,systemUrl,curso,s,force);
            }
        }
    }

    private void generateAutoUrlUnidade(UnidadeType unidadeType,1.5.0/docs/api/java/lang/String.html">String systemUrl,Curso curso,Curso.Semestre semestre,boolean force)
    {
        if(force || unidadeType.getUrlFichaCurricular() == null || unidadeType.getUrlFichaCurricular().trim().length()==0)
        {
            logger.info("GENERATING FICHA CURRICULAR URL For " + unidadeType.getNome());
            1.5.0/docs/api/java/lang/String.html">String url = systemUrl != null ? systemUrl : "";
            if(!url.endsWith("/"))
                url = url + "/";

            //Nao fornece o ano pois o servico irá assumir o ultimo
            unidadeType.setUrlFichaCurricular(url + "startLoadCourseUnitProgramSiges.do?unitCode=" + unidadeType.getSiges() + "&courseCode=" + curso.getSiges() + "&semestre=" + semestre.getId());
            unidadeType.setUrlUnidadeCurricular(url + "startLoadCourseUnitSiges.do?unitCode=" + unidadeType.getSiges() + "&courseCode=" + curso.getSiges() + "&semestre=" + semestre.getId());
        }
    }


    private static Genson getGensonCourse(){
        Genson genson = new GensonBuilder()
                .exclude(5+0%2Fdocs%2Fapi+Object">Object.class)
                .useFields(false)
                .useMethods(true)
                .setMethodFilter(VisibilityFilter.PACKAGE_PUBLIC)
                .exclude("admin")
                .exclude("autoBlock")
                .exclude("autoBlockMode")
                .exclude("manualBlock")
                .exclude("newUser")
                .exclude("student")
                .exclude("superuser")
                .exclude("superuserOrAdmin")
                .exclude("teacher")
                .exclude("unitCheck")
                .exclude("id")

/*              .exclude(Course.class)
                .exclude(CourseImpl.class)
                .exclude(GenericUser.class)
                .exclude(User.class)
                .exclude(UserImpl.class)
                .exclude(Teacher.class)
                .exclude(TeacherImpl.class)
                .exclude(SigesUser.class)
                .exclude(SigesUserImpl.class)
                .exclude(GenericUser.class)
                .exclude(GenericUserImpl.class)
*/

                .exclude("id", Course.class)
                .exclude("status", Course.class)
                .exclude("showStudiesPlan", Course.class)
                .include("degreeForJsonApi", CourseImpl.class)
                .include("degreeForJsonApiEn", CourseImpl.class)
                .include("degreeForJsonApiEs", CourseImpl.class)
                .include("degreeForJsonApiFr", CourseImpl.class)
                .include("schoolForJsonApi", CourseImpl.class)
                .include("statusForJsonApi", CourseImpl.class)


                .include("name", Course.class)
                .include("nameEn", Course.class)
                .include("nameEs", Course.class)
                .include("nameFr", Course.class)
                .include("department", Course.class)
                .exclude("active", CourseDepartment.class)
                .include("sigla", CourseDepartment.class)
                .include("name", CourseDepartment.class)
                .include("nameEn", CourseDepartment.class)
                .include("nameEs", CourseDepartment.class)
                .include("nameFr", CourseDepartment.class)
                .include("code", Course.class)
                .include("validationRole", Course.class)

                .include("courseComission", CourseImpl.class)

                .include("name", GenericUser.class)
                .include("email", GenericUser.class)
                .include("sigesCode", SigesUser.class)
                .include("coordinator", Course.class)
                .create();

        return genson;
    }



    public List<CourseView> loadCourses() throws ServiceException
    {
        List<Course> courses = DaoFactory.getCourseDaoImpl().findAllOrderByName();
        List<CourseView> courseViews = new ArrayList<CourseView>();
        for(Course c: courses)
        {
            CourseView courseView = new CourseView(c);
            courseViews.add(courseView);
        }
        return courseViews;
    }

    public List<CourseView> loadCoursesImportYearArea(1.5.0/docs/api/java/lang/String.html">String importYear, 1.5.0/docs/api/java/lang/String.html">String area) throws ServiceException
    {
        return loadCoursesImportYearAreaInstitution(importYear, area,null);
    }

    public List<CourseView> loadCoursesImportYearAreaInstitution(1.5.0/docs/api/java/lang/String.html">String importYear, 1.5.0/docs/api/java/lang/String.html">String area,1.5.0/docs/api/java/lang/String.html">String institutionCode) throws ServiceException
    {
        List<Course> courses = DaoFactory.getCourseDaoImpl().findAllOrderByName(importYear,area,null,institutionCode);
        List<CourseView> courseViews = new ArrayList<CourseView>();
        for(Course c: courses)
        {
            CourseView courseView = new CourseView(c);
            courseViews.add(courseView);
        }
        return courseViews;
    }

    public List<CourseView> loadCoursesImportYear() throws ServiceException
    {
        1.5.0/docs/api/java/lang/String.html">String importYearIntranet = DaoFactory.getConfigurationDaoImpl().getInterfaceImportYear();
        List<Course> courses = DaoFactory.getCourseDaoImpl().findAllOrderByName(importYearIntranet);
        List<CourseView> courseViews = new ArrayList<CourseView>();
        for(Course c: courses)
        {
            CourseView courseView = new CourseView(c);
            courseViews.add(courseView);
        }
        return courseViews;
    }
    public List<CourseView> loadCoursesImportYearByType(1.5.0/docs/api/java/lang/String.html">String type) throws ServiceException
    {
        1.5.0/docs/api/java/lang/String.html">String importYearIntranet = DaoFactory.getConfigurationDaoImpl().getInterfaceImportYear();
        List<Course> courses = DaoFactory.getCourseDaoImpl().findAllOrderByNameEvenWithoutCourseUnit(importYearIntranet,null,type);
        List<CourseView> courseViews = new ArrayList<CourseView>();
        for(Course c: courses)
        {
            CourseView courseView = new CourseView(c);
            courseViews.add(courseView);
        }
        return courseViews;
    }

    public List<CourseView> loadActiveCoursesByType(1.5.0/docs/api/java/lang/String.html">String type) throws ServiceException
    {
        1.5.0/docs/api/java/lang/String.html">String importYearIntranet = DaoFactory.getConfigurationDaoImpl().getInterfaceImportYear();
        List<Course> courses = DaoFactory.getCourseDaoImpl().findAllActiveOrderByNameEvenWithoutCourseUnit(importYearIntranet,null,type);
        List<CourseView> courseViews = new ArrayList<CourseView>();
        for(Course c: courses)
        {
            CourseView courseView = new CourseView(c);
            courseViews.add(courseView);
        }
        return courseViews;
    }



    /** JSON API **/
    /**
     * @SERVICE@
     *
     * @param school
     * @param type
     * @return
     * @throws JSONException
     */

    public JSONObject getActiveCoursesForJsonApi(1.5.0/docs/api/java/lang/String.html">String school,1.5.0/docs/api/java/lang/String.html">String type) throws JSONException {
        1.5.0/docs/api/java/lang/String.html">String institutionalCode = null;
        1.5.0/docs/api/java/lang/String.html">String degree = null;
        if(school != null && school.length() > 0)
            institutionalCode = ConfigProperties.getProperty("institution.code.prefix.inverse." + school);

        if(type != null && type.length() > 0)
            degree = ConfigProperties.getProperty("course.inverse." + type);

        List<Course> courses = DaoFactory.getCourseDaoImpl().findAllShowStudiesPlanCoursesOrderByNameEvenWithoutCourseUnit(institutionalCode, degree);
        JSONObject coursesResponse = new JSONObject();

        JSONArray coursesArray = new JSONArray();
        for(Course cAux: courses)
        {
            CourseImpl c = (CourseImpl) DaoFactory.getCourseDaoImpl().narrow(cAux);
            JSONObject courseJson = new JSONObject();
            courseJson.put("name",c.getName());
            courseJson.put("code",c.getCode());
            courseJson.put("schoolForJsonApi",c.getSchoolForJsonApi());
            courseJson.put("degreeForJsonApi",c.getDegreeForJsonApi());
            courseJson.put("degreeForJsonApiEn",c.getDegreeForJsonApiEn());
            courseJson.put("degreeForJsonApiEs",c.getDegreeForJsonApiEs());
            courseJson.put("degreeForJsonApiFr",c.getDegreeForJsonApiFr());
            courseJson.put("statusForJsonApi",c.getStatusForJsonApi());
            courseJson.put("getDetailedInfoUrl","/wsjson/api?service=getCourse&code=" + c.getCode());
            coursesArray.put(courseJson);

        }
        coursesResponse.put("status","ok");
        coursesResponse.put("courses",coursesArray);

        return coursesResponse;
    }

    /**
     *
     * * Serviço invocado para obter o JSON de um curso
     * O JSON tem dois campos o courseInfo e o plano de estudos colocados separadamente
     *
     * Atenção o plano de estudos usado é o ultimo considerando o seu ID
     *  Nota: O plano de Estudos é uma classe persistente que tem apenas versão e descrição
     *  deverá ter como campo o XML e o JSON já gerados do plano de estudos que comporta
     *
     * //TODO REVER
     * @param code
     * @return
     * @throws JSONException
     * @throws IOException
     * @throws JAXBException
     */

    public JSONObject getCourseDetailForJsonApi(1.5.0/docs/api/java/lang/String.html">String code) throws JSONException, 1.5.0/docs/api/java/io/IOException.html">IOException, JAXBException {

        Course course = DaoFactory.getCourseDaoImpl().findCourseByCode(code);


        JSONObject coursesResponse = new JSONObject();

        generateCourseJson(course);

        //if(course.toJson() == null)
        //{
        //    logger.info("status JSON NOT EXIST FOR STUDIES PLAN IN THIS COURSE, will generate");
        //    new CoursesService().generateCourseJson(course);
        //}

        if(course.getJson() != null)
        {
            JSONObject courseObj = new JSONObject(course.getJson());
            coursesResponse.put("courseInfo",courseObj);
            //Este caso apenas se dá se o plano nunca tiver sido editado ou sincronizado
            //Nesse caso o sistema irá tentar obtê-lo da stream do repositorio
            if(course.getStudiesPlans() == null || course.getStudiesPlans().size() == 0)
            {
                logger.info("status JSON NOT EXIST FOR STUDIES PLAN IN THIS COURSE, will try generate from studies plan OLD Stream");
                UserSession userSession = DomainObjectFactory.createUserSessionImpl();
                userSession.setUser(DaoFactory.getUserDaoImpl().load(new 1.5.0/docs/api/java/lang/Long.html">Long(1)));
                new CoursesService().generateXmlJaxbStudiesPlanVersionFromRepositoryOldPlanStream(userSession, course, false, null);
            }

            if(course.getStudiesPlans() != null )
            {
                CourseStudiesPlan studiesPlan = course.getStudiesPlans().iterator().next();
                JSONObject studiesPlanObj;
                if(studiesPlan.getJson() != null)
                {
                    CursoImpl c = CursoImpl.loadFromJson(studiesPlan.getJson());
                    autoFillTotalHorasContacto(c);
                    studiesPlanObj = c.toJsonObjectJsonApiWS();
                    studiesPlanObj.put("version",studiesPlan.getVersion());
                    coursesResponse.put("courseStudiesPlan",studiesPlanObj);
                }
                else
                {
                    studiesPlanObj = new JSONObject();
                    studiesPlanObj.put("fault","Zero contents for this version");
                    studiesPlanObj.put("version",studiesPlan.getVersion());
                    coursesResponse.put("courseStudiesPlan",studiesPlanObj);
                }
                coursesResponse.put("courseStudiesPlan",studiesPlanObj);

            }
            else
            {
                coursesResponse.put("status","JSON NOT EXIST FOR STUDIES PLAN IN THIS COURSE");
            }
        }
        else
        {
            coursesResponse.put("status","JSON NOT EXIST FOR COURSE, PLEASE OPEN AND SAVE COURSE IN ADMINISTRATION");
        }
        return coursesResponse;
    }

    /**
     * @SERVICE@
     *
     * @param code
     * @return
     * @throws JSONException
     */

    public 1.5.0/docs/api/java/lang/String.html">String getCourseStudiesPlanXml(1.5.0/docs/api/java/lang/String.html">String code,1.5.0/docs/api/java/lang/String.html">String renew) throws JSONException {

        Course course = DaoFactory.getCourseDaoImpl().findCourseByCode(code);

        if(renew != null || course.getStudiesPlans() == null || course.getStudiesPlans().size() == 0)
        {
            logger.info("status JSON NOT EXIST FOR STUDIES PLAN IN THIS COURSE, will generate");
            UserSession userSession = DomainObjectFactory.createUserSessionImpl();
            userSession.setUser(DaoFactory.getUserDaoImpl().load(new 1.5.0/docs/api/java/lang/Long.html">Long(1)));
            try {
                generateXmlJaxbStudiesPlanVersionFromRepositoryOldPlanStream(userSession, course, false, null);
            } catch (JAXBException e) {
                logger.error(e,e);
                return "<error>" + e.toString() + ". see log for details</error>";
            }
        }
       
        if(course.getStudiesPlans() != null && course.getStudiesPlans().size() > 0)
        {
            return course.getStudiesPlans().iterator().next().getXml();
        }
        return "<error>Does not exixt</error>";

    }


    /**
     * @SERVICE@
     *
     * @param systemUrl
     * @param setActive
     * @return
     * @throws IOException
     * @throws JSONException
     * @throws JAXBException
     */


    public 1.5.0/docs/api/java/lang/String.html">String sincronizeCoursesStudiesPlans(1.5.0/docs/api/java/lang/String.html">String systemUrl,boolean setActive,UserSession sess) throws 1.5.0/docs/api/java/io/IOException.html">IOException, JSONException, JAXBException {

        1.5.0/docs/api/java/lang/StringBuilder.html">StringBuilder log = new 1.5.0/docs/api/java/lang/StringBuilder.html">StringBuilder();
        1.5.0/docs/api/java/net/URL.html">URL url = new 1.5.0/docs/api/java/net/URL.html">URL(systemUrl + "/wsjson/api?service=listCourses");
        5+0%2Fdocs%2Fapi+InputStream">InputStream is = url.openStream();
        1.5.0/docs/api/java/lang/String.html">String str = StreamsUtils.readString(is);
        JSONObject obj = new JSONObject(str);
        JSONArray courses = obj.getJSONArray("courses");
        for(int i = 0; i < courses.length();i++)
        {
            1.5.0/docs/api/java/lang/String.html">String code = "";
            try{
                JSONObject course = courses.getJSONObject(i);
                code = course.getString("code");
                Course c = DaoFactory.getCourseDaoImpl().findCourseByCode(code);
                if(c == null)
                {
                    1.5.0/docs/api/java/lang/String.html">String msg = "SKIPING - Course " + code + " " + course.getString("name") + " does not exist in this system";
                    log.append("<info>" + msg+"</info>");
                    logger.info(msg);
                }
                else
                {
                    1.5.0/docs/api/java/lang/String.html">String msg = "UPDATING - Course " + code + " " + course.getString("name") + " exist in this system";
                    log.append("<info>" + msg+"</info>");
                    logger.info(msg);

                    //#############UPDATING Course Comission Members
                    updateCourseComissionMembersAndCourseInfo(systemUrl, code, c);

                    //#############UPDATING STUDIES PLAN
                    updateStudiesPlanFromRemoteSystem(systemUrl, setActive, log, course, code, c);


                }
            }
            catch(1.5.0/docs/api/java/lang/Throwable.html">Throwable e)
            {
                logger.error("UPDATE COURSE: " + i + " code: " + code + " FAILED");
                logger.error(e,e);
            }
        }
        return log.toString();

    }

    private void updateStudiesPlanFromRemoteSystem(1.5.0/docs/api/java/lang/String.html">String systemUrl, boolean setActive, 1.5.0/docs/api/java/lang/StringBuilder.html">StringBuilder log, JSONObject course, 1.5.0/docs/api/java/lang/String.html">String code, Course c) throws 1.5.0/docs/api/java/io/IOException.html">IOException, JSONException, JAXBException {
        1.5.0/docs/api/java/lang/String.html">String msg;
        5+0%2Fdocs%2Fapi+InputStream">InputStream stream = new 1.5.0/docs/api/java/net/URL.html">URL(systemUrl + "/wsjson/api?service=getStudiesPlanXml&code=" + code + "&renew=true").openStream();
        1.5.0/docs/api/java/lang/String.html">String studiesPlan = StreamsUtils.readString(stream);
        int len = studiesPlan.length();
        if(studiesPlan == null || studiesPlan.trim().length() == 0 || studiesPlan.contains("<error>"))
        {
            msg = "Course " + code + " " + course.getString("name") + " dont has studies plan";
            log.append("<warn>" + msg+"</warn>");
            logger.warn(msg);
        }
        else
        {
            msg = "Found studies plan for "  + code + " " + course.getString("name") + " will update ";
            log.append("<info>" + msg+"</info>");
            logger.info(msg);
            if(setActive)
            {
                msg = "Setting course to active";
                log.append("<info>" + msg+"</info>");
                logger.info(msg);
                c.setStatus(true);
            }
            //System.out.println(studiesPlan);
            msg = "GENERATING COURSE JSON ....";
            log.append("<info>" + msg+"</info>");
            logger.info(msg);
            new CoursesService().generateCourseJson(c);

            msg="GENERATING COURSE STUDIES PLAN JSON ....";
            log.append("<info>" + msg+"</info>");
            logger.info(msg);
            stream.close();
            stream = new 1.5.0/docs/api/java/net/URL.html">URL(systemUrl + "/wsjson/api?service=getStudiesPlanXml&code=" + code).openStream();
            UserSession userSession = DomainObjectFactory.createUserSessionImpl();
            userSession.setUser(DaoFactory.getUserDaoImpl().load(new 1.5.0/docs/api/java/lang/Long.html">Long(1)));
            new CoursesService().uploadStudiesPlan(stream, "curso_" + code + ".xml", len,"appication/xml", userSession,c,true,systemUrl);
        }
    }


    /**
     * Update courseComission Members
     * @param systemUrl
     * @param code
     * @param c
     * @throws IOException
     * @throws JSONException
     */

    private void updateCourseComissionMembersAndCourseInfo(1.5.0/docs/api/java/lang/String.html">String systemUrl, 1.5.0/docs/api/java/lang/String.html">String code, Course c) throws 1.5.0/docs/api/java/io/IOException.html">IOException, JSONException
    {

        1.5.0/docs/api/java/net/URL.html">URL urlCourseDetails = new 1.5.0/docs/api/java/net/URL.html">URL(systemUrl + "/wsjson/api?service=getCourse&code=" + code);
        5+0%2Fdocs%2Fapi+InputStream">InputStream isCourseDetails = urlCourseDetails.openStream();
        1.5.0/docs/api/java/lang/String.html">String strCourseDetails = StreamsUtils.readString(isCourseDetails);
        JSONObject objCourseDetails = new JSONObject(strCourseDetails);

        //DEPARTMENT
        JSONObject department = objCourseDetails.getJSONObject("courseInfo").getJSONObject("department");
        if(department != null)
        {
            1.5.0/docs/api/java/lang/String.html">String sigla = department.getString("sigla");
            if(sigla != null)
            {
                CourseDepartment department1 =  DaoFactory.getCourseDepartmentDaoImpl().findBySigla(sigla);
                if(department1 != null)
                {
                    c.setDepartment(department1);
                }
            }
        }


        1.5.0/docs/api/java/lang/String.html">String validationRole = objCourseDetails.getJSONObject("courseInfo").getString("validationRole");




        if(validationRole == null)
        {
            logger.info("validationRole is not defined");
        }
        else
        {
            logger.info("found validationRole: " + validationRole);
            c.setValidationRole(validationRole);

            JSONObject coordinator = objCourseDetails.getJSONObject("courseInfo").getJSONObject("coordinator");
            JSONArray courseComission = objCourseDetails.getJSONObject("courseInfo").getJSONArray("courseComission");

            Teacher coordinatorPersistent = findPersonFromCourseDetails(coordinator);
            if(coordinatorPersistent == null)
            {
                logger.warn("Coordinator does not exist in this system ");
            }
            else
            {
                c.setCoordinator(coordinatorPersistent);
            }

            List<User> users = DaoFactory.getUserDaoImpl().loadRoleUsers(validationRole);
            logger.info("Encontrados " + users.size() + " docentes com o papel de comissao " + validationRole + " vai remover");
            for(User u: users)
            {
                logger.info("Removendo role a " + u.getName());
                u.removeRole(validationRole);
            }

            for(int j = 0 ; j < courseComission.length(); j++)
            {
                JSONObject memberComission = courseComission.getJSONObject(j);
                Teacher memberPersistent = findPersonFromCourseDetails(memberComission);
                if(memberPersistent == null)
                {
                    logger.info("Member does not exist in this system ");
                }
                else
                {
                    logger.info("Adding role of course comission member");
                    if(!memberPersistent.hasRole(validationRole))
                    {
                        memberPersistent.addRole(validationRole);
                    }
                }
            }
        }
    }

    private Teacher findPersonFromCourseDetails(JSONObject coordinator) {
        int code;
        try {
            if(coordinator.has("sigesCode"))
            {
                code = coordinator.getInt("sigesCode");
            }
            else
            {
                logger.warn("there is no sigesCode for this person " + coordinator.toString());
                return null;
            }
        } catch (JSONException e){
            return null;
        } catch (1.5.0/docs/api/java/lang/NumberFormatException.html">NumberFormatException e){
            return null;
        }
        return DaoFactory.getTeacherDaoImpl().loadBySigesCode(code);
    }



    /*
     * Studies Plans Administration Services
     *
     */

    public void addNewStudiesPlan(long courseId,CourseStudiesPlan studiesPlan,UserSession session)
    {
        Course c = DaoFactory.getCourseDaoImpl().load(courseId);
        studiesPlan.setCourse(c);
        c.getStudiesPlans().add(studiesPlan);
        DaoFactory.getCourseStudiesPlanDaoImpl().save(studiesPlan);
    }

    public CourseStudiesPlanImpl cloneVersionFrom(long sourcePlanId, long targetPlanId, long courseId, UserSession session)
    {
        Course course = DaoFactory.getCourseDaoImpl().load(courseId);
        CourseStudiesPlan source = null;
        CourseStudiesPlan target = null;
        for(CourseStudiesPlan plan: course.getStudiesPlans())
        {
            if(plan.getId() == sourcePlanId)
                source = plan;
            else if(plan.getId() == targetPlanId)
                target = plan;
        }
        target.setXml(source.getXml());
        target.setJson(source.getJson());
        return (CourseStudiesPlanImpl) DaoFactory.getCourseStudiesPlanDaoImpl().narrow(target);
    }

    public Curso loadCursoPlanoFromXml(1.5.0/docs/api/java/lang/String.html">String xml)
    {
        try {
            if(xml != null)
            {
                JAXBContext jc = JAXBContext.newInstance(Curso.class);
                Unmarshaller unmarshaller = jc.createUnmarshaller();
                Curso curso = (Curso) unmarshaller.unmarshal(new 1.5.0/docs/api/java/io/StringReader.html">StringReader(xml));
                return curso;
            }
            return null;
        } catch (JAXBException e) {
            logger.error(e,e);
            return null;
        }
    }

    /**
     * Persist the edited studies plan
     * Updates studiesPlanVersion
     * Updates studiesPlanVersionDescription
     * Updates PlanoEstudos XML and JSON
     * TODO REVER
     * @param courseId
     * @param coursePlanId
     * @param planoEditado
     * @param courseStudiesPlanEditado
     * @return
     */

    public Course savePlanoEstudosEditado(long courseId, long coursePlanId, Curso planoEditado, CourseStudiesPlan courseStudiesPlanEditado,UserSession session)
    {
        try {
            Course course = DaoFactory.getCourseDaoImpl().load(courseId);

            for(CourseStudiesPlan courseStudiesPlanPersistente: course.getStudiesPlans())
            {
                if(courseStudiesPlanPersistente.getId() == coursePlanId)
                {
                    courseStudiesPlanPersistente.setVersion(courseStudiesPlanEditado.getVersion());
                    courseStudiesPlanPersistente.setVersionDescription(courseStudiesPlanEditado.getVersionDescription());

                    //REMOVED UNIDADES TO REMOVE
                    for(Curso.Semestre semestre:planoEditado.getSemestre())
                    {
                        Iterator<UnidadeType> uIter = semestre.getUnidade().iterator();
                        while(uIter.hasNext())
                        {
                            UnidadeType unidade = uIter.next();
                            if(unidade.getRemoved() != null && unidade.getRemoved().equals("true"))
                                uIter.remove();
                        }
                        for(Curso.Semestre.Perfil perfil: semestre.getPerfil())
                        {
                            Iterator<UnidadeType> uIter2 = perfil.getUnidade().iterator();
                            while(uIter2.hasNext())
                            {
                                UnidadeType unidade = uIter2.next();
                                if(unidade.getRemoved() != null && unidade.getRemoved().equals("true"))
                                    uIter2.remove();
                            }
                        }
                    }
                    //Garante-se mas depois não vai para o JSON
                    planoEditado.setSiges(course.getCode());//GARANTIR QUE O CODIGO SIGEST ESTA CORRECTO
                    planoEditado.setNome(course.getName());
                    planoEditado.setDep(course.getArea());

                    /**
                     * Calcula automaticamente as horas de contacto totais
                     */

                    autoFillTotalHorasContacto(planoEditado);

                    //planoEditado.setDepDesc("");
                    //planoEditado.setDepDescEn("");
                    //planoEditado.setDepDescEs("");
                    //planoEditado.setDepDescFr("");
                    JAXBContext jc = JAXBContext.newInstance(Curso.class);
                    Marshaller marshaller = jc.createMarshaller();
                    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
                    1.5.0/docs/api/java/io/StringWriter.html">StringWriter xml = new 1.5.0/docs/api/java/io/StringWriter.html">StringWriter();
                    marshaller.marshal(planoEditado,xml);

                    courseStudiesPlanPersistente.setXml(xml.toString());
                    1.5.0/docs/api/java/lang/String.html">String json = CursoImpl.getGensonPlanoEstudosParaApiJsonWS().serialize(planoEditado);
                    //SETTING JSON in COURSE STUDIES PLAN
                    courseStudiesPlanPersistente.setJson(json);
                    break;
                }
            }
            return course;
        } catch (JAXBException e) {
            logger.error(e,e);
            return null;
        }
    }

    private void autoFillTotalHorasContacto(Curso planoEditado) {
        if(planoEditado.getSemestre() != null)
        {
            for(Curso.Semestre s : planoEditado.getSemestre())
            {
                if(s.getUnidade() != null)
                {
                    for(UnidadeType u : s.getUnidade())
                    {
                        u.setTotalHorasContacto(UnidadeImpl.calculateTotalHorasContacto(u.getHorasContacto()));
                    }
                }
                if(s.getPerfil() != null)
                {
                    for(Curso.Semestre.Perfil p : s.getPerfil())
                    {
                        if(p.getUnidade() != null)
                        {
                            for(UnidadeType u : p.getUnidade())
                            {
                                u.setTotalHorasContacto(UnidadeImpl.calculateTotalHorasContacto(u.getHorasContacto()));
                            }
                        }
                    }
                }
            }
        }
    }

    public void generateFreshJsonPlanosEstudosFromXml(UserSession session)
    {
        List<CourseStudiesPlan> coursePlans = DaoFactory.getCourseStudiesPlanDaoImpl().findAll();
        for(CourseStudiesPlan courseStudiesPlanPersistente: coursePlans)
        {
            try
            {
                logger.info("Generating JSON for " + courseStudiesPlanPersistente.getCourse().getName() + " version: " + courseStudiesPlanPersistente.getVersion());
                Curso cursoPlano = loadCursoPlanoFromXml(courseStudiesPlanPersistente.getXml());
                if(cursoPlano != null)
                {
                    for(Curso.Semestre s : cursoPlano.getSemestre())
                    {
                        SemestreImpl.setDescriptionsDefaults(s);
                    }
                    //send to XML again
                    JAXBContext jc = JAXBContext.newInstance(Curso.class);
                    Marshaller marshaller = jc.createMarshaller();
                    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
                    1.5.0/docs/api/java/io/StringWriter.html">StringWriter xml = new 1.5.0/docs/api/java/io/StringWriter.html">StringWriter();
                    marshaller.marshal(cursoPlano,xml);
                    courseStudiesPlanPersistente.setXml(xml.toString());
                    1.5.0/docs/api/java/lang/String.html">String json = CursoImpl.getGensonPlanoEstudosParaApiJsonWS().serialize(cursoPlano);
                    //SETTING JSON in COURSE STUDIES PLAN
                    courseStudiesPlanPersistente.setJson(json);
                }

            }
            catch(1.5.0/docs/api/java/lang/Throwable.html">Throwable e)
            {
                logger.error(e,e);
            }
        }

        logger.info("GENERATING JSON FOR CLASS COURSE");
        for(Course course: DaoFactory.getCourseDaoImpl().findAll())
        {
            try {
                logger.info("generating json for course: " + course.getName() + " (" + course.getCode() + ")");
                generateCourseJson(course);
            } catch (1.5.0/docs/api/java/io/IOException.html">IOException e) {
                logger.error(e,e);
            }
        }
    }



    public List<CourseDepartment> loadDepartments()
    {
        List<CourseDepartment> departments = DaoFactory.getCourseDepartmentDaoImpl().findAll();
        for(CourseDepartment dep: departments)
            dep.getName();
        return departments;

    }


    public Teacher addTeacherCommission(1.5.0/docs/api/java/lang/String.html">String teacherId,1.5.0/docs/api/java/lang/String.html">String courseId, UserSession session)
    {
        Course course = DaoFactory.getCourseDaoImpl().load(new 1.5.0/docs/api/java/lang/Long.html">Long(courseId));
        Teacher t = DaoFactory.getTeacherDaoImpl().load(new 1.5.0/docs/api/java/lang/Long.html">Long(teacherId));
        t.addRole(course.getValidationRole());
        return t;
    }

    public Teacher removeTeacherCommission(1.5.0/docs/api/java/lang/String.html">String teacherId,1.5.0/docs/api/java/lang/String.html">String courseId, UserSession session)
    {
        Course course = DaoFactory.getCourseDaoImpl().load(new 1.5.0/docs/api/java/lang/Long.html">Long(courseId));
        Teacher t = DaoFactory.getTeacherDaoImpl().load(new 1.5.0/docs/api/java/lang/Long.html">Long(teacherId));
        t.removeRole(course.getValidationRole());
        return t;
    }


    public static void main(1.5.0/docs/api/java/lang/String.html">String[] args)
    {
        AbstractDao.getCurrentSession().beginTransaction();
        new CoursesService().generateFreshJsonPlanosEstudosFromXml(null);
        AbstractDao.getCurrentSession().getTransaction().commit();
    }

    public StudiesPlanImporter importStudiesPlanVersionFromFile(5+0%2Fdocs%2Fapi+InputStream">InputStream stream, 1.5.0/docs/api/java/lang/Long.html">Long studiesPlanId, UserSession session) throws 1.5.0/docs/api/java/io/IOException.html">IOException
    {
        StudiesPlanImporter importer = new StudiesPlanImporter();
        importer.parseFile(stream);
        1.5.0/docs/api/java/lang/System.html">System.out.println(importer.getLog());
        CourseStudiesPlan plan = DaoFactory.getCourseStudiesPlanDaoImpl().load(studiesPlanId);
        plan.setImportLog(importer.getLog());
        return importer;
    }
    public StudiesPlanImporter mergeStudiesPlanVersionFromFile(5+0%2Fdocs%2Fapi+InputStream">InputStream stream, 1.5.0/docs/api/java/lang/Long.html">Long studiesPlanId, UserSession session) throws 1.5.0/docs/api/java/io/IOException.html">IOException
    {
        StudiesPlanImporter importer = new StudiesPlanImporter();
        importer.parseFile(stream);
        1.5.0/docs/api/java/lang/System.html">System.out.println(importer.getLog());
        CourseStudiesPlan plan = DaoFactory.getCourseStudiesPlanDaoImpl().load(studiesPlanId);
        plan.setImportLog(plan.getImportLog() + "\n\n############\n\n##MERGING\n\n" + importer.getLog());
        return importer;
    }

    public ReplaceRoleResult createRoleCourseComission(long courseId,UserSession userSession) throws AccessDeniedException
    {
        Course c = DaoFactory.getCourseDaoImpl().load(courseId);
        1.5.0/docs/api/java/lang/String.html">String normalizedName = StringsUtils.getNormalizedNameSafeforCode(c.getName());
        if(normalizedName == null)
            throw new 1.5.0/docs/api/java/lang/RuntimeException.html">RuntimeException("Erro o curso " + c.getId() +" + nao tem nome");
        1.5.0/docs/api/java/lang/String.html">String roleValidation = "courseValidateProgram" + normalizedName;
        UserRoleConfigImpl newUserRoleConfig = DomainObjectFactory.createUserRoleConfigImpl();
        newUserRoleConfig.setRole(roleValidation);
        newUserRoleConfig.setValid(true);
        newUserRoleConfig.setValue("Comissão de Curso de " + c.getName());
        newUserRoleConfig.setValuePt("Comissão de Curso de " + c.getName());
        newUserRoleConfig.setValueEn("");
        newUserRoleConfig.setValueEs("");
        newUserRoleConfig.setValueFr("");

        try {

            ReplaceRoleResult result;
            if(c.getValidationRole() == null || c.getValidationRole().trim().length() == 0)
            {
                result = new  UserRoleConfigService().addUpdateRole(newUserRoleConfig,userSession,false);
            }
            else
            {
                1.5.0/docs/api/java/lang/String.html">String oldValidationRole = c.getValidationRole();
                result = new  UserRoleConfigService().updateOldRoleWithView(oldValidationRole, newUserRoleConfig, userSession,false);
            }


            if(result.roleKeyAlreadyExist)
            {
                logger.error("Tentado CRIAR um Role que já existe e não é Administrador nem Super user");
                throw new AccessDeniedException("Tentado CRIAR um Role que já existe e não é Administrador nem Super user");
            }
            c.setValidationRole(roleValidation);
            return result;
        } catch (AccessDeniedException e) {
            logger.error("Tentado alterar um Role e não é Administrador nem Super user");
            throw e;
        }
    }



    public Teacher changeCoordinator(long teacherId,long courseId,UserSession userSession)
    {
        Course c = DaoFactory.getCourseDaoImpl().load(courseId);
        Teacher t = DaoFactory.getTeacherDaoImpl().load(teacherId);
        c.setCoordinator(t);
        t = DaoFactory.getTeacherDaoImpl().narrow(t);
        return t;
    }

    public CourseDepartmentImpl updateDepartmentFromJson(1.5.0/docs/api/java/lang/String.html">String json,UserSession session) throws 1.5.0/docs/api/java/io/IOException.html">IOException
    {
        CourseDepartmentImpl courseDepartment = CourseDepartmentImpl.loadFromJson(json);
        CourseDepartmentImpl courseDepartmentPersistent = (CourseDepartmentImpl) DaoFactory.getCourseDepartmentDaoImpl().load(courseDepartment.getSigla());
        if(!courseDepartment.getSiglaNova().equals(courseDepartment.getSigla()))
            courseDepartmentPersistent.setSigla(courseDepartment.getSiglaNova());
        //courseDepartmentPersistent.setSigla(courseDepartment.getSigla());
        courseDepartmentPersistent.setActive(courseDepartment.isActive());
        courseDepartmentPersistent.setName(courseDepartment.getName());
        courseDepartmentPersistent.setNameEs(courseDepartment.getNameEs());
        courseDepartmentPersistent.setNameEn(courseDepartment.getNameEs());
        courseDepartmentPersistent.setNameFr(courseDepartment.getNameFr());
        //courseDepartmentPersistent.setInstitutionalCode(courseDepartment.getInstitutionalCode());
        courseDepartmentPersistent.setBoardRole(courseDepartment.getBoardRole());
        courseDepartmentPersistent.setDirectorRole(courseDepartment.getDirectorRole());
        if(courseDepartment.getCourseSchool() != null && courseDepartment.getCourseSchool().getId() > 0)
        {
            CourseSchoolImpl courseSchool = (CourseSchoolImpl) DaoFactory.getCourseSchoolDaoImpl().load(courseDepartment.getCourseSchool().getId());
            courseDepartmentPersistent.setCourseSchool(courseSchool);
        }
        else
            courseDepartmentPersistent.setCourseSchool(null);
        return courseDepartmentPersistent;

    }

    public CourseDepartmentImpl removeDepartmentFromJson(1.5.0/docs/api/java/lang/String.html">String json,UserSession session) throws 1.5.0/docs/api/java/io/IOException.html">IOException
    {
        CourseDepartmentImpl courseDepartment = CourseDepartmentImpl.loadFromJson(json);
        CourseDepartmentImpl courseDepartmentPersistent = (CourseDepartmentImpl) DaoFactory.getCourseDepartmentDaoImpl().load(courseDepartment.getSigla());
        DaoFactory.getCourseDepartmentDaoImpl().delete(courseDepartmentPersistent);
        return courseDepartmentPersistent;

    }

    public CourseDepartmentImpl newDepartmentFromJson(UserSession session) throws 1.5.0/docs/api/java/io/IOException.html">IOException
    {
        CourseDepartmentImpl courseDepartmentPersistent = DomainObjectFactory.createCourseDepartmentImpl();

        courseDepartmentPersistent.setSigla(BytesUtils.generateKey().substring(0,10));
        courseDepartmentPersistent.setSiglaNova(courseDepartmentPersistent.getSigla());
        courseDepartmentPersistent.setActive(false);
        DaoFactory.getCourseDepartmentDaoImpl().save(courseDepartmentPersistent);
        return courseDepartmentPersistent;

    }


    public CourseSchoolImpl updateSchoolFromJson(1.5.0/docs/api/java/lang/String.html">String json,UserSession session) throws 1.5.0/docs/api/java/io/IOException.html">IOException
    {
        CourseSchoolImpl courseSchool = CourseSchoolImpl.loadFromJson(json);
        CourseSchoolImpl courseSchoolPersistent = (CourseSchoolImpl) DaoFactory.getCourseSchoolDaoImpl().load(courseSchool.getId());

        courseSchoolPersistent.setActive(courseSchool.isActive());
        courseSchoolPersistent.setName(courseSchool.getName());
        courseSchoolPersistent.setNameEs(courseSchool.getNameEs());
        courseSchoolPersistent.setNameEn(courseSchool.getNameEs());
        courseSchoolPersistent.setNameFr(courseSchool.getNameFr());
        courseSchoolPersistent.setInstitutionalCode(courseSchool.getInstitutionalCode());
        courseSchoolPersistent.setInitials(courseSchool.getInitials());

        courseSchoolPersistent.setSchoolDirectorRole(courseSchool.getSchoolDirectorRole());
        courseSchoolPersistent.setSchoolBoardRole(courseSchool.getSchoolBoardRole());
        courseSchoolPersistent.setSchoolSecretariadoRole(courseSchool.getSchoolSecretariadoRole());

        courseSchoolPersistent.setCtcPresidentRole(courseSchool.getCtcPresidentRole());
        courseSchoolPersistent.setCtcMemberRole(courseSchool.getCtcMemberRole());
        courseSchoolPersistent.setCtcSecretariadoRole(courseSchool.getCtcSecretariadoRole());

        courseSchoolPersistent.setPedagogicoPresidentRole(courseSchool.getPedagogicoPresidentRole());
        courseSchoolPersistent.setPedagogicoMemberRole(courseSchool.getPedagogicoMemberRole());
        courseSchoolPersistent.setPedagogicoSecretariadoRole(courseSchool.getPedagogicoSecretariadoRole());

        courseSchoolPersistent.setFuncionarioRole(courseSchool.getFuncionarioRole());
        courseSchoolPersistent.setTeacherRole(courseSchool.getTeacherRole());
        courseSchoolPersistent.setStudentRole(courseSchool.getStudentRole());

        return courseSchoolPersistent;

    }

    public CourseSchoolImpl newSchoolFromJson(UserSession session) throws 1.5.0/docs/api/java/io/IOException.html">IOException
    {
        CourseSchoolImpl courseSchoolPersistent = DomainObjectFactory.createCourseSchoolImpl();

        courseSchoolPersistent.setActive(false);
        DaoFactory.getCourseSchoolDaoImpl().save(courseSchoolPersistent);
        return courseSchoolPersistent;

    }

    public CourseSchoolImpl removeSchoolFromJson(1.5.0/docs/api/java/lang/String.html">String json,UserSession session) throws 1.5.0/docs/api/java/io/IOException.html">IOException
    {
        CourseSchoolImpl courseSchool = CourseSchoolImpl.loadFromJson(json);
        CourseSchoolImpl courseSchoolPersistent = (CourseSchoolImpl) DaoFactory.getCourseSchoolDaoImpl().load(courseSchool.getId());
        DaoFactory.getCourseSchoolDaoImpl().delete(courseSchoolPersistent);
        return courseSchoolPersistent;

    }

    /*
    public static void main(String[] args) throws JAXBException, IOException {

        String json = "{\"anoPlanoSiges\":null,\"codigoPlanoSiges\":null,\"dep\":null,\"descPlanoSiges\":null,\"nome\":null,\"semestre\":[{\"id\":\"S1\",\"notas\":null,\"perfil\":[],\"semestreDesc\":\"Semestre 1\",\"semestreDescEn\":\"Semester 1\",\"semestreDescEs\":\"Semestre 1\",\"semestreDescFr\":\"Semestre 1\",\"semestreId\":null,\"unidade\":[{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Português — Língua e Literatura\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"150\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:12\",\"horasContacto\":{\"tP\":\"60\",\"oT\":\"15\"},\"eCTS\":\"6\"},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Geografia\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"125\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:16\",\"horasContacto\":{\"tP\":\"45\",\"oT\":\"15\"},\"eCTS\":\"5\"},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"História\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"125\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:20\",\"horasContacto\":{\"tP\":\"45\",\"oT\":\"15\"},\"eCTS\":\"5\"},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Linguística e Análise do Discurso\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"150\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:24\",\"horasContacto\":{\"tP\":\"60\",\"oT\":\"15\"},\"eCTS\":\"6\"},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Matemática no 1.o Ciclo do Ensino Básico\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"125\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:28\",\"horasContacto\":{\"tP\":\"45\",\"oT\":\"15\"},\"eCTS\":\"5\"},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Educação para a Saúde\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"75\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:32\",\"horasContacto\":{\"tP\":\"30\",\"oT\":\"7\"},\"eCTS\":\"3\"},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Música, Emoção e Criatividade\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"75\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:36\",\"horasContacto\":{\"tP\":\"30\",\"oT\":\"7\"},\"eCTS\":\"3\"},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Educação para a Cidadania\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"75\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:40\",\"horasContacto\":{\"tP\":\"30\",\"oT\":\"7\"},\"eCTS\":\"3\"},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Descobrir a Matemática\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"75\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:44\",\"horasContacto\":{\"tP\":\"30\",\"oT\":\"7\"},\"eCTS\":\"3\"}],\"type\":\"semestre\",\"$$hashKey\":\"object:6\"},{\"id\":\"S2\",\"notas\":null,\"perfil\":[],\"semestreDesc\":\"Semestre 1\",\"semestreDescEn\":\"Semester 1\",\"semestreDescEs\":\"Semestre 1\",\"semestreDescFr\":\"Semestre 1\",\"semestreId\":null,\"unidade\":[{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Didática do Português no 1º Ciclo do Ensino Básico\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"150\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:54\",\"eCTS\":\"6\",\"horasContacto\":{\"tP\":\"60\",\"oT\":\"15\"}},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Didática do Estudo do Meio no 1º Ciclo do Ensino Básico\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"150\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:58\",\"eCTS\":\"6\",\"horasContacto\":{\"tP\":\"60\",\"oT\":\"15\"}},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Didática da Matemática no 1º Ciclo do Ensino Básico\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"150\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:62\",\"eCTS\":\"6\",\"horasContacto\":{\"tP\":\"60\",\"oT\":\"15\"}},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Didática das Expressões no 1º Ciclo do Ensino Básico\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"150\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:66\",\"eCTS\":\"6\",\"horasContacto\":{\"tP\":\"60\",\"oT\":\"15\"}},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Psicologia da Educação\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"75\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:70\",\"eCTS\":\"3\",\"horasContacto\":{\"tP\":\"30\",\"oT\":\"7\"}},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Investigação em Educação\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"75\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:74\",\"eCTS\":\"3\",\"horasContacto\":{\"tP\":\"30\",\"oT\":\"7\"}}],\"type\":\"semestre\",\"$$hashKey\":\"object:48\"},{\"id\":\"S3\",\"notas\":null,\"perfil\":[],\"semestreDesc\":\"Semestre 1\",\"semestreDescEn\":\"Semester 1\",\"semestreDescEs\":\"Semestre 1\",\"semestreDescFr\":\"Semestre 1\",\"semestreId\":null,\"unidade\":[{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Prática de Ensino Supervisionada no 1º Ciclo do Ensino Básico\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"500\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:90\",\"eCTS\":\"20\",\"horasContacto\":{\"s\":\"30\",\"e\":\"270\",\"oT\":\"45\"}},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Seminário de Investigação I\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"50\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:98\",\"eCTS\":\"2\",\"horasContacto\":{\"s\":\"20\",\"oT\":\"10\"}},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Didática da História e Geografia de Portugal no 2º Ciclo do  Ensino Básico\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"100\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:94\",\"eCTS\":\"4\",\"horasContacto\":{\"tP\":\"35\",\"oT\":\"15\"}},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"Didática do Português no 2º Ciclo do Ensino Básico\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":\"100\",\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:102\",\"eCTS\":\"4\",\"horasContacto\":{\"oT\":\"15\",\"tP\":\"35\"}}],\"type\":\"semestre\",\"$$hashKey\":\"object:78\"},{\"id\":\"S4\",\"notas\":null,\"perfil\":[],\"semestreDesc\":\"Semestre 1\",\"semestreDescEn\":\"Semester 1\",\"semestreDescEs\":\"Semestre 1\",\"semestreDescFr\":\"Semestre 1\",\"semestreId\":null,\"unidade\":[{\"dep\":\"\",\"ects\":\"\",\"nome\":\"\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":0,\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:106\"},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":0,\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:110\"},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":0,\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:114\"},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":0,\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:118\"},{\"dep\":\"\",\"ects\":\"\",\"nome\":\"\",\"nomeEn\":null,\"nomeEs\":null,\"nomeFr\":null,\"obs\":\"\",\"removed\":null,\"siges\":null,\"totalHoras\":0,\"urlFichaCurricular\":\"\",\"urlUnidadeCurricular\":\"\",\"type\":\"unidade\",\"$$hashKey\":\"object:122\"}],\"type\":\"semestre\",\"$$hashKey\":\"object:84\"}],\"siges\":null}";
        CursoImpl c = CursoImpl.loadFromJson(json);

        JAXBContext jc = JAXBContext.newInstance(Curso.class);
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        StringWriter xml = new StringWriter();
        marshaller.marshal(c,xml);
        System.out.println(xml);
    }*/



}