/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/sam/trunk/samigo-app/src/java/org/sakaiproject/tool/assessment/ui/queue/delivery/SubmitTimedAssessmentThread.java $
* $Id: SubmitTimedAssessmentThread.java 121258 2013-03-15 15:03:36Z ottenhoff@longsight.com $
***********************************************************************************
*
* 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.opensource.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 java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.TimerTask;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.EventLogData;
import org.sakaiproject.tool.assessment.data.dao.assessment.PublishedAssessmentData;
import org.sakaiproject.tool.assessment.data.dao.grading.AssessmentGradingData;
import org.sakaiproject.tool.assessment.data.ifc.assessment.EvaluationModelIfc;
import org.sakaiproject.tool.assessment.facade.AgentFacade;
import org.sakaiproject.tool.assessment.facade.EventLogFacade;
import org.sakaiproject.tool.assessment.facade.PublishedAssessmentFacade;
import org.sakaiproject.tool.assessment.services.GradingService;
import org.sakaiproject.tool.assessment.services.assessment.EventLogService;
import org.sakaiproject.tool.assessment.services.assessment.PublishedAssessmentService;
import org.sakaiproject.tool.assessment.ui.model.delivery.TimedAssessmentGradingModel;
import org.sakaiproject.tool.cover.SessionManager;
import java.util.ResourceBundle;
/**
* <p>Title: Samigo</p>
* <p>Description: Sakai Assessment Manager</p>
* @version $Id: SubmitTimedAssessmentThread.java 121258 2013-03-15 15:03:36Z ottenhoff@longsight.com $
*/
public class SubmitTimedAssessmentThread extends TimerTask
{
private static Log log = LogFactory.getLog(SubmitTimedAssessmentThread.class);
private static ResourceBundle eventLogMessages = ResourceBundle.getBundle("org.sakaiproject.tool.assessment.bundle.EventLogMessages");
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(), false);
if (!ag.getForGrade().booleanValue()) {
ag.setForGrade(Boolean.TRUE);
ag.setTimeElapsed(Integer.valueOf(timedAG.getTimeLimit()));
ag.setStatus(AssessmentGradingData.SUBMITTED); // this will change status 0 -> 1
ag.setIsLate(islate(ag.getPublishedAssessmentId()));
Date submitDate = new Date();
ag.setSubmittedDate(submitDate);
// 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(Double.valueOf("0"));
if (ag.getTotalAutoScore() == null) ag.setTotalAutoScore(Double.valueOf("0"));
service.completeItemGradingData(ag);
service.saveOrUpdateAssessmentGrading(ag);
EventLogService eventService = new EventLogService();
EventLogFacade eventLogFacade = new EventLogFacade();
List eventLogDataList = eventService.getEventLogData(ag.getAssessmentGradingId());
EventLogData eventLogData= (EventLogData) eventLogDataList.get(0);
eventLogData.setErrorMsg(eventLogMessages.getString("timer_submit"));
eventLogData.setEndDate(submitDate);
if(submitDate != null && eventLogData.getStartDate() != null) {
double minute= 1000*60;
int eclipseTime = (int)Math.ceil(((submitDate.getTime() - eventLogData.getStartDate().getTime())/minute));
eventLogData.setEclipseTime(Integer.valueOf(eclipseTime));
} else {
eventLogData.setEclipseTime(null);
eventLogData.setErrorMsg(eventLogMessages.getString("error_take"));
}
eventLogFacade.setData(eventLogData);
PublishedAssessmentService publishedAssessmentService = new PublishedAssessmentService();
String siteId = publishedAssessmentService.getPublishedAssessmentOwner(ag.getPublishedAssessmentId());
EventTrackingService.post(EventTrackingService.newEvent("sam.assessment.thread_submit", "siteId=" + AgentFacade.getCurrentSiteId() + ", 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(AssessmentGradingData 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())) {
AssessmentGradingData 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);
}
}
}
}