package org.sakaiproject.tool.assessment.ui.listener.author; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import javax.faces.context.FacesContext; import javax.faces.event.AbortProcessingException; import javax.faces.event.ActionEvent; import javax.faces.event.ActionListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.sakaiproject.event.cover.EventTrackingService; import org.sakaiproject.service.gradebook.shared.GradebookExternalAssessmentService; import org.sakaiproject.service.gradebook.shared.GradebookService; import org.sakaiproject.spring.SpringBeanLocator; import org.sakaiproject.tool.assessment.data.dao.assessment.PublishedAssessmentData; import org.sakaiproject.tool.assessment.data.dao.assessment.PublishedEvaluationModel; import org.sakaiproject.tool.assessment.data.dao.grading.AssessmentGradingData; import org.sakaiproject.tool.assessment.data.exception.SamigoDataAccessException; import org.sakaiproject.tool.assessment.data.ifc.assessment.AssessmentBaseIfc; import org.sakaiproject.tool.assessment.data.ifc.assessment.EvaluationModelIfc; import org.sakaiproject.tool.assessment.facade.AgentFacade; import org.sakaiproject.tool.assessment.facade.GradebookFacade; import org.sakaiproject.tool.assessment.facade.PublishedAssessmentFacade; import org.sakaiproject.tool.assessment.integration.context.IntegrationContextFactory; import org.sakaiproject.tool.assessment.integration.helper.ifc.CalendarServiceHelper; import org.sakaiproject.tool.assessment.integration.helper.ifc.GradebookServiceHelper; import org.sakaiproject.tool.assessment.services.FinFormatException; import org.sakaiproject.tool.assessment.services.GradebookServiceException; import org.sakaiproject.tool.assessment.services.GradingService; import org.sakaiproject.tool.assessment.services.PersistenceService; import org.sakaiproject.tool.assessment.services.assessment.AssessmentService; import org.sakaiproject.tool.assessment.services.assessment.PublishedAssessmentService; import org.sakaiproject.tool.assessment.ui.bean.author.AssessmentBean; import org.sakaiproject.tool.assessment.ui.bean.author.AuthorBean; import org.sakaiproject.tool.assessment.ui.bean.author.PublishRepublishNotificationBean; import org.sakaiproject.tool.assessment.ui.bean.author.PublishedAssessmentSettingsBean; import org.sakaiproject.tool.assessment.ui.listener.util.ContextUtil; import org.sakaiproject.util.ResourceLoader; public class RepublishAssessmentListener implements ActionListener { private static Log log = LogFactory .getLog(RepublishAssessmentListener.class); private static final GradebookServiceHelper gbsHelper = IntegrationContextFactory.getInstance().getGradebookServiceHelper(); private static final boolean integrated = IntegrationContextFactory.getInstance().isIntegrated(); private CalendarServiceHelper calendarService = IntegrationContextFactory.getInstance().getCalendarServiceHelper(); private ResourceLoader rl= new ResourceLoader("org.sakaiproject.tool.assessment.bundle.AssessmentSettingsMessages"); public void processAction(ActionEvent ae) throws AbortProcessingException { AssessmentBean assessmentBean = (AssessmentBean) ContextUtil .lookupBean("assessmentBean"); boolean hasGradingData = assessmentBean.getHasGradingData(); String publishedAssessmentId = assessmentBean.getAssessmentId(); log.debug("publishedAssessmentId = " + publishedAssessmentId); PublishedAssessmentService publishedAssessmentService = new PublishedAssessmentService(); // Go to database to get the newly updated data. The data inside beans might not be up to date. PublishedAssessmentFacade assessment = publishedAssessmentService.getPublishedAssessment(publishedAssessmentId); EventTrackingService.post(EventTrackingService.newEvent("sam.pubassessment.republish", "siteId=" + AgentFacade.getCurrentSiteId() + ", publishedAssessmentId=" + publishedAssessmentId, true)); assessment.setStatus(AssessmentBaseIfc.ACTIVE_STATUS); publishedAssessmentService.saveAssessment(assessment); AuthorBean author = (AuthorBean) ContextUtil.lookupBean("author"); // If there are submissions, need to regrade them if (author.getIsRepublishAndRegrade() && hasGradingData) { try { regradeRepublishedAssessment(publishedAssessmentService, assessment); } catch (SamigoDataAccessException e) { e.printStackTrace(); } } EventTrackingService.post(EventTrackingService.newEvent("sam.pubassessment.republish", "siteId=" + AgentFacade.getCurrentSiteId() + ", publishedAssessmentId=" + publishedAssessmentId, true)); assessment.setStatus(AssessmentBaseIfc.ACTIVE_STATUS); publishedAssessmentService.saveAssessment(assessment); updateGB(assessment); PublishRepublishNotificationBean publishRepublishNotification = (PublishRepublishNotificationBean) ContextUtil.lookupBean("publishRepublishNotification"); PublishedAssessmentSettingsBean publishedAssessmentSettings = (PublishedAssessmentSettingsBean) ContextUtil.lookupBean("publishedSettings"); PublishAssessmentListener publishAssessmentListener = new PublishAssessmentListener(); String subject = publishRepublishNotification.getNotificationSubject(); String notificationMessage = publishAssessmentListener.getNotificationMessage(publishRepublishNotification, publishedAssessmentSettings.getTitle(), publishedAssessmentSettings.getReleaseTo(), publishedAssessmentSettings.getStartDateString(), publishedAssessmentSettings.getPublishedUrl(), publishedAssessmentSettings.getReleaseToGroupsAsString(), publishedAssessmentSettings.getDueDateString(), publishedAssessmentSettings.getTimedHours(), publishedAssessmentSettings.getTimedMinutes(), publishedAssessmentSettings.getUnlimitedSubmissions(), publishedAssessmentSettings.getSubmissionsAllowed(), publishedAssessmentSettings.getScoringType(), publishedAssessmentSettings.getFeedbackDelivery(), publishedAssessmentSettings.getFeedbackDateString()); if (publishRepublishNotification.getSendNotification()) { publishAssessmentListener.sendNotification(assessment, publishedAssessmentService, subject, notificationMessage, publishedAssessmentSettings.getReleaseTo()); } GradingService gradingService = new GradingService(); AssessmentService assessmentService = new AssessmentService(); AuthorActionListener authorActionListener = new AuthorActionListener(); authorActionListener.prepareAssessmentsList(author, assessmentService, gradingService, publishedAssessmentService); // Tell AuthorBean that we just published an assessment // This will allow us to jump directly to published assessments tab author.setJustPublishedAnAssessment(true); //update Calendar Events boolean addDueDateToCalendar = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("publishAssessmentForm:calendarDueDate2") != null; calendarService.updateAllCalendarEvents(assessment, publishedAssessmentSettings.getReleaseTo(), publishedAssessmentSettings.getGroupsAuthorized(), rl.getString("calendarDueDatePrefix") + " ", addDueDateToCalendar, notificationMessage); author.setOutcome("author"); } private void regradeRepublishedAssessment (PublishedAssessmentService pubService, PublishedAssessmentFacade publishedAssessment) throws GradebookServiceException, FinFormatException, SamigoDataAccessException { HashMap publishedItemHash = pubService.preparePublishedItemHash(publishedAssessment); HashMap publishedItemTextHash = pubService.preparePublishedItemTextHash(publishedAssessment); HashMap publishedAnswerHash = pubService.preparePublishedAnswerHash(publishedAssessment); PublishedAssessmentSettingsBean publishedAssessmentSettings = (PublishedAssessmentSettingsBean) ContextUtil .lookupBean("publishedSettings"); // Actually we don't really need to consider linear or random here. // boolean randomAccessAssessment = publishedAssessmentSettings.getItemNavigation().equals("2"); boolean updateMostCurrentSubmission = publishedAssessmentSettings.getupdateMostCurrentSubmission(); GradingService service = new GradingService(); List list = service.getAllAssessmentGradingData(publishedAssessment.getPublishedAssessmentId()); Iterator iter = list.iterator(); if (updateMostCurrentSubmission) { publishedAssessment.setLastNeedResubmitDate(new Date()); String currentAgent = ""; while (iter.hasNext()) { AssessmentGradingData adata = (AssessmentGradingData) iter.next(); if (!currentAgent.equals(adata.getAgentId())){ if (adata.getForGrade().booleanValue()) { adata.setForGrade(Boolean.FALSE); adata.setStatus(AssessmentGradingData.ASSESSMENT_UPDATED_NEED_RESUBMIT); } else { adata.setStatus(AssessmentGradingData.ASSESSMENT_UPDATED); } currentAgent = adata.getAgentId(); } service.storeGrades(adata, true, publishedAssessment, publishedItemHash, publishedItemTextHash, publishedAnswerHash, true); } } else { while (iter.hasNext()) { AssessmentGradingData adata = (AssessmentGradingData) iter.next(); service.storeGrades(adata, true, publishedAssessment, publishedItemHash, publishedItemTextHash, publishedAnswerHash, true); } } } private void updateGB(PublishedAssessmentFacade assessment) { // a. if Gradebook does not exists, do nothing // b. if Gradebook exists, just call removeExternal first to clean up all data. And call addExternal to create // a new record. At the end, populate the scores by calling updateExternalAssessmentScores GradebookExternalAssessmentService g = null; if (integrated) { g = (GradebookExternalAssessmentService) SpringBeanLocator.getInstance().getBean( "org.sakaiproject.service.gradebook.GradebookExternalAssessmentService"); } if (gbsHelper.gradebookExists(GradebookFacade.getGradebookUId(), g)) { PublishedEvaluationModel evaluation = (PublishedEvaluationModel) assessment.getEvaluationModel(); //Integer scoringType = EvaluationModelIfc.HIGHEST_SCORE; if (evaluation == null) { evaluation = new PublishedEvaluationModel(); evaluation.setAssessmentBase(assessment.getData()); } Integer scoringType = evaluation.getScoringType(); if (evaluation.getToGradeBook() != null && evaluation.getToGradeBook().equals(EvaluationModelIfc.TO_DEFAULT_GRADEBOOK.toString())) { try { log.debug("before gbsHelper.removeGradebook()"); gbsHelper.removeExternalAssessment(GradebookFacade.getGradebookUId(), assessment.getPublishedAssessmentId().toString(), g); } catch (Exception e1) { // Should be the external assessment doesn't exist in GB. So we quiet swallow the exception. Please check the log for the actual error. log.info("Exception thrown in updateGB():" + e1.getMessage()); } try { log.debug("before gbsHelper.addToGradebook()"); gbsHelper.addToGradebook((PublishedAssessmentData) assessment.getData(), g); // any score to copy over? get all the assessmentGradingData and copy over GradingService gradingService = new GradingService(); // need to decide what to tell gradebook List list = null; if ((scoringType).equals(EvaluationModelIfc.HIGHEST_SCORE)) { list = gradingService.getHighestSubmittedOrGradedAssessmentGradingList(assessment.getPublishedAssessmentId()); } else { list = gradingService.getLastSubmittedOrGradedAssessmentGradingList(assessment.getPublishedAssessmentId()); } log.debug("list size =" + list.size()); for (int i = 0; i < list.size(); i++) { try { AssessmentGradingData ag = (AssessmentGradingData) list.get(i); log.debug("ag.scores " + ag.getTotalAutoScore()); // Send the average score if average was selected for multiple submissions if (scoringType.equals(EvaluationModelIfc.AVERAGE_SCORE)) { // status = 5: there is no submission but grader update something in the score page if(ag.getStatus() ==5) { ag.setFinalScore(ag.getFinalScore()); } else { Double averageScore = PersistenceService.getInstance().getAssessmentGradingFacadeQueries(). getAverageSubmittedAssessmentGrading(Long.valueOf(assessment.getPublishedAssessmentId()), ag.getAgentId()); ag.setFinalScore(averageScore); } } gbsHelper.updateExternalAssessmentScore(ag, g); } catch (Exception e) { log.warn("Exception occues in " + i + "th record. Message:" + e.getMessage()); } } } catch (Exception e2) { log.warn("Exception thrown in updateGB():" + e2.getMessage()); } } else{ //remove try{ gbsHelper.removeExternalAssessment( GradebookFacade.getGradebookUId(), assessment.getPublishedAssessmentId().toString(), g); } catch(Exception e){ log.info("*** oh well, looks like there is nothing to remove:"+e.getMessage()); } } } } }