/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package ee.tlu.htk.dippler.course; import ee.tlu.htk.dippler.backoffice.StatusCodes; import ee.tlu.htk.dippler.entities.Course; import ee.tlu.htk.dippler.entities.Coursegroup; import ee.tlu.htk.dippler.entities.Learner; import ee.tlu.htk.dippler.entities.Organization; import ee.tlu.htk.dippler.entities.User; import ee.tlu.htk.dippler.entities.Profile; import ee.tlu.htk.dippler.managers.ProfileManagerLocal; import ee.tlu.htk.dippler.managers.UserManagerLocal; import ee.tlu.htk.dippler.utils.XMLHandler; import ee.tlu.htk.dippler.utils.permissionChecker; import java.io.StringReader; import java.util.Collection; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.ejb.EJB; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; /** * * @author metz */ enum LearnerActions { ADD, DELETE, LOAD, ACTIVATE, ENROLL, SEARCH, SAVE_GRADE, LOAD_GRADE } @Stateless public class LearnerManager implements LearnerManagerLocal { @PersistenceContext private EntityManager em; @EJB private UserManagerLocal userManager; @EJB private CourseManagerLocal courseManager; @EJB private GroupManagerLocal groupManager; @EJB private ActivityManagerLocal activityManager; @EJB private ProfileManagerLocal profileManager; @EJB private GradeManagerLocal gradeManager; public static final Integer LEARNER_ADD = 50; public static final Integer LEARNER_DELETE = 50; public static final Integer LEARNER_ACTIVATE = 50; public static final Integer LEARNER_LOAD = 1; public static final Integer LEARNER_ENROLL = 10; public static final Integer LEARNER_SEARCH = 50; public static final Integer GRADE_SAVE = 50; public static final Integer GRADE_LOAD = 10; private Unmarshaller unmarshaller = null; public LearnerManager() { try { final JAXBContext context = JAXBContext.newInstance(Learner.class); unmarshaller = context.createUnmarshaller(); } catch (JAXBException ex) { Logger.getLogger(LearnerManager.class.getName()).log(Level.SEVERE, null, ex); } } @Override public String manageLearner(String action, String data, User user, Organization org) { switch (LearnerActions.valueOf(action)) { case ADD: if (userManager.hasPermission(user, LEARNER_ADD)) { return this.addLearner(data, user); } else { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "No rights for add learner"); } case ENROLL: if (userManager.hasPermission(user, LEARNER_ENROLL)) { return this.enrollLearner(data, user); } else { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "No rights for enroll learner"); } case DELETE: if (userManager.hasPermission(user, LEARNER_DELETE)) { return this.removeLearner(data, user); } else { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "No rights for delete learner"); } case ACTIVATE: if (userManager.hasPermission(user, LEARNER_ACTIVATE)) { return this.editLearner(data, user); } else { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "No rights for activate learner"); } case LOAD: if (userManager.hasPermission(user, LEARNER_LOAD)) { return this.loadLearner(data); } else { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "No rights for load learner"); } case SEARCH: if (userManager.hasPermission(user, LEARNER_SEARCH)) { return this.searchForLearners(data, user, org); } else { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "No rights for search learner"); } case SAVE_GRADE: if (userManager.hasPermission(user, GRADE_SAVE)) { return gradeManager.saveGrade(data, user); } else { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "No rights for save grade"); } case LOAD_GRADE: if (userManager.hasPermission(user, GRADE_LOAD)) { return gradeManager.loadGrade(data, user); } else { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "No rights for load grade"); } default: return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, ""); } } /** * Adds user to course learners, returns XML response. Checks for user being * course facilitator, owner or administrator. * @param data XML string containing marshallable learner data. * @param actor User making the request. * @return A string with response XML. */ public String addLearner(String data, User actor) { Learner learner = unMarshal(data); if ( learner != null ) { Course course = courseManager.findById(learner.getCourseId()); if (!permissionChecker.isFacilitator(actor, course)) { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "Not facilitator or admin"); } User user = userManager.findById(learner.getUser_id()); if ( user != null && course != null ) { // learner.setCourse(course); //learner.setUser(user); // Manually set status to 5 //learner.setStatus(5); //em.persist(learner); course.addLearner(user, 5); activityManager.addActivity("CREATE", course, actor, user.getId(), user.getFullname(), "Learner"); return StatusCodes.respond(StatusCodes.SUCCESS, ""); } } return StatusCodes.respond(StatusCodes.COURSE_ERROR, "Add learner failed"); } public String enrollLearner(String data, User actor) { Learner learner = unMarshal(data); if ( learner != null ) { Course course = courseManager.findById(learner.getCourseId()); if ( course.isActive() && course.getApproved() && course.canApply() ) { if (!isPublicRegistrationOpen(course)) { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "Public registration is not open"); } if ( course != null ) { // learner.setCourse(course); //learner.setUser(actor); // Checking learner status, do not trust the sender int learner_status = 1; int enrollment_status = Integer.parseInt(course.getEnrollment()); if (enrollment_status == 1) { // Learner needs to be activated in case of moderated enrollment // Facilitator will use addLearner not this one learner_status = 1; } else if (enrollment_status == 2) { // Learner is active in case of open enrollment learner_status = 5; } // Set learner status course.addLearner(actor, learner_status); activityManager.addActivity("ENROLL", course, actor, actor.getId(), actor.getFullname(), "Learner"); return StatusCodes.respond(StatusCodes.SUCCESS, ""); } } if ( !course.isActive() ) { return StatusCodes.respond(StatusCodes.COURSE_IS_NOT_ACTIVE, "Course is not active"); } if ( !course.canApply() ) { return StatusCodes.respond(StatusCodes.COURSE_CANNOT_APPLY, "Course apply deadline exceeded"); } } return StatusCodes.respond(StatusCodes.COURSE_ERROR, "Enroll learner failed"); } public String editLearner(String data, User actor) { Learner learner = findByData(data); if ( learner != null ) { Learner l = unMarshal(data); if (!permissionChecker.isOwnerOrAdmin(actor, learner.getCourse().getOwner())) { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "Not owner or admin"); } learner.setStatus(l.getStatus()); User user = learner.getUser(); activityManager.addActivity("ACCEPT", learner.getCourse(), actor, user.getId(), user.getFullname(), "Learner"); return StatusCodes.respondWithData(StatusCodes.SUCCESS, "", marshal(learner)); } return StatusCodes.respond(StatusCodes.COURSE_ERROR, "Edit learner failed"); } //TODO - not called ever public String removeLearner(String data, User actor) { Learner learner = findByData(data); if ( learner != null ) { if (!permissionChecker.isOwnerOrAdmin(actor, learner.getCourse().getOwner())) { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "Not owner or admin"); } User user = learner.getUser(); activityManager.addActivity("DELETE", learner.getCourse(), actor, user.getId(), user.getFullname(), "Learner"); Course course = learner.getCourse(); course.remove(learner); em.remove(learner); return StatusCodes.respond(StatusCodes.SUCCESS, ""); } return StatusCodes.respond(StatusCodes.COURSE_ERROR, "Remove learner failed"); } public String loadLearner(String data) { Learner learner = findByData(data); if ( learner != null ) { return StatusCodes.respondWithData(StatusCodes.SUCCESS, "", marshal(learner)); } return StatusCodes.respond(StatusCodes.COURSE_ERROR, "Not loaded"); } /** * Responds with XML string containing user data. Respects same ogranization * policy, only possible learners from same Organization are returned. * Filters out users that are already learners in the same course. * * @param data XML string containing search term and Course identifier. * @param user User making the request. * @param org Organization session Client belongs to. * @return A string with response XML. */ public String searchForLearners(String data, User user, Organization org) { XMLHandler doc = new XMLHandler(data); if ( doc.parseSuccess() ) { String term = doc.getNodeValue("term"); Course course = courseManager.findById(doc.getNodeValueLong("course")); if ( course != null ) { if (!permissionChecker.isFacilitator(user, course)) { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "Not owner, facilitator or admin"); } Query query = em.createNamedQuery("User.findAvailableLearners"); query.setParameter("term", "%"+term+"%"); query.setParameter("course", course); query.setParameter("organization", org); List users = (List) query.getResultList(); StringBuilder xml = new StringBuilder(""); for(User single : users ) { xml.append("") .append("").append(single.getId().toString()).append("") .append("") .append("") .append(""); } xml.append(""); return StatusCodes.respondWithData(StatusCodes.SUCCESS, "", xml.toString()); } } return StatusCodes.respond(StatusCodes.COURSE_ERROR, ""); } public Learner unMarshal(String data) { if ( unmarshaller != null ) { try { final Learner coursegroupUNM = (Learner) unmarshaller.unmarshal(new StringReader(data)); return coursegroupUNM; } catch(JAXBException e) { //something went wrong } } return null; } @Override public String marshal(Learner learner) { User lu = learner.getUser(); Collection groups = learner.getGroups(); String groups_string = ""; for (Coursegroup group : groups) { groups_string += groupManager.marshal(group); } String blogurl = ""; Profile up = profileManager.findByUserId(lu.getId()); if ( up != null ) { if ( up.getBlogurl() != null ) { blogurl = up.getBlogurl(); } } StringBuilder xml = new StringBuilder(""); xml.append("").append(learner.getId()).append(""); xml.append(""); xml.append(""); xml.append(""); xml.append("").append(learner.getStatus().toString()).append(""); xml.append("").append(learner.getCourse().getId()).append(""); xml.append("").append(groups_string).append(""); xml.append("").append(learner.getUser().getId()).append(""); xml.append(""); xml.append("").append(activityManager.getUserCourseActivityCount(learner.getUser().getId(), learner.getCourse().getId())).append(""); xml.append("").append(activityManager.getUserCourseActivityLastDate(learner.getUser().getId(), learner.getCourse().getId())).append(""); xml.append(""); return xml.toString(); } @Override public Learner findById(Long id) { if ( id != null && id > 0 ) { return em.find(Learner.class, id); } return null; } public Learner findByData(String data) { Learner fake_learner = unMarshal(data); if ( fake_learner != null ) { return em.find(Learner.class, fake_learner.getId()); } return null; } private static Boolean isPublicRegistrationOpen(Course course) { if ( Integer.parseInt(course.getEnrollment()) > 0) { Integer closes = course.getCloses(); if (closes.intValue() > 0) { closes = closes + 86339; // Get the timestamp matching number of seconds since UNIX Epoch long now = System.currentTimeMillis() / 1000L; if ((now <= closes.longValue())) { return Boolean.TRUE; } } else { return Boolean.TRUE; } } return Boolean.FALSE; } }