/*==========================================================================*\
| $Id: GraderSubmissionUploadComponent.java,v 1.8 2012/05/09 16:31:36 stedwar2 Exp $
|*-------------------------------------------------------------------------*|
| Copyright (C) 2006-2012 Virginia Tech
|
| This file is part of Web-CAT.
|
| Web-CAT is free software; you can redistribute it and/or modify
| it under the terms of the GNU Affero General Public License as published
| by the Free Software Foundation; either version 3 of the License, or
| (at your option) any later version.
|
| Web-CAT is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU Affero General Public License
| along with Web-CAT; if not, see <http://www.gnu.org/licenses/>.
\*==========================================================================*/
package org.webcat.grader;
import com.webobjects.appserver.*;
import com.webobjects.foundation.*;
import java.io.*;
import org.apache.log4j.Logger;
import org.webcat.core.*;
import org.webcat.core.messaging.UnexpectedExceptionMessage;
//-------------------------------------------------------------------------
/**
* A {@link GraderAssignmentComponent} that adds support for a
* {@link SubmissionInProcess} state object.
*
* @author Stephen Edwards
* @author Last changed by $Author: stedwar2 $
* @version $Revision: 1.8 $, $Date: 2012/05/09 16:31:36 $
*/
public class GraderSubmissionUploadComponent
extends GraderAssignmentComponent
{
//~ Constructors ..........................................................
// ----------------------------------------------------------
/**
* Creates a new object.
*
* @param context The context to use
*/
public GraderSubmissionUploadComponent( WOContext context )
{
super( context );
}
//~ Methods ...............................................................
// ----------------------------------------------------------
/**
* Access the user's current submission in progress.
* @return the submission in progress for this page
*/
public SubmissionInProcess submissionInProcess()
{
if (sip == null)
{
sip = (SubmissionInProcess)transientState().valueForKey(KEY);
if (sip == null)
{
sip = new SubmissionInProcess();
transientState().takeValueForKey(sip, KEY);
}
}
return sip;
}
// ----------------------------------------------------------
/**
* Creates a fresh (but not saved or committed) submission
* object and binds it to the submission key.
* @param submitNumber the number of the new submission
* @param user the person making the submission
* @param partners an array of partners to be associated with the
* submission
*/
public void startSubmission(int submitNumber, User user)
{
log.debug("startSubmission( " + submitNumber + ", " + user + " )");
submissionInProcess().startSubmission(user, submitNumber);
}
// ----------------------------------------------------------
/**
* Enters the current submission into the editing context,
* establishes all the necessary relationships, and saves the
* uploaded file to disk.
*
* @param context the context of the request
* @param submitTime the time to record for this submission
* @return a string error message, or null if there were no errors
*/
public String commitSubmission( WOContext context,
NSTimestamp submitTime )
{
String errorMessage = null;
log.debug( "committing submission" );
String uploadedFileName = submissionInProcess().uploadedFileName();
if (uploadedFileName == null)
{
return "No file name provided for uploaded file!";
}
Submission submission = Submission.create(localContext(), false);
submission.setSubmitNumber(submissionInProcess().submitNumber());
submission.setUserRelationship(submissionInProcess().user());
submission.setSubmitTime( submitTime );
submission.setFileName( uploadedFileName );
// wcSession().localContext().insertObject( submission );
// ec.saveChanges();
submission.setAssignmentOfferingRelationship(
prefs().assignmentOffering() );
prefs().assignmentOffering().addToSubmissionsRelationship( submission );
log.debug( "Uploaded file name: " + uploadedFileName );
// Do the actual partnering of the users (this will create the dummy
// Submission objects for the other partners).
if (submissionInProcess().partners() != null)
{
submission.partnerWith(submissionInProcess().partners());
}
// Then, make the necessary directory.
try
{
File dirFile = new File( submission.dirName() );
dirFile.mkdirs();
}
catch ( Exception e )
{
// Security exception
new UnexpectedExceptionMessage(e, context, null,
"Exception creating submission directory").send();
localContext().deleteObject( submission );
prefs().setSubmissionRelationship( null );
submissionInProcess().cancelSubmission();
applyLocalChanges();
return "A file error occurred while saving your "
+ "submission. The error has been reported "
+ "to the administrator. Please try your "
+ "submission again later once the problem "
+ "has been corrected.";
}
// Next, write out the file
try
{
File outFile = submission.file();
log.debug( "Local file name: " + outFile.getPath() );
FileOutputStream out = new FileOutputStream( outFile );
submissionInProcess().uploadedFile().writeToStream( out );
out.close();
}
catch ( Exception e )
{
// Do something with the exception
new UnexpectedExceptionMessage(e, context, null,
"Exception uploading submission file").send();
localContext().deleteObject( submission );
prefs().setSubmissionRelationship( null );
submissionInProcess().cancelSubmission();
applyLocalChanges();
return "A file error occurred while saving your "
+ "submission. The error has been reported "
+ "to the administrator. Please try your "
+ "submission again later once the problem "
+ "has been corrected.";
}
// Clear out older jobs
try
{
NSArray<EnqueuedJob> oldJobs =
EnqueuedJob.objectsMatchingQualifier(localContext(),
EnqueuedJob.submission.dot(Submission.user).eq(user()).and(
EnqueuedJob.submission.dot(Submission.assignmentOffering)
.eq(submission.assignmentOffering()))
.and(EnqueuedJob.regrading.isFalse()));
for (EnqueuedJob job : oldJobs)
{
job.setDiscarded(true);
}
}
catch ( Exception e )
{
// ignore it
}
// Queue it up for the grader
EnqueuedJob job = new EnqueuedJob();
// job.setSubmission( submission );
localContext().insertObject( job );
job.setSubmissionRelationship( submission );
job.setQueueTime( new NSTimestamp() );
applyLocalChanges();
prefs().setSubmissionRelationship(submission);
Grader.getInstance().graderQueue().enqueue( null );
// reset the submission in process so it is clear again
submissionInProcess().cancelSubmission();
return errorMessage;
}
// ----------------------------------------------------------
/**
* Erases the submission in progress and nulls out the corresponding
* data members.
*/
public void clearSubmission()
{
submissionInProcess().cancelSubmission();
}
// ----------------------------------------------------------
/**
* Cancels any editing in progress. Typically called when pressing
* a cancel button or using a tab to transfer to a different page.
*/
public void cancelLocalChanges()
{
clearSubmission();
super.cancelLocalChanges();
}
//~ Instance/static variables .............................................
private SubmissionInProcess sip;
private static final String KEY = SubmissionInProcess.class.getName();
static Logger log = Logger.getLogger(GraderSubmissionUploadComponent.class);
}