/* * 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.Answer; import ee.tlu.htk.dippler.entities.Assignment; import ee.tlu.htk.dippler.entities.Course; import ee.tlu.htk.dippler.entities.Learner; import ee.tlu.htk.dippler.entities.User; import ee.tlu.htk.dippler.managers.UserManagerLocal; import ee.tlu.htk.dippler.utils.permissionChecker; import java.io.StringReader; import java.util.Date; 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.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; /** * * @author metz */ enum AnswerActions { CREATE, DELETE, EDIT, LOAD, GRADE } @Stateless public class AnswerManager implements AnswerManagerLocal { @PersistenceContext private EntityManager em; @EJB private UserManagerLocal userManager; @EJB private LearnerManagerLocal learnerManager; @EJB private AssignmentManagerLocal assignmentManager; @EJB private ActivityManagerLocal activityManager; public static final Integer LOAD = 1; public static final Integer CREATE = 10; public static final Integer DELETE = 10; public static final Integer EDIT = 10; public static final Integer GRADE = 50; private Unmarshaller unmarshaller = null; public AnswerManager() { try { final JAXBContext context = JAXBContext.newInstance(Answer.class); unmarshaller = context.createUnmarshaller(); } catch (JAXBException ex) { Logger.getLogger(AnswerManager.class.getName()).log(Level.SEVERE, null, ex); } } @Override public String manageAnswer(String action, String data, User user) { Answer answer = unMarshal(data); if ( answer != null ) { switch (AnswerActions.valueOf(action)) { case CREATE: if (userManager.hasPermission(user, CREATE)) { return this.createAnswer(answer, user); } else { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "No rights for creating answer"); } case EDIT: if (userManager.hasPermission(user, EDIT)) { return this.editAnswer(answer, user); } else { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "No rights for edit answer"); } case DELETE: if (userManager.hasPermission(user, DELETE)) { return this.deleteAnswer(answer, user); } else { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "No rights for delete answer"); } case LOAD: if (userManager.hasPermission(user, LOAD)) { return this.loadAnswer(answer); } else { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "No rights for load answer"); } case GRADE: // access check is done in method, cause automatic tests will be graded automatically (and not by logged in users) return this.gradeAnswer(answer, user); default: return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, ""); } } return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, ""); } public String createAnswer(Answer answer, User user) { System.out.println("CREATE ANSWER"); final Assignment assignment = assignmentManager.findById(answer.getAssignmentId()); if ( assignment != null ) { if ( !assignment.getSubtype().equalsIgnoreCase("test") && !assignment.isSubmissionValid() ) { return StatusCodes.respond(StatusCodes.COURSE_ERROR, "Create failed"); } // if user himself is not creating answer and learner-id is given in xml, then use learner as creator // this is needed for questr Long learner_id = answer.getLearnerId(); Learner learner = learnerManager.findById(learner_id); if (learner != null) { user = learner.getUser(); } // TODO Additional time check is needed if (!permissionChecker.isLearner(user, assignment.getCourse())) { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "Not a learner."); } Answer existing_answer = assignment.getLearnerAnswer(user.getId()); if (existing_answer != null) { // Need to set id to answer object, it might not have any answer.setId(existing_answer.getId()); return this.editAnswer(answer, user); } else { Date dateIn = new Date(); answer.setCreator(user); answer.setCreated(dateIn); answer.setModified(dateIn); answer.setGraded(dateIn); answer.setFeedback(""); answer.setAssignment(assignment); em.persist(answer); // in case of questr (if learner id given), answer objects are created in advance, so nothing should be shown in activity stream if (answer.getLearnerId() == null) { activityManager.addActivity("CREATE", assignment.getCourse(), user, answer.getId(), answer.getTitle(), "Answer"); } return StatusCodes.respondWithData(StatusCodes.SUCCESS, "", marshal(answer)); } } return StatusCodes.respond(StatusCodes.COURSE_ERROR, "Create failed"); } public String loadAnswer(Answer a) { Answer answer = findById(a.getId()); if ( answer != null ) { // TODO Needs check for who can load (see) answer; probably course facilitator (admin, owner and facilitators) and owner return StatusCodes.respondWithData(StatusCodes.SUCCESS, "", marshal(answer)); } return StatusCodes.respond(StatusCodes.COURSE_ERROR, "Not loaded"); } public String gradeAnswer(Answer a, User user) { Answer answer = findById(a.getId()); if ( answer != null ) { Course course = answer.getAssignment().getCourse(); // automatic test answers are graded automatically (so permission check can only be done for other types) if (!answer.getAssignment().getSubtype().equals("test") && !permissionChecker.isFacilitator(user, course)) { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "Not facilitator"); } else if (answer.getAssignment().getSubtype().equals("test")){ Assignment assignment = answer.getAssignment(); activityManager.addActivity("ANSWER", assignment.getCourse(), answer.getCreator(), assignment.getId(), assignment.getTitle(), "Assignment"); } answer.setGrade(a.getGrade()); answer.setFeedback(a.getFeedback()); answer.setGraded(new Date()); return StatusCodes.respondWithData(StatusCodes.SUCCESS, "", marshal(answer)); } return StatusCodes.respond(StatusCodes.COURSE_ERROR, "Grade failed"); } public String editAnswer(Answer a, User user) { Answer answer = findById(a.getId()); if ( answer != null ) { // TODO Additional time check is needed for owner/creator if (!permissionChecker.isFacilitator(user, answer.getAssignment().getCourse()) && !permissionChecker.isOwner(user, answer.getCreator())) { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "Not facilitator, owner or admin"); } answer.setTitle(a.getTitle()); answer.setBackup(answer.getContent()); answer.setContent(a.getContent()); answer.setModified(new Date()); // Reset grade if user overwrites the answer if (answer.getGrade() > 0) { answer.setGrade(0); } activityManager.addActivity("EDIT", answer.getAssignment().getCourse(), user, answer.getId(), answer.getTitle(), "Answer"); return StatusCodes.respondWithData(StatusCodes.SUCCESS, "", marshal(answer)); } return StatusCodes.respond(StatusCodes.COURSE_ERROR, "Edit failed"); } public String deleteAnswer(Answer a, User user) { Answer answer = findById(a.getId()); if ( answer != null ) { if (!permissionChecker.isFacilitator(user, answer.getAssignment().getCourse())) { return StatusCodes.respond(StatusCodes.OPERATION_NOT_ALLOWED, "Not owner or admin"); } em.remove(answer); return StatusCodes.respond(StatusCodes.SUCCESS, ""); } return StatusCodes.respond(StatusCodes.COURSE_ERROR, "Delete failed"); } @Override public Answer unMarshal(String data) { if ( unmarshaller != null ) { try { final Answer answerUNM = (Answer) unmarshaller.unmarshal(new StringReader(data)); return answerUNM; } catch(JAXBException e) { //Something went wrong } } return null; } @Override public String marshal(Answer answer) { StringBuilder xml = new StringBuilder(""); xml.append("").append(answer.getId()).append(""); xml.append("<![CDATA[").append(answer.getTitle()).append("]]>"); xml.append(""); xml.append(""); xml.append("").append(answer.getCreated()).append(""); xml.append("").append(answer.getModified()).append(""); xml.append("").append(answer.getGraded()).append(""); xml.append("").append(answer.getCreator().getId()).append(""); xml.append("").append(answer.getAssignment().getId().toString()).append(""); xml.append(""); xml.append(""); xml.append(""); return xml.toString(); } @Override public Answer findById(Long id) { if ( id > 0 ) { return em.find(Answer.class, id); } return null; } }