/********************************************************************************** * $URL$ * $Id$ *********************************************************************************** * * Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009 The Sakai Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.osedu.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **********************************************************************************/ package org.sakaiproject.tool.assessment.ui.queue.delivery; import org.sakaiproject.event.cover.EventTrackingService; import org.sakaiproject.event.cover.NotificationService; import org.sakaiproject.tool.api.Session; import org.sakaiproject.tool.assessment.data.dao.assessment.PublishedAssessmentData; import org.sakaiproject.tool.assessment.data.dao.assessment.PublishedItemData; import org.sakaiproject.tool.assessment.data.dao.assessment.PublishedSectionData; import org.sakaiproject.tool.assessment.data.dao.grading.AssessmentGradingData; import org.sakaiproject.tool.assessment.data.dao.grading.ItemGradingData; import org.sakaiproject.tool.assessment.data.ifc.assessment.EvaluationModelIfc; import org.sakaiproject.tool.assessment.data.ifc.assessment.PublishedAssessmentIfc; import org.sakaiproject.tool.assessment.data.ifc.assessment.SectionDataIfc; import org.sakaiproject.tool.assessment.data.ifc.grading.AssessmentGradingIfc; import org.sakaiproject.tool.assessment.facade.AgentFacade; import org.sakaiproject.tool.assessment.facade.PublishedAssessmentFacade; import org.sakaiproject.tool.assessment.ui.queue.delivery.TimedAssessmentQueue; import org.sakaiproject.tool.assessment.ui.bean.delivery.DeliveryBean; import org.sakaiproject.tool.assessment.ui.listener.delivery.SubmitToGradingActionListener; import org.sakaiproject.tool.assessment.ui.listener.util.ContextUtil; import org.sakaiproject.tool.assessment.ui.model.delivery.TimedAssessmentGradingModel; import org.sakaiproject.tool.assessment.services.GradingService; import org.sakaiproject.tool.assessment.services.ItemService; import org.sakaiproject.tool.assessment.services.assessment.PublishedAssessmentService; import org.sakaiproject.tool.cover.SessionManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Random; import java.util.TimerTask; /** * <p>Title: Samigo</p> * <p>Description: Sakai Assessment Manager</p> * @version $Id: SubmitTimedAssessmentThread.java 1294 2005-08-19 17:22:35Z esmiley@stanford.edu $ */ public class SubmitTimedAssessmentThread extends TimerTask { private static Log log = LogFactory.getLog(SubmitTimedAssessmentThread.class); public SubmitTimedAssessmentThread(){} public void run(){ log.debug("run!!"); ArrayList<TimedAssessmentGradingModel> removeTimedAGList = new ArrayList<TimedAssessmentGradingModel>(); // get the queue, go through the queue till it is empty TimedAssessmentQueue queue = TimedAssessmentQueue.getInstance(); Iterator iter = queue.iterator(); while (iter.hasNext()){ TimedAssessmentGradingModel timedAG = (TimedAssessmentGradingModel)iter.next(); log.debug("****** going through timedAG in queue, timedAG"+timedAG); boolean submitted = timedAG.getSubmittedForGrade(); long bufferedExpirationTime = timedAG.getBufferedExpirationDate().getTime(); // in millesec long currentTime = (new Date()).getTime(); // in millisec log.debug("****** submitted="+submitted); log.debug("****** currentTime="+currentTime); log.debug("****** bufferedExpirationTime="+bufferedExpirationTime); log.debug("****** expired="+(currentTime > bufferedExpirationTime)); if (!submitted){ if (currentTime > bufferedExpirationTime){ // time's up, i.e. timeLeft + latency buffer reached timedAG.setSubmittedForGrade(true); // set all the properties right and persist status to DB GradingService service = new GradingService(); AssessmentGradingData ag = service.load(timedAG.getAssessmentGradingId().toString()); if (!ag.getForGrade().booleanValue()) { ag.setForGrade(Boolean.TRUE); ag.setTimeElapsed(Integer.valueOf(timedAG.getTimeLimit())); ag.setStatus(AssessmentGradingIfc.SUBMITTED); // this will change status 0 -> 1 ag.setIsLate(islate(ag.getPublishedAssessmentId())); ag.setSubmittedDate(new Date()); // SAK-7302, users taking a timed assessment may exit without completing the assessment // set these two scores to 0 instaed of null if (ag.getFinalScore() == null) ag.setFinalScore(Float.valueOf("0")); if (ag.getTotalAutoScore() == null) ag.setTotalAutoScore(Float.valueOf("0")); service.completeItemGradingData(ag); service.saveOrUpdateAssessmentGrading(ag); PublishedAssessmentService publishedAssessmentService = new PublishedAssessmentService(); String siteId = publishedAssessmentService.getPublishedAssessmentOwner(ag.getPublishedAssessmentId()); EventTrackingService.post(EventTrackingService.newEvent("sam.assessment.thread_submit", "submissionId=" + ag.getAssessmentGradingId(), siteId, true, NotificationService.NOTI_REQUIRED)); notifyGradebookByScoringType(ag, timedAG.getPublishedAssessment()); log.debug("**** 4a. time's up, timeLeft+latency buffer reached, saved to DB"); } } } else{ //submitted, remove from queue if transaction buffer is also reached if (currentTime > (bufferedExpirationTime + timedAG.getTransactionBuffer()*1000L)){ //queue.remove(timedAG); removeTimedAGList.add(timedAG); log.debug("**** 4b. transaction buffer reached"); } } } Iterator i = removeTimedAGList.iterator(); while(i.hasNext()) { log.debug("removing from queue"); queue.remove((TimedAssessmentGradingModel)i.next()); } } private Boolean islate(Long publishedId) { PublishedAssessmentService service = new PublishedAssessmentService(); PublishedAssessmentData pub = service.getBasicInfoOfPublishedAssessment(publishedId.toString()); if (pub.getDueDate()!=null && pub.getDueDate().before(new Date())) return Boolean.TRUE; else return Boolean.FALSE; } private void notifyGradebookByScoringType(AssessmentGradingIfc ag, PublishedAssessmentFacade publishedAssessment){ if (publishedAssessment == null || publishedAssessment.getEvaluationModel() == null) { // should not come to here log.debug("publishedAssessment is null or publishedAssessment.getEvaluationModel() is null"); return; } if (publishedAssessment.getEvaluationModel().getToGradeBook().equals(EvaluationModelIfc.TO_DEFAULT_GRADEBOOK.toString())) { AssessmentGradingIfc assessmentGrading = ag; // data is the last submission GradingService g = new GradingService(); // need to decide what to tell gradebook if (publishedAssessment.getEvaluationModel().getScoringType().equals(EvaluationModelIfc.HIGHEST_SCORE)) { assessmentGrading = g.getHighestSubmittedAssessmentGrading(publishedAssessment.getPublishedAssessmentId().toString(), ag.getAgentId()); } Session s = SessionManager.getCurrentSession(); if (s != null) { s.setUserId(assessmentGrading.getAgentId()); g.notifyGradebook(assessmentGrading, publishedAssessment); } } } }