0001: /**********************************************************************************
0002: * $URL: https://source.sakaiproject.org/svn/sam/tags/sakai_2-4-1/samigo-app/src/java/org/sakaiproject/tool/assessment/ui/bean/delivery/DeliveryBean.java $
0003: * $Id: DeliveryBean.java 29634 2007-04-26 14:43:28Z ajpoland@iupui.edu $
0004: ***********************************************************************************
0005: *
0006: * Copyright (c) 2004, 2005, 2006 The Sakai Foundation.
0007: *
0008: * Licensed under the Educational Community License, Version 1.0 (the"License");
0009: * you may not use this file except in compliance with the License.
0010: * You may obtain a copy of the License at
0011: *
0012: * http://www.opensource.org/licenses/ecl1.php
0013: *
0014: * Unless required by applicable law or agreed to in writing, software
0015: * distributed under the License is distributed on an "AS IS" BASIS,
0016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017: * See the License for the specific language governing permissions and
0018: * limitations under the License.
0019: *
0020: **********************************************************************************/package org.sakaiproject.tool.assessment.ui.bean.delivery;
0021:
0022: import java.io.File;
0023: import java.io.FileInputStream;
0024: import java.io.FileNotFoundException;
0025: import java.io.IOException;
0026: import java.io.Serializable;
0027: import java.util.ArrayList;
0028: import java.util.Date;
0029: import java.util.HashMap;
0030: import java.util.Iterator;
0031: import java.util.List;
0032: import java.util.Set;
0033: import javax.faces.application.FacesMessage;
0034: import javax.faces.context.FacesContext;
0035: import javax.faces.context.ExternalContext;
0036: import javax.servlet.ServletContext;
0037:
0038: import org.apache.commons.logging.Log;
0039: import org.apache.commons.logging.LogFactory;
0040:
0041: import org.sakaiproject.site.api.Site;
0042: import org.sakaiproject.site.api.SitePage;
0043: import org.sakaiproject.site.api.ToolConfiguration;
0044: import org.sakaiproject.site.cover.SiteService;
0045: import org.sakaiproject.tool.assessment.data.dao.assessment.PublishedSectionData;
0046: import org.sakaiproject.tool.assessment.data.dao.assessment.PublishedItemData;
0047: import org.sakaiproject.tool.assessment.data.dao.assessment.PublishedItemText;
0048: import org.sakaiproject.tool.assessment.data.dao.assessment.PublishedSecuredIPAddress;
0049: import org.sakaiproject.tool.assessment.data.dao.grading.AssessmentGradingData;
0050: import org.sakaiproject.tool.assessment.data.dao.grading.ItemGradingData;
0051: import org.sakaiproject.tool.assessment.data.dao.grading.MediaData;
0052: import org.sakaiproject.tool.assessment.data.ifc.assessment.AssessmentAccessControlIfc;
0053: import org.sakaiproject.tool.assessment.facade.AgentFacade;
0054: import org.sakaiproject.tool.assessment.facade.PublishedAssessmentFacade;
0055: import org.sakaiproject.tool.assessment.services.GradingService;
0056: import org.sakaiproject.tool.assessment.services.assessment.PublishedAssessmentService;
0057: import org.sakaiproject.tool.assessment.ui.bean.util.Validator;
0058: import org.sakaiproject.tool.assessment.ui.listener.delivery.DeliveryActionListener;
0059: import org.sakaiproject.tool.assessment.ui.listener.delivery.SubmitToGradingActionListener;
0060: import org.sakaiproject.tool.assessment.ui.listener.select.SelectActionListener;
0061: import org.sakaiproject.tool.assessment.ui.listener.util.ContextUtil;
0062: import org.sakaiproject.tool.assessment.util.MimeTypesLocator;
0063: import org.sakaiproject.tool.assessment.ui.web.session.SessionUtil;
0064: import org.sakaiproject.tool.assessment.ui.bean.shared.PersonBean;
0065: import org.sakaiproject.tool.assessment.ui.queue.delivery.TimedAssessmentQueue;
0066: import org.sakaiproject.tool.assessment.ui.model.delivery.TimedAssessmentGradingModel;
0067:
0068: //cwen
0069: import org.sakaiproject.tool.cover.ToolManager;
0070: import org.sakaiproject.tool.api.Placement; // note: we should wrap above dependency in a backend service--esmiley
0071:
0072: import java.text.SimpleDateFormat;
0073: import org.sakaiproject.tool.assessment.ui.listener.util.TimeUtil;
0074: import org.sakaiproject.component.cover.ServerConfigurationService;
0075: import org.sakaiproject.exception.IdUnusedException;
0076:
0077: /**
0078: *
0079: * @author casong
0080: * @author esmiley@stanford.edu added agentState
0081: * $Id: DeliveryBean.java 29634 2007-04-26 14:43:28Z ajpoland@iupui.edu $
0082: *
0083: * Used to be org.navigoproject.ui.web.asi.delivery.XmlDeliveryForm.java
0084: */
0085: public class DeliveryBean implements Serializable {
0086: private static Log log = LogFactory.getLog(DeliveryBean.class);
0087:
0088: private String assessmentId;
0089: private String assessmentTitle;
0090: private ArrayList markedForReview;
0091: private ArrayList blankItems;
0092: private ArrayList markedForReviewIdents;
0093: private ArrayList blankItemIdents;
0094: private boolean reviewMarked;
0095: private boolean reviewAll;
0096: private boolean reviewBlank;
0097: private int itemIndex;
0098: private int size;
0099: private String action;
0100: private Date beginTime;
0101: private String endTime;
0102: private String currentTime;
0103: private String multipleAttempts;
0104: private String timeOutSubmission;
0105: private String submissionTicket;
0106: private String timeElapse;
0107: private String username;
0108: private int sectionIndex;
0109: private boolean previous;
0110: private String duration;
0111: private String url;
0112: private String confirmation;
0113: private String outcome;
0114:
0115: //Settings
0116: private String questionLayout;
0117: private String navigation;
0118: private String numbering;
0119: private String feedback;
0120: private String noFeedback;
0121: private String statistics;
0122: private String creatorName;
0123:
0124: private FeedbackComponent feedbackComponent;
0125: private boolean feedbackOnDate;
0126: private String errorMessage;
0127: private SettingsDeliveryBean settings;
0128: private java.util.Date dueDate;
0129: private boolean statsAvailable;
0130: private boolean submitted;
0131: private boolean graded;
0132: private String graderComment;
0133: private String rawScore;
0134: private String grade;
0135: private java.util.Date submissionDate;
0136: private java.util.Date submissionTime;
0137: private String image;
0138: private boolean hasImage;
0139: private String instructorMessage;
0140: private String courseName;
0141: private String timeLimit;
0142: private int timeLimit_hour;
0143: private int timeLimit_minute;
0144: private ContentsDeliveryBean tableOfContents;
0145: private String submissionId;
0146: private String submissionMessage;
0147: private String instructorName;
0148: private ContentsDeliveryBean pageContents;
0149: private int submissionsRemaining;
0150: private boolean forGrade;
0151: private String password;
0152:
0153: // For paging
0154: private int partIndex;
0155: private int questionIndex;
0156: private boolean next_page;
0157: private boolean reload = true;
0158:
0159: // daisy added these for SelectActionListener
0160: private boolean notTakeable = true;
0161: private boolean pastDue;
0162: private long subTime;
0163: private long raw;
0164: private String takenHours;
0165: private String takenMinutes;
0166: private AssessmentGradingData adata;
0167: private PublishedAssessmentFacade publishedAssessment;
0168: private java.util.Date feedbackDate;
0169: private String feedbackDelivery;
0170: private String showScore;
0171: private boolean hasTimeLimit;
0172: private boolean isMoreThanOneQuestion;
0173:
0174: // daisyf added for servlet Login.java, to support anonymous login with
0175: // publishedUrl
0176: private boolean anonymousLogin = false;
0177: private String contextPath;
0178: private boolean initAgentAccessString = false;
0179:
0180: // daisyf added this for timed assessment for SAK-6990, to check if mutiple windows were open
0181: // during timed assessment
0182: private String timerId = null;
0183:
0184: /** Use serialVersionUID for interoperability. */
0185: private final static long serialVersionUID = -1090852048737428722L;
0186: private boolean showStudentScore;
0187: private boolean showStudentQuestionScore;
0188:
0189: // SAM-387
0190: // esmiley added to track if timer has been started in timed assessments
0191: private boolean timeRunning;
0192: // SAM-535
0193: // esmiley added to track JavaScript
0194: private String javaScriptEnabledCheck;
0195:
0196: //cwen
0197: private String siteId;
0198:
0199: private boolean beginAssessment;
0200:
0201: // this instance tracks if the Agent is taking a test via URL, as well as
0202: // current agent string (if assigned). SAK-1927: esmiley
0203: private AgentFacade deliveryAgent;
0204:
0205: // lydial added for timezone conversion
0206: //private String display_dateFormat= ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.GeneralMessages","output_date_no_sec");
0207: private String display_dateFormat = "yyyy-MMM-dd hh:mm aaa";
0208: private SimpleDateFormat displayFormat = new SimpleDateFormat(
0209: display_dateFormat);
0210:
0211: private boolean noQuestions = false;
0212:
0213: // this assessmentGradingId is used to generate seed in getSeed(...) of DeliveryActaionListener.java
0214: // We need this because the assessmentGradingData in delivery bean might not be the one we want to display
0215: // especially for review assessment and grade assessment. In other word, if student has started taking another assessment,
0216: // the assessmentGradingData in deliver bean will be the newly created one. Then, of course, the assessmentGradingId
0217: // will be the new id which is not what we want in review assessment or grade assessment
0218: private Long assessmentGradingId;
0219:
0220: /**
0221: * Creates a new DeliveryBean object.
0222: */
0223: public DeliveryBean() {
0224: deliveryAgent = new AgentFacade();
0225: }
0226:
0227: /**
0228: *
0229: *
0230: * @return
0231: */
0232: public int getItemIndex() {
0233: return this .itemIndex;
0234: }
0235:
0236: /**
0237: *
0238: *
0239: * @param itemIndex
0240: */
0241: public void setItemIndex(int itemIndex) {
0242: this .itemIndex = itemIndex;
0243: }
0244:
0245: /**
0246: *
0247: *
0248: * @return
0249: */
0250: public int getSize() {
0251: return this .size;
0252: }
0253:
0254: /**
0255: *
0256: *
0257: * @param size
0258: */
0259: public void setSize(int size) {
0260: this .size = size;
0261: }
0262:
0263: /**
0264: *
0265: *
0266: * @return
0267: */
0268: public String getAssessmentId() {
0269: return assessmentId;
0270: }
0271:
0272: /**
0273: *
0274: *
0275: * @param assessmentId
0276: */
0277: public void setAssessmentId(String assessmentId) {
0278: this .assessmentId = assessmentId;
0279: }
0280:
0281: /**
0282: *
0283: *
0284: * @return
0285: */
0286: public ArrayList getMarkedForReview() {
0287: return markedForReview;
0288: }
0289:
0290: /**
0291: *
0292: *
0293: * @param markedForReview
0294: */
0295: public void setMarkedForReview(ArrayList markedForReview) {
0296: this .markedForReview = markedForReview;
0297: }
0298:
0299: /**
0300: *
0301: *
0302: * @return
0303: */
0304: public boolean getReviewMarked() {
0305: return this .reviewMarked;
0306: }
0307:
0308: /**
0309: *
0310: *
0311: * @param reviewMarked
0312: */
0313: public void setReviewMarked(boolean reviewMarked) {
0314: this .reviewMarked = reviewMarked;
0315: }
0316:
0317: /**
0318: *
0319: *
0320: * @return
0321: */
0322: public boolean getReviewAll() {
0323: return this .reviewAll;
0324: }
0325:
0326: /**
0327: *
0328: *
0329: * @param reviewAll
0330: */
0331: public void setReviewAll(boolean reviewAll) {
0332: this .reviewAll = reviewAll;
0333: }
0334:
0335: /**
0336: *
0337: *
0338: * @return
0339: */
0340: public String getAction() {
0341: return this .action;
0342: }
0343:
0344: /**
0345: *
0346: *
0347: * @param action
0348: */
0349: public void setAction(String action) {
0350: this .action = action;
0351: }
0352:
0353: /**
0354: *
0355: *
0356: * @return
0357: */
0358: public Date getBeginTime() {
0359: return beginTime;
0360: }
0361:
0362: /**
0363: *
0364: *
0365: * @param beginTime
0366: */
0367: public void setBeginTime(Date beginTime) {
0368: this .beginTime = beginTime;
0369: }
0370:
0371: /**
0372: *
0373: *
0374: * @return
0375: */
0376: public String getEndTime() {
0377: return endTime;
0378: }
0379:
0380: /**
0381: *
0382: *
0383: * @param endTime
0384: */
0385: public void setEndTime(String endTime) {
0386: this .endTime = endTime;
0387: }
0388:
0389: /**
0390: *
0391: *
0392: * @return
0393: */
0394: public String getCurrentTime() {
0395: return this .currentTime;
0396: }
0397:
0398: /**
0399: *
0400: *
0401: * @param currentTime
0402: */
0403: public void setCurrentTime(String currentTime) {
0404: this .currentTime = currentTime;
0405: }
0406:
0407: /**
0408: *
0409: *
0410: * @return
0411: */
0412: public String getMultipleAttempts() {
0413: return this .multipleAttempts;
0414: }
0415:
0416: /**
0417: *
0418: *
0419: * @param multipleAttempts
0420: */
0421: public void setMultipleAttempts(String multipleAttempts) {
0422: this .multipleAttempts = multipleAttempts;
0423: }
0424:
0425: /**
0426: *
0427: *
0428: * @return
0429: */
0430: public String getTimeOutSubmission() {
0431: return this .timeOutSubmission;
0432: }
0433:
0434: /**
0435: *
0436: *
0437: * @param timeOutSubmission
0438: */
0439: public void setTimeOutSubmission(String timeOutSubmission) {
0440: this .timeOutSubmission = timeOutSubmission;
0441: }
0442:
0443: /**
0444: *
0445: *
0446: * @return
0447: */
0448: public java.util.Date getSubmissionTime() {
0449: return submissionTime;
0450: }
0451:
0452: /**
0453: *
0454: *
0455: * @param submissionTime
0456: */
0457: public void setSubmissionTime(java.util.Date submissionTime) {
0458: this .submissionTime = submissionTime;
0459: }
0460:
0461: /**
0462: *
0463: *
0464: * @return
0465: */
0466: public String getTimeElapse() {
0467: return timeElapse;
0468: }
0469:
0470: /**
0471: *
0472: *
0473: * @param timeElapse
0474: */
0475: public void setTimeElapse(String timeElapse) {
0476: try {
0477: if (timeElapse != null && !("").equals(timeElapse)
0478: && getTimeLimit() != null
0479: && !("").equals(getTimeLimit())) {
0480: float limit = (new Float(getTimeLimit())).floatValue();
0481: float elapsed = (new Float(timeElapse)).floatValue();
0482: if (limit > elapsed)
0483: this .timeElapse = timeElapse;
0484: else
0485: this .timeElapse = getTimeLimit();
0486: setTimeElapseFloat((new Float(timeElapse)).floatValue());
0487: }
0488: } catch (Exception e) {
0489: log.warn("setTimeElapse error:" + e.getMessage());
0490: }
0491: }
0492:
0493: /**
0494: *
0495: *
0496: * @return
0497: */
0498: public String getSubmissionTicket() {
0499: return submissionTicket;
0500: }
0501:
0502: /**
0503: *
0504: *
0505: * @param submissionTicket
0506: */
0507: public void setSubmissionTicket(String submissionTicket) {
0508: this .submissionTicket = submissionTicket;
0509: }
0510:
0511: /**
0512: *
0513: *
0514: * @return
0515: */
0516: public int getDisplayIndex() {
0517: return this .itemIndex + 1;
0518: }
0519:
0520: /**
0521: *
0522: *
0523: * @return
0524: */
0525: public String getUsername() {
0526: return username;
0527: }
0528:
0529: /**
0530: *
0531: *
0532: * @param username
0533: */
0534: public void setUsername(String username) {
0535: this .username = username;
0536: }
0537:
0538: /**
0539: *
0540: *
0541: * @return
0542: */
0543: public String getAssessmentTitle() {
0544: return assessmentTitle;
0545: }
0546:
0547: /**
0548: *
0549: *
0550: * @param assessmentTitle
0551: */
0552: public void setAssessmentTitle(String assessmentTitle) {
0553: this .assessmentTitle = assessmentTitle;
0554: }
0555:
0556: /**
0557: *
0558: *
0559: * @return
0560: */
0561: public ArrayList getBlankItems() {
0562: return this .blankItems;
0563: }
0564:
0565: /**
0566: *
0567: *
0568: * @param blankItems
0569: */
0570: public void setBlankItems(ArrayList blankItems) {
0571: this .blankItems = blankItems;
0572: }
0573:
0574: /**
0575: *
0576: *
0577: * @return
0578: */
0579: public boolean getReviewBlank() {
0580: return reviewBlank;
0581: }
0582:
0583: /**
0584: *
0585: *
0586: * @param reviewBlank
0587: */
0588: public void setReviewBlank(boolean reviewBlank) {
0589: this .reviewBlank = reviewBlank;
0590: }
0591:
0592: /**
0593: *
0594: *
0595: * @return
0596: */
0597: public ArrayList getMarkedForReviewIdents() {
0598: return markedForReviewIdents;
0599: }
0600:
0601: /**
0602: *
0603: *
0604: * @param markedForReviewIdents
0605: */
0606: public void setMarkedForReviewIdents(ArrayList markedForReviewIdents) {
0607: this .markedForReviewIdents = markedForReviewIdents;
0608: }
0609:
0610: /**
0611: *
0612: *
0613: * @return
0614: */
0615: public ArrayList getBlankItemIdents() {
0616: return blankItemIdents;
0617: }
0618:
0619: /**
0620: *
0621: *
0622: * @param blankItemIdents
0623: */
0624: public void setBlankItemIdents(ArrayList blankItemIdents) {
0625: this .blankItemIdents = blankItemIdents;
0626: }
0627:
0628: /**
0629: *
0630: *
0631: * @return
0632: */
0633: public int getSectionIndex() {
0634: return this .sectionIndex;
0635: }
0636:
0637: /**
0638: *
0639: *
0640: * @param sectionIndex
0641: */
0642: public void setSectionIndex(int sectionIndex) {
0643: this .sectionIndex = sectionIndex;
0644: }
0645:
0646: /**
0647: *
0648: *
0649: * @return
0650: */
0651: public boolean getPrevious() {
0652: return previous;
0653: }
0654:
0655: /**
0656: *
0657: *
0658: * @param previous
0659: */
0660: public void setPrevious(boolean previous) {
0661: this .previous = previous;
0662: }
0663:
0664: //Settings
0665: public String getQuestionLayout() {
0666: return questionLayout;
0667: }
0668:
0669: /**
0670: *
0671: *
0672: * @param questionLayout
0673: */
0674: public void setQuestionLayout(String questionLayout) {
0675: this .questionLayout = questionLayout;
0676: }
0677:
0678: /**
0679: *
0680: *
0681: * @return
0682: */
0683: public String getNavigation() {
0684: return navigation;
0685: }
0686:
0687: /**
0688: *
0689: *
0690: * @param navigation
0691: */
0692: public void setNavigation(String navigation) {
0693: this .navigation = navigation;
0694: }
0695:
0696: /**
0697: *
0698: *
0699: * @return
0700: */
0701: public String getNumbering() {
0702: return numbering;
0703: }
0704:
0705: /**
0706: *
0707: *
0708: * @param numbering
0709: */
0710: public void setNumbering(String numbering) {
0711: this .numbering = numbering;
0712: }
0713:
0714: /**
0715: *
0716: *
0717: * @return
0718: */
0719: public String getFeedback() {
0720: return feedback;
0721: }
0722:
0723: /**
0724: *
0725: *
0726: * @param feedback
0727: */
0728: public void setFeedback(String feedback) {
0729: this .feedback = feedback;
0730: }
0731:
0732: /**
0733: *
0734: *
0735: * @return
0736: */
0737: public String getNoFeedback() {
0738: return noFeedback;
0739: }
0740:
0741: /**
0742: *
0743: *
0744: * @param noFeedback
0745: */
0746: public void setNoFeedback(String noFeedback) {
0747: this .noFeedback = noFeedback;
0748: }
0749:
0750: /**
0751: *
0752: *
0753: * @return
0754: */
0755: public String getStatistics() {
0756: return statistics;
0757: }
0758:
0759: /**
0760: *
0761: *
0762: * @param statistics
0763: */
0764: public void setStatistics(String statistics) {
0765: this .statistics = statistics;
0766: }
0767:
0768: /**
0769: *
0770: *
0771: * @return
0772: */
0773: public FeedbackComponent getFeedbackComponent() {
0774: return feedbackComponent;
0775: }
0776:
0777: /**
0778: *
0779: *
0780: * @param feedbackComponent
0781: */
0782: public void setFeedbackComponent(FeedbackComponent feedbackComponent) {
0783: this .feedbackComponent = feedbackComponent;
0784: }
0785:
0786: /**
0787: * Types of feedback in FeedbackComponent:
0788: *
0789: * SHOW CORRECT SCORE
0790: * SHOW STUDENT SCORE
0791: * SHOW ITEM LEVEL
0792: * SHOW SECTION LEVEL
0793: * SHOW GRADER COMMENT
0794: * SHOW STATS
0795: * SHOW QUESTION
0796: * SHOW RESPONSE
0797: **/
0798:
0799: /**
0800: * @return
0801: */
0802: public SettingsDeliveryBean getSettings() {
0803: return settings;
0804: }
0805:
0806: /**
0807: * @param bean
0808: */
0809: public void setSettings(SettingsDeliveryBean settings) {
0810: this .settings = settings;
0811: }
0812:
0813: /**
0814: * @return
0815: */
0816: public String getErrorMessage() {
0817: return errorMessage;
0818: }
0819:
0820: /**
0821: * @param string
0822: */
0823: public void setErrorMessage(String string) {
0824: errorMessage = string;
0825: }
0826:
0827: /**
0828: * @return
0829: */
0830: public String getDuration() {
0831: return duration;
0832: }
0833:
0834: /**
0835: * @param string
0836: */
0837: public void setDuration(String string) {
0838: duration = string;
0839: }
0840:
0841: /**
0842: * @return
0843: */
0844: public String getCreatorName() {
0845: return creatorName;
0846: }
0847:
0848: /**
0849: * @param string
0850: */
0851: public void setCreatorName(String string) {
0852: creatorName = string;
0853: }
0854:
0855: public java.util.Date getDueDate() {
0856: return dueDate;
0857: }
0858:
0859: public String getDueDateString() {
0860: String dateString = "";
0861: if (dueDate == null) {
0862: return dateString;
0863: }
0864:
0865: try {
0866: TimeUtil tu = new TimeUtil();
0867: dateString = tu.getDisplayDateTime(displayFormat, dueDate);
0868: } catch (Exception ex) {
0869: // we will leave it as an empty string
0870: log.warn("Unable to format date.");
0871: ex.printStackTrace();
0872: }
0873: return dateString;
0874: }
0875:
0876: public void setDueDate(java.util.Date dueDate) {
0877: this .dueDate = dueDate;
0878: }
0879:
0880: public boolean isStatsAvailable() {
0881: return statsAvailable;
0882: }
0883:
0884: public void setStatsAvailable(boolean statsAvailable) {
0885: this .statsAvailable = statsAvailable;
0886: }
0887:
0888: public boolean isSubmitted() {
0889: return submitted;
0890: }
0891:
0892: public void setSubmitted(boolean submitted) {
0893: this .submitted = submitted;
0894: }
0895:
0896: public boolean isGraded() {
0897: return graded;
0898: }
0899:
0900: public void setGraded(boolean graded) {
0901: this .graded = graded;
0902: }
0903:
0904: public boolean getFeedbackOnDate() {
0905: return feedbackOnDate;
0906: }
0907:
0908: public void setFeedbackOnDate(boolean feedbackOnDate) {
0909: this .feedbackOnDate = feedbackOnDate;
0910: }
0911:
0912: public String getGraderComment() {
0913: if (graderComment == null) {
0914: return "";
0915: }
0916: return graderComment;
0917: }
0918:
0919: public void setGraderComment(String newComment) {
0920: graderComment = newComment;
0921: }
0922:
0923: public String getRawScore() {
0924: return rawScore;
0925: }
0926:
0927: public String getRoundedRawScore() {
0928: try {
0929: String newscore = ContextUtil.getRoundedValue(rawScore, 2);
0930: return Validator.check(newscore, "N/A");
0931: } catch (Exception e) {
0932: // encountered some weird number format/locale
0933: return Validator.check(rawScore, "0");
0934: }
0935:
0936: }
0937:
0938: public void setRawScore(String rawScore) {
0939: this .rawScore = rawScore;
0940: }
0941:
0942: public long getRaw() {
0943: return raw;
0944: }
0945:
0946: public void setRaw(long raw) {
0947: this .raw = raw;
0948: }
0949:
0950: public String getGrade() {
0951: return grade;
0952: }
0953:
0954: public void setGrade(String grade) {
0955: this .grade = grade;
0956: }
0957:
0958: public java.util.Date getSubmissionDate() {
0959: return submissionDate;
0960: }
0961:
0962: public String getSubmissionDateString() {
0963: String dateString = "";
0964: if (submissionDate == null) {
0965: return dateString;
0966: }
0967:
0968: try {
0969: TimeUtil tu = new TimeUtil();
0970: dateString = tu.getDisplayDateTime(displayFormat,
0971: submissionDate);
0972: } catch (Exception ex) {
0973: // we will leave it as an empty string
0974: log.warn("Unable to format date.");
0975: ex.printStackTrace();
0976: }
0977: return dateString;
0978: }
0979:
0980: public void setSubmissionDate(java.util.Date submissionDate) {
0981: this .submissionDate = submissionDate;
0982: }
0983:
0984: public String getImage() {
0985: return image;
0986: }
0987:
0988: public void setImage(String image) {
0989: this .image = image;
0990: }
0991:
0992: public boolean isHasImage() {
0993: return hasImage;
0994: }
0995:
0996: public void setHasImage(boolean hasImage) {
0997: this .hasImage = hasImage;
0998: }
0999:
1000: public String getInstructorMessage() {
1001: return instructorMessage;
1002: }
1003:
1004: public void setInstructorMessage(String instructorMessage) {
1005: this .instructorMessage = instructorMessage;
1006: }
1007:
1008: public String getCourseName() {
1009: return courseName;
1010: }
1011:
1012: public void setCourseName(String courseName) {
1013: this .courseName = courseName;
1014: }
1015:
1016: public String getTimeLimit() {
1017: return timeLimit;
1018: }
1019:
1020: public void setTimeLimit(String timeLimit) {
1021: this .timeLimit = timeLimit;
1022: }
1023:
1024: public int getTimeLimit_hour() {
1025: return timeLimit_hour;
1026: }
1027:
1028: public void setTimeLimit_hour(int timeLimit_hour) {
1029: this .timeLimit_hour = timeLimit_hour;
1030: }
1031:
1032: public int getTimeLimit_minute() {
1033: return timeLimit_minute;
1034: }
1035:
1036: public void setTimeLimit_minute(int timeLimit_minute) {
1037: this .timeLimit_minute = timeLimit_minute;
1038: }
1039:
1040: /**
1041: * Bean with table of contents information and
1042: * a list of all the sections in the assessment
1043: * which in turn has a list of all the item contents.
1044: * @return table of contents
1045: */
1046: public ContentsDeliveryBean getTableOfContents() {
1047: return tableOfContents;
1048: }
1049:
1050: /**
1051: * Bean with table of contents information and
1052: * a list of all the sections in the assessment
1053: * which in turn has a list of all the item contents.
1054: * @param tableOfContents table of contents
1055: */
1056: public void setTableOfContents(ContentsDeliveryBean tableOfContents) {
1057: this .tableOfContents = tableOfContents;
1058: }
1059:
1060: /**
1061: * Bean with a list of all the sections in the current page
1062: * which in turn has a list of all the item contents for the page.
1063: *
1064: * This is like the table of contents, but the selections are restricted to
1065: * that on one page.
1066: *
1067: * Since these properties are on a page delivery basis--if:
1068: * 1. there is only one item per page the list of items will
1069: * contain one item and the list of parts will return one part, or if--
1070: *
1071: * 2. there is one part per page the list of items will be that
1072: * for that part only and there will only be one part, however--
1073: *
1074: * 3. if it is all parts and items on a single page there
1075: * will be a list of all parts and items.
1076: *
1077: * @return ContentsDeliveryBean
1078: */
1079: public ContentsDeliveryBean getPageContents() {
1080: return pageContents;
1081: }
1082:
1083: /**
1084: * Bean with a list of all the sections in the current page
1085: * which in turn has a list of all the item contents for the page.
1086: *
1087: * Since these properties are on a page delivery basis--if:
1088: * 1. there is only one item per page the list of items will
1089: * contain one item and the list of parts will return one part, or if--
1090: *
1091: * 2. there is one part per page the list of items will be that
1092: * for that part only and there will only be one part, however--
1093: *
1094: * 3. if it is all parts and items on a single page there
1095: * will be a list of all parts and items.
1096: *
1097: * @param pageContents ContentsDeliveryBean
1098: */
1099: public void setPageContents(ContentsDeliveryBean pageContents) {
1100: this .pageContents = pageContents;
1101: }
1102:
1103: public String getSubmissionId() {
1104: return submissionId;
1105: }
1106:
1107: public void setSubmissionId(String submissionId) {
1108: this .submissionId = submissionId;
1109: }
1110:
1111: public String getSubmissionMessage() {
1112: return submissionMessage;
1113: }
1114:
1115: public void setSubmissionMessage(String submissionMessage) {
1116: this .submissionMessage = submissionMessage;
1117: }
1118:
1119: public int getSubmissionsRemaining() {
1120: return submissionsRemaining;
1121: }
1122:
1123: public void setSubmissionsRemaining(int submissionsRemaining) {
1124: this .submissionsRemaining = submissionsRemaining;
1125: }
1126:
1127: public String getInstructorName() {
1128: return instructorName;
1129: }
1130:
1131: public void setInstructorName(String instructorName) {
1132: this .instructorName = instructorName;
1133: }
1134:
1135: public boolean getForGrade() {
1136: return forGrade;
1137: }
1138:
1139: public void setForGrade(boolean newfor) {
1140: forGrade = newfor;
1141: }
1142:
1143: public String submitForGrade() {
1144: if (this .actionMode == PREVIEW_ASSESSMENT) {
1145: return "editAssessment";
1146: }
1147: String nextAction = checkBeforeProceed();
1148: log.debug("***** next Action=" + nextAction);
1149: if (!("safeToProceed").equals(nextAction)) {
1150: return nextAction;
1151: }
1152:
1153: setForGrade(true);
1154: SessionUtil.setSessionTimeout(
1155: FacesContext.getCurrentInstance(), this , false);
1156:
1157: // submission remaining and totalSubmissionPerAssessmentHash is updated inside
1158: // SubmitToGradingListener
1159: SubmitToGradingActionListener listener = new SubmitToGradingActionListener();
1160: listener.processAction(null);
1161:
1162: // We don't need to call completeItemGradingData to create new ItemGradingData for linear access
1163: // because each ItemGradingData is created when it is viewed/answered
1164: if (!navigation.equals("1")) {
1165: listener.completeItemGradingData();
1166: }
1167: syncTimeElapsedWithServer();
1168:
1169: String returnValue = "submitAssessment";
1170: if (this .actionMode == TAKE_ASSESSMENT_VIA_URL) // this is for accessing via published url
1171: {
1172: returnValue = "anonymousThankYou";
1173: }
1174: forGrade = false;
1175: SelectActionListener l2 = new SelectActionListener();
1176: l2.processAction(null);
1177: reload = true;
1178:
1179: // finish within time limit, clean timedAssessment from queue
1180: removeTimedAssessmentFromQueue();
1181: return returnValue;
1182: }
1183:
1184: public String saveAndExit() {
1185: String nextAction = checkBeforeProceed();
1186: log.debug("***** next Action=" + nextAction);
1187: if (!("safeToProceed").equals(nextAction)) {
1188: return nextAction;
1189: }
1190:
1191: FacesContext context = FacesContext.getCurrentInstance();
1192: SessionUtil.setSessionTimeout(context, this , false);
1193: log
1194: .debug("***DeliverBean.saveAndEXit face context ="
1195: + context);
1196:
1197: forGrade = false;
1198: SubmitToGradingActionListener listener = new SubmitToGradingActionListener();
1199: listener.processAction(null);
1200: syncTimeElapsedWithServer();
1201:
1202: String returnValue = "select";
1203: if (this .actionMode == TAKE_ASSESSMENT_VIA_URL) { // if this is access via url, display quit message
1204: log.debug("**anonymous login, go to quit");
1205: returnValue = "anonymousQuit";
1206: }
1207:
1208: SelectActionListener l2 = new SelectActionListener();
1209: l2.processAction(null);
1210: reload = true;
1211:
1212: // quit within time limit, clean timedAssessment from queue,
1213: // removeTimedAssessmentFromQueue();
1214: return returnValue;
1215: }
1216:
1217: public String next_page() {
1218: String nextAction = checkBeforeProceed();
1219: log.debug("***** next Action=" + nextAction);
1220: if (!("safeToProceed").equals(nextAction)) {
1221: return nextAction;
1222: }
1223:
1224: if (getSettings().isFormatByPart()) {
1225: partIndex++;
1226: }
1227: if (getSettings().isFormatByQuestion()) {
1228: questionIndex++;
1229:
1230: }
1231: forGrade = false;
1232:
1233: if (this .actionMode == TAKE_ASSESSMENT
1234: || this .actionMode == TAKE_ASSESSMENT_VIA_URL) {
1235: SubmitToGradingActionListener listener = new SubmitToGradingActionListener();
1236: listener.processAction(null);
1237: }
1238: syncTimeElapsedWithServer();
1239:
1240: DeliveryActionListener l2 = new DeliveryActionListener();
1241: l2.processAction(null);
1242:
1243: reload = false;
1244: return "takeAssessment";
1245: }
1246:
1247: public String previous() {
1248: String nextAction = checkBeforeProceed();
1249: log.debug("***** next Action=" + nextAction);
1250: if (!("safeToProceed").equals(nextAction)) {
1251: return nextAction;
1252: }
1253:
1254: if (getSettings().isFormatByPart()) {
1255: partIndex--;
1256: questionIndex = 0;
1257: }
1258: if (getSettings().isFormatByQuestion()) {
1259: questionIndex--;
1260:
1261: }
1262: forGrade = false;
1263:
1264: if (this .actionMode == TAKE_ASSESSMENT
1265: || this .actionMode == TAKE_ASSESSMENT_VIA_URL) {
1266: SubmitToGradingActionListener listener = new SubmitToGradingActionListener();
1267: listener.processAction(null);
1268: }
1269: syncTimeElapsedWithServer();
1270:
1271: DeliveryActionListener l2 = new DeliveryActionListener();
1272: l2.processAction(null);
1273:
1274: reload = false;
1275: return "takeAssessment";
1276: }
1277:
1278: // this is the PublishedAccessControl.finalPageUrl
1279: public String getUrl() {
1280: return url;
1281: }
1282:
1283: public void setUrl(String url) {
1284: this .url = url;
1285: }
1286:
1287: public String getConfirmation() {
1288: return confirmation;
1289: }
1290:
1291: public void setConfirmation(String confirmation) {
1292: this .confirmation = confirmation;
1293: }
1294:
1295: /**
1296: * if required, assessment password
1297: * @return password
1298: */
1299: public String getPassword() {
1300: return password;
1301: }
1302:
1303: /**
1304: * if required, assessment password
1305: * @param string assessment password
1306: */
1307: public void setPassword(String string) {
1308: password = string;
1309: }
1310:
1311: public String validatePassword() {
1312: log.debug("**** username=" + username);
1313: log.debug("**** password=" + password);
1314: log.debug("**** setting username="
1315: + getSettings().getUsername());
1316: log.debug("**** setting password="
1317: + getSettings().getPassword());
1318: if (password == null || username == null) {
1319: return "passwordAccessError";
1320: }
1321: if (password.equals(getSettings().getPassword())
1322: && username.equals(getSettings().getUsername())) {
1323: // in post 2.1, clicking at Begin Assessment takes users to the
1324: // 1st question.
1325: return "takeAssessment";
1326: } else {
1327: return "passwordAccessError";
1328: }
1329: }
1330:
1331: public String validateIP() {
1332: String this Ip = ((javax.servlet.http.HttpServletRequest) FacesContext
1333: .getCurrentInstance().getExternalContext().getRequest())
1334: .getRemoteAddr();
1335: Iterator addresses = getSettings().getIpAddresses().iterator();
1336: while (addresses.hasNext()) {
1337: String next = ((PublishedSecuredIPAddress) addresses.next())
1338: .getIpAddress();
1339: if (next != null && next.indexOf("*") > -1) {
1340: next = next.substring(0, next.indexOf("*"));
1341: }
1342: if (next == null || next.trim().equals("")
1343: || this Ip.trim().startsWith(next.trim())) {
1344: // in post 2.1, clicking at Begin Assessment takes users to the
1345: // 1st question.
1346: return "takeAssessment";
1347: }
1348: }
1349: return "ipAccessError";
1350: }
1351:
1352: public String validate() {
1353: // check before proceed
1354: String nextAction = checkBeforeProceed();
1355: log.debug("***** next Action=" + nextAction);
1356: if (!("safeToProceed").equals(nextAction)) {
1357: return nextAction;
1358: }
1359:
1360: try {
1361: String results = "";
1362: // #1. check password
1363: if (!getSettings().getUsername().equals("")) {
1364: results = validatePassword();
1365: log.debug("*** checked password=" + results);
1366: }
1367:
1368: // #2. check IP
1369: if (!results.equals("passwordAccessError")
1370: && getSettings().getIpAddresses() != null
1371: && !getSettings().getIpAddresses().isEmpty()) {
1372: results = validateIP();
1373: log.debug("*** checked password & IP=" + results);
1374: } else { // password error
1375: }
1376:
1377: // #3. results="" => no security checking required
1378: if (results.equals("")) {
1379: // in post 2.1, clicking at Begin Assessment takes users to the
1380: // 1st question.
1381: return "takeAssessment";
1382: }
1383:
1384: // #4. if results != "takeAssessment", stop the clock if it is a timed assessment
1385: // Trouble was the timer was started by DeliveryActionListener before validate() is being run.
1386: // So, we need to remove the timer thread as soon as we realized that the validation fails.
1387: if (!("takeAssessment".equals(results)) && adata != null) {
1388: TimedAssessmentQueue queue = TimedAssessmentQueue
1389: .getInstance();
1390: TimedAssessmentGradingModel timedAG = (TimedAssessmentGradingModel) queue
1391: .get(adata.getAssessmentGradingId());
1392: if (timedAG != null) {
1393: String agTimerId = timedAG.getTimerId();
1394: if (agTimerId != null && agTimerId.equals(timerId)) {
1395: // SAK-6990: it is only safe to removed if u are sure that timedAG is started by your beginAssessment.jsp
1396: // we added a hidden field timerId on beginAssessment.jsp. Upon successful security check, a timedAG
1397: // will be created that carried this timerId. If user open another browser to take the same timed
1398: // assessment. If the security check of the new one fails, it won't stop the clock for existing one.
1399: queue.remove(timedAG);
1400: timeRunning = false;
1401: }
1402: }
1403: }
1404: return results;
1405: } catch (Exception e) {
1406: e.printStackTrace();
1407: return "accessError";
1408: }
1409: }
1410:
1411: public String pvalidate() {
1412: // in post 2.1, clicking at Begin Assessment takes users to the
1413: // 1st question.
1414: return "takeAssessment";
1415: }
1416:
1417: // Skipped paging methods
1418: public int getPartIndex() {
1419: return partIndex;
1420: }
1421:
1422: public void setPartIndex(int newindex) {
1423: partIndex = newindex;
1424: }
1425:
1426: public int getQuestionIndex() {
1427: return questionIndex;
1428: }
1429:
1430: public void setQuestionIndex(int newindex) {
1431: questionIndex = newindex;
1432: }
1433:
1434: public boolean getContinue() {
1435: return next_page;
1436: }
1437:
1438: public void setContinue(boolean docontinue) {
1439: next_page = docontinue;
1440: }
1441:
1442: public boolean getReload() {
1443: return reload;
1444: }
1445:
1446: public void setReload(boolean doreload) {
1447: reload = doreload;
1448: }
1449:
1450: // Store for paging
1451: public AssessmentGradingData getAssessmentGrading() {
1452: return adata;
1453: }
1454:
1455: public void setAssessmentGrading(AssessmentGradingData newdata) {
1456: adata = newdata;
1457: }
1458:
1459: private byte[] getMediaStream(String mediaLocation) {
1460: FileInputStream mediaStream = null;
1461: FileInputStream mediaStream2 = null;
1462: byte[] mediaByte = new byte[0];
1463: try {
1464: int i;
1465: int size = 0;
1466: mediaStream = new FileInputStream(mediaLocation);
1467: if (mediaStream != null) {
1468: while ((i = mediaStream.read()) != -1) {
1469: size++;
1470: }
1471: }
1472: mediaStream2 = new FileInputStream(mediaLocation);
1473: mediaByte = new byte[size];
1474: if (mediaStream2 != null) {
1475: mediaStream2.read(mediaByte, 0, size);
1476: }
1477: } catch (FileNotFoundException ex) {
1478: log.error("file not found=" + ex.getMessage());
1479: } catch (IOException ex) {
1480: log.error("io exception=" + ex.getMessage());
1481: } finally {
1482: if (mediaStream != null) {
1483: try {
1484: mediaStream.close();
1485: } catch (IOException ex1) {
1486: log.warn(ex1.getMessage());
1487: }
1488: }
1489: }
1490: if (mediaStream2 != null) {
1491: try {
1492: mediaStream2.close();
1493: } catch (IOException ex1) {
1494: log.warn(ex1.getMessage());
1495: }
1496: }
1497: return mediaByte;
1498: }
1499:
1500: /**
1501: * This method is used by jsf/delivery/deliveryFileUpload.jsp
1502: * <corejsf:upload
1503: * target="/jsf/upload_tmp/assessment#{delivery.assessmentId}/
1504: * question#{question.itemData.itemId}/admin"
1505: * valueChangeListener="#{delivery.addMediaToItemGrading}" />
1506: */
1507: public void addMediaToItemGrading(
1508: javax.faces.event.ValueChangeEvent e) {
1509: if (isTimeRunning() && timeExpired())
1510: setOutcome("timeExpired");
1511:
1512: String mediaLocation = (String) e.getNewValue();
1513: String action = addMediaToItemGrading(mediaLocation);
1514: syncTimeElapsedWithServer();
1515: log
1516: .debug("****time passed after fileupload before loading of next question"
1517: + getTimeElapse());
1518: setTimeElapseAfterFileUpload(getTimeElapse());
1519: setOutcome(action);
1520: }
1521:
1522: /**
1523: * This method is used by jsf/delivery/deliverAudioRecording.jsp and
1524: * is called by addMediaToItemGrading(javax.faces.event.ValueChangeEvent e)
1525: *
1526: * @param mediaLocation the media location
1527: * @return the action string
1528: */
1529: public String addMediaToItemGrading(String mediaLocation) {
1530: log.debug("****" + mediaLocation + " " + (new Date()));
1531: GradingService gradingService = new GradingService();
1532: //PublishedAssessmentService publishedService = new PublishedAssessmentService();
1533: HashMap itemHash = getPublishedItemHash();
1534: PersonBean person = (PersonBean) ContextUtil
1535: .lookupBean("person");
1536: String agent = person.getId();
1537:
1538: // 2. format of the media location is: assessmentXXX/questionXXX/agentId/myfile
1539: // 3. get the questionId (which is the PublishedItemData.itemId)
1540: //int assessmentIndex = mediaLocation.indexOf("assessment");
1541: int questionIndex = mediaLocation.indexOf("question");
1542: int agentIndex = mediaLocation.indexOf("/", questionIndex + 8);
1543: int myfileIndex = mediaLocation.lastIndexOf("/");
1544: //cwen
1545: if (agentIndex < 0) {
1546: agentIndex = mediaLocation.indexOf("\\", questionIndex + 8);
1547: }
1548: //String pubAssessmentId = mediaLocation.substring(assessmentIndex + 10, questionIndex - 1);
1549: String questionId = mediaLocation.substring(questionIndex + 8,
1550: agentIndex);
1551: log.debug("***3a. addMediaToItemGrading, questionId ="
1552: + questionId);
1553: log.debug("***3b. addMediaToItemGrading, assessmentId ="
1554: + assessmentId);
1555: if (agent == null) {
1556: String agentId = mediaLocation.substring(agentIndex,
1557: myfileIndex - 1);
1558: log.debug("**** agentId=" + agentId);
1559: agent = agentId;
1560: }
1561: log.debug("***3c. addMediaToItemGrading, agent =" + agent);
1562:
1563: // 4. prepare itemGradingData and attach it to assessmentGarding
1564: PublishedItemData item = (PublishedItemData) itemHash
1565: .get(new Long(questionId));
1566: log.debug("***4a. addMediaToItemGrading, itemText(0) ="
1567: + item.getItemTextArray().get(0));
1568: // there is only one text in audio question
1569: PublishedItemText itemText = (PublishedItemText) item
1570: .getItemTextArraySorted().get(0);
1571: ItemGradingData itemGradingData = getItemGradingData(questionId);
1572: boolean newItemGradingData = false;
1573: if (itemGradingData == null) {
1574: newItemGradingData = true;
1575: itemGradingData = new ItemGradingData();
1576: itemGradingData.setAssessmentGradingId(adata
1577: .getAssessmentGradingId());
1578: itemGradingData.setPublishedItemId(item.getItemId());
1579: itemGradingData.setPublishedItemTextId(itemText.getId());
1580: itemGradingData.setSubmittedDate(new Date());
1581: itemGradingData.setAgentId(agent);
1582: itemGradingData.setOverrideScore(new Float(0));
1583: }
1584: setAssessmentGrading(adata);
1585:
1586: // 5. save ItemGradingData alone 'cos assessmentGrading score won't be changed
1587: // we don't need to update every itemGrading in assessmentGrading
1588: gradingService.saveItemGrading(itemGradingData);
1589:
1590: //if media is uploaded, create media record and attach to itemGradingData
1591: if (mediaIsValid())
1592: saveMedia(agent, mediaLocation, itemGradingData,
1593: gradingService);
1594:
1595: // 8. do whatever need doing
1596: DeliveryActionListener dlistener = new DeliveryActionListener();
1597: // false => do not reset the entire current delivery.pageContents.
1598: // we will do it ourselves and only update the question that this media
1599: // is attached to
1600: dlistener.processAction(null, false);
1601: if (newItemGradingData)
1602: attachToItemContentBean(itemGradingData, questionId);
1603:
1604: reload = true;
1605: return "takeAssessment"; // which doesn't exists to force it to reload
1606:
1607: }
1608:
1609: public void saveMedia(String agent, String mediaLocation,
1610: ItemGradingData itemGradingData,
1611: GradingService gradingService) {
1612: // 1. create a media record
1613: File media = new File(mediaLocation);
1614: byte[] mediaByte = getMediaStream(mediaLocation);
1615: String mimeType = MimeTypesLocator.getInstance()
1616: .getContentType(media);
1617: boolean SAVETODB = getSaveToDb();
1618: log.debug("**** SAVETODB=" + SAVETODB);
1619: MediaData mediaData = null;
1620: log.debug("***6a. addMediaToItemGrading, itemGradinDataId="
1621: + itemGradingData.getItemGradingId());
1622: // 1b. get filename
1623: String fullname = media.getName();
1624: int underscore_index = fullname.lastIndexOf("_");
1625: int dot_index = fullname.lastIndexOf(".");
1626: String filename = fullname.substring(0, underscore_index);
1627: filename = filename + fullname.substring(dot_index);
1628: log.debug("**** filename=" + filename);
1629:
1630: if (SAVETODB) { // put the byte[] in
1631: mediaData = new MediaData(itemGradingData, mediaByte,
1632: new Long(mediaByte.length + ""), mimeType,
1633: "description", null, filename, false, false,
1634: new Integer(1), agent, new Date(), agent,
1635: new Date(), null);
1636: } else { // put the location in
1637: mediaData = new MediaData(itemGradingData, null, new Long(
1638: mediaByte.length + ""), mimeType, "description",
1639: mediaLocation, filename, false, false, new Integer(
1640: 1), agent, new Date(), agent, new Date(),
1641: null);
1642:
1643: }
1644: Long mediaId = gradingService.saveMedia(mediaData);
1645: log.debug("mediaId=" + mediaId);
1646: log
1647: .debug("***6c. addMediaToItemGrading, media.itemGradinDataId="
1648: + ((ItemGradingData) mediaData
1649: .getItemGradingData())
1650: .getItemGradingId());
1651: log.debug("***6d. addMediaToItemGrading, mediaId="
1652: + mediaData.getMediaId());
1653:
1654: // 2. store mediaId in itemGradingRecord.answerText
1655: log.debug("***7. addMediaToItemGrading, adata=" + adata);
1656: itemGradingData.setAnswerText(mediaId + "");
1657: gradingService.saveItemGrading(itemGradingData);
1658: // 3. if saveToDB, remove file from file system
1659: try {
1660: if (SAVETODB)
1661: media.delete();
1662: } catch (Exception e) {
1663: log.warn(e.getMessage());
1664: }
1665: }
1666:
1667: public boolean mediaIsValid() {
1668: boolean returnValue = true;
1669: // check if file is too big
1670: FacesContext context = FacesContext.getCurrentInstance();
1671: ExternalContext external = context.getExternalContext();
1672: Long fileSize = (Long) ((ServletContext) external.getContext())
1673: .getAttribute("TEMP_FILEUPLOAD_SIZE");
1674: Long maxSize = (Long) ((ServletContext) external.getContext())
1675: .getAttribute("FILEUPLOAD_SIZE_MAX");
1676: //log.info("**** filesize is ="+fileSize);
1677: //log.info("**** maxsize is ="+maxSize);
1678: ((ServletContext) external.getContext())
1679: .removeAttribute("TEMP_FILEUPLOAD_SIZE");
1680: if (fileSize != null) {
1681: float fileSize_float = fileSize.floatValue() / 1024;
1682: int tmp = Math.round(fileSize_float * 10.0f);
1683: fileSize_float = (float) tmp / 10.0f;
1684: float maxSize_float = maxSize.floatValue() / 1024;
1685: int tmp0 = Math.round(maxSize_float * 10.0f);
1686: maxSize_float = (float) tmp0 / 10.0f;
1687:
1688: String err1 = (String) ContextUtil
1689: .getLocalizedString(
1690: "org.sakaiproject.tool.assessment.bundle.DeliveryMessages",
1691: "file_upload_error");
1692: String err2 = (String) ContextUtil
1693: .getLocalizedString(
1694: "org.sakaiproject.tool.assessment.bundle.DeliveryMessages",
1695: "file_uploaded");
1696: String err3 = (String) ContextUtil
1697: .getLocalizedString(
1698: "org.sakaiproject.tool.assessment.bundle.DeliveryMessages",
1699: "max_size_allowed");
1700: String err4 = (String) ContextUtil
1701: .getLocalizedString(
1702: "org.sakaiproject.tool.assessment.bundle.DeliveryMessages",
1703: "upload_again");
1704: String err = err2 + fileSize_float + err3 + maxSize_float
1705: + err4;
1706: context.addMessage("file_upload_error", new FacesMessage(
1707: err1));
1708: context.addMessage("file_upload_error", new FacesMessage(
1709: err));
1710: returnValue = false;
1711: }
1712: return returnValue;
1713: }
1714:
1715: public boolean getNotTakeable() {
1716: return notTakeable;
1717: }
1718:
1719: public void setNotTakeable(boolean notTakeable) {
1720: this .notTakeable = notTakeable;
1721: }
1722:
1723: public boolean getPastDue() {
1724: return pastDue;
1725: }
1726:
1727: public void setPastDue(boolean pastDue) {
1728: this .pastDue = pastDue;
1729: }
1730:
1731: public long getSubTime() {
1732: return subTime;
1733: }
1734:
1735: public void setSubTime(long newSubTime) {
1736: subTime = newSubTime;
1737: }
1738:
1739: public String getSubmissionHours() {
1740: return takenHours;
1741: }
1742:
1743: public void setSubmissionHours(String newHours) {
1744: takenHours = newHours;
1745: }
1746:
1747: public String getSubmissionMinutes() {
1748: return takenMinutes;
1749: }
1750:
1751: public void setSubmissionMinutes(String newMinutes) {
1752: takenMinutes = newMinutes;
1753: }
1754:
1755: public PublishedAssessmentFacade getPublishedAssessment() {
1756: return publishedAssessment;
1757: }
1758:
1759: public void setPublishedAssessment(
1760: PublishedAssessmentFacade publishedAssessment) {
1761: this .publishedAssessment = publishedAssessment;
1762: }
1763:
1764: public java.util.Date getFeedbackDate() {
1765: return feedbackDate;
1766: }
1767:
1768: public String getFeedbackDateString() {
1769: String dateString = "";
1770: if (feedbackDate == null) {
1771: return dateString;
1772: }
1773:
1774: try {
1775: TimeUtil tu = new TimeUtil();
1776: dateString = tu.getDisplayDateTime(displayFormat,
1777: feedbackDate);
1778: } catch (Exception ex) {
1779: // we will leave it as an empty string
1780: log.warn("Unable to format date.");
1781: ex.printStackTrace();
1782: }
1783: return dateString;
1784: }
1785:
1786: public void setFeedbackDate(java.util.Date feedbackDate) {
1787: this .feedbackDate = feedbackDate;
1788: }
1789:
1790: public String getFeedbackDelivery() {
1791: return feedbackDelivery;
1792: }
1793:
1794: public void setFeedbackDelivery(String feedbackDelivery) {
1795: this .feedbackDelivery = feedbackDelivery;
1796: }
1797:
1798: public String getShowScore() {
1799: return showScore;
1800: }
1801:
1802: public void setShowScore(String showScore) {
1803: this .showScore = showScore;
1804: }
1805:
1806: public boolean getHasTimeLimit() {
1807: return hasTimeLimit;
1808: }
1809:
1810: public void setHasTimeLimit(boolean hasTimeLimit) {
1811: this .hasTimeLimit = hasTimeLimit;
1812: }
1813:
1814: public String getOutcome() {
1815: return outcome;
1816: }
1817:
1818: public void setOutcome(String outcome) {
1819: this .outcome = outcome;
1820: }
1821:
1822: public String doit() {
1823: return outcome;
1824: }
1825:
1826: public boolean getAnonymousLogin() {
1827: return anonymousLogin;
1828: }
1829:
1830: public void setAnonymousLogin(boolean anonymousLogin) {
1831: this .anonymousLogin = anonymousLogin;
1832: }
1833:
1834: public ItemGradingData getItemGradingData(String publishedItemId) {
1835: ItemGradingData selected = null;
1836: if (adata != null) {
1837: Set items = adata.getItemGradingSet();
1838: if (items != null) {
1839: Iterator iter = items.iterator();
1840: while (iter.hasNext()) {
1841: ItemGradingData itemGradingData = (ItemGradingData) iter
1842: .next();
1843: String itemPublishedId = itemGradingData
1844: .getPublishedItemId().toString();
1845: if ((publishedItemId).equals(itemPublishedId)) {
1846: log
1847: .debug("*** addMediaToItemGrading, same : found it");
1848: selected = itemGradingData;
1849: } else {
1850: log
1851: .debug("*** addMediaToItemGrading, not the same");
1852: }
1853: }
1854: log
1855: .debug("*** addMediaToItemGrading, publishedItemId ="
1856: + publishedItemId);
1857: if (selected != null) {
1858: log
1859: .debug("*** addMediaToItemGrading, itemGradingData.publishedItemId ="
1860: + selected.getPublishedItemId()
1861: .toString());
1862: }
1863: }
1864: }
1865: return selected;
1866: }
1867:
1868: public String getContextPath() {
1869: return contextPath;
1870: }
1871:
1872: public void setContextPath(String contextPath) {
1873: this .contextPath = contextPath;
1874: }
1875:
1876: public boolean isShowStudentScore() {
1877: return showStudentScore;
1878: }
1879:
1880: public void setShowStudentScore(boolean showStudentScore) {
1881: this .showStudentScore = showStudentScore;
1882: }
1883:
1884: public boolean isShowStudentQuestionScore() {
1885: return showStudentQuestionScore;
1886: }
1887:
1888: public void setShowStudentQuestionScore(boolean param) {
1889: this .showStudentQuestionScore = param;
1890: }
1891:
1892: public boolean isTimeRunning() {
1893: return timeRunning;
1894: }
1895:
1896: public void setTimeRunning(boolean timeRunning) {
1897: this .timeRunning = timeRunning;
1898: }
1899:
1900: /**
1901: * Used for a JavaScript enable check.
1902: */
1903: public String getJavaScriptEnabledCheck() {
1904: return this .javaScriptEnabledCheck;
1905: }
1906:
1907: /**
1908: * Used for a JavaScript enable check.
1909: */
1910: public void setJavaScriptEnabledCheck(String javaScriptEnabledCheck) {
1911: this .javaScriptEnabledCheck = javaScriptEnabledCheck;
1912: }
1913:
1914: //cwen
1915: public void setSiteId(String siteId) {
1916: this .siteId = siteId;
1917: }
1918:
1919: public String getSiteId() {
1920: siteId = null;
1921: Placement currentPlacement = ToolManager.getCurrentPlacement();
1922: if (currentPlacement != null)
1923: siteId = currentPlacement.getContext();
1924: return siteId;
1925: }
1926:
1927: public String getAgentAccessString() {
1928: return deliveryAgent.getAgentInstanceString();
1929: }
1930:
1931: public void setAgentAccessString(String agentString) {
1932: deliveryAgent.setAgentInstanceString(agentString);
1933: }
1934:
1935: public boolean getSaveToDb() {
1936: FacesContext context = FacesContext.getCurrentInstance();
1937: ExternalContext external = context.getExternalContext();
1938: String saveToDb = (String) ((ServletContext) external
1939: .getContext())
1940: .getAttribute("FILEUPLOAD_SAVE_MEDIA_TO_DB");
1941: if (("true").equals(saveToDb))
1942: return true;
1943: else
1944: return false;
1945: }
1946:
1947: public void attachToItemContentBean(
1948: ItemGradingData itemGradingData, String questionId) {
1949: ArrayList list = new ArrayList();
1950: list.add(itemGradingData);
1951: //find out sectionId from questionId
1952: log.debug("**** attachToItemContentBean, questionId="
1953: + questionId);
1954: /*
1955: PublishedAssessmentService publishedService = new
1956: PublishedAssessmentService();
1957: PublishedItemData publishedItem = publishedService.
1958: loadPublishedItem(questionId);
1959: */
1960: PublishedItemData publishedItem = (PublishedItemData) getPublishedItemHash()
1961: .get(new Long(questionId));
1962: PublishedSectionData publishedSection = (PublishedSectionData) publishedItem
1963: .getSection();
1964: String sectionId = publishedSection.getSectionId().toString();
1965: SectionContentsBean partSelected = null;
1966:
1967: //get all partContents
1968: ArrayList parts = getPageContents().getPartsContents();
1969: for (int i = 0; i < parts.size(); i++) {
1970: SectionContentsBean part = (SectionContentsBean) parts
1971: .get(i);
1972: log.debug("**** question's sectionId" + sectionId);
1973: log.debug("**** partId" + part.getSectionId());
1974: if (sectionId.equals(part.getSectionId())) {
1975: partSelected = part;
1976: break;
1977: }
1978: }
1979: //locate the itemContentBean - the hard way, sigh...
1980: ArrayList items = new ArrayList();
1981: if (partSelected != null)
1982: items = partSelected.getItemContents();
1983: for (int j = 0; j < items.size(); j++) {
1984: ItemContentsBean item = (ItemContentsBean) items.get(j);
1985: if ((publishedItem.getItemId()).equals(item.getItemData()
1986: .getItemId())) { // comparing itemId not object
1987: item.setItemGradingDataArray(list);
1988: break;
1989: }
1990: }
1991: }
1992:
1993: // delivery action
1994: public static final int TAKE_ASSESSMENT = 1;
1995: public static final int PREVIEW_ASSESSMENT = 2;
1996: public static final int REVIEW_ASSESSMENT = 3;
1997: public static final int GRADE_ASSESSMENT = 4;
1998: public static final int TAKE_ASSESSMENT_VIA_URL = 5;
1999: private int actionMode;
2000: private String actionString;
2001:
2002: public void setActionString(String actionString) {
2003: this .actionString = actionString;
2004: // the follwoing two values will be evaluated when reviewing assessment
2005: // based on PublishedFeedback settings
2006: setFeedback("false");
2007: setNoFeedback("true");
2008:
2009: if (("previewAssessment").equals(actionString)) {
2010: setActionMode(PREVIEW_ASSESSMENT);
2011: } else if (("reviewAssessment").equals(actionString)) {
2012: setActionMode(REVIEW_ASSESSMENT);
2013: } else if (("gradeAssessment").equals(actionString)) {
2014: setFeedback("true");
2015: setNoFeedback("false");
2016: setActionMode(GRADE_ASSESSMENT);
2017: } else if (("takeAssessment").equals(actionString)) {
2018: setActionMode(TAKE_ASSESSMENT);
2019: } else if (("takeAssessmentViaUrl").equals(actionString)) {
2020: setActionMode(TAKE_ASSESSMENT_VIA_URL);
2021: }
2022: }
2023:
2024: public String getActionString() {
2025: return actionString;
2026: }
2027:
2028: private void setActionMode(int actionMode) {
2029: this .actionMode = actionMode;
2030: }
2031:
2032: public int getActionMode() {
2033: return actionMode;
2034: }
2035:
2036: private long time = 0;
2037:
2038: public void setLastTimer(long time) {
2039: this .time = time;
2040: }
2041:
2042: public long getLastTimer() {
2043: return time;
2044: }
2045:
2046: public boolean getBeginAssessment() {
2047: return beginAssessment;
2048: }
2049:
2050: public void setBeginAssessment(boolean beginAssessment) {
2051: this .beginAssessment = beginAssessment;
2052: }
2053:
2054: public boolean timeExpired() {
2055: boolean timeExpired = false;
2056: TimedAssessmentQueue queue = TimedAssessmentQueue.getInstance();
2057: TimedAssessmentGradingModel timedAG = (TimedAssessmentGradingModel) queue
2058: .get(adata.getAssessmentGradingId());
2059: if (timedAG != null) {
2060: // if server already submit the assessment, this happen if JScript latency is very long
2061: // and assessment passed the time left + latency buffer
2062: // in this case, we will display the time expired message.
2063: if (timedAG.getSubmittedForGrade()) {
2064: timeExpired = true;
2065: queue.remove(timedAG);
2066: }
2067: } else {
2068: // null => not only does the assessment miss the latency buffer, it also missed the
2069: // transaction buffer
2070: timeExpired = true;
2071: }
2072: return timeExpired;
2073: }
2074:
2075: private void removeTimedAssessmentFromQueue() {
2076: TimedAssessmentQueue queue = TimedAssessmentQueue.getInstance();
2077: TimedAssessmentGradingModel timedAG = (TimedAssessmentGradingModel) queue
2078: .get(adata.getAssessmentGradingId());
2079: if (timedAG != null) {
2080: queue.remove(timedAG);
2081: timeRunning = false;
2082: }
2083: }
2084:
2085: public void syncTimeElapsedWithServer() {
2086: if (("takeAssessment").equals(actionString)
2087: || ("takeAssessmentViaUrl").equals(actionString)) {
2088: TimedAssessmentQueue queue = TimedAssessmentQueue
2089: .getInstance();
2090: TimedAssessmentGradingModel timedAG = queue.get(adata
2091: .getAssessmentGradingId());
2092: if (timedAG != null) {
2093: int timeElapsed = Math
2094: .round(((new Date()).getTime() - timedAG
2095: .getBeginDate().getTime()) / 1000); //in sec
2096: // this is to cover the scenerio when user took an assessment, Save & Exit, Then returned at a
2097: // later time, we need to account for the time taht he used before
2098: int timeTakenBefore = Math.round(timedAG.getTimeLimit()
2099: - timedAG.getTimeLeft()); // in sec
2100: //log.debug("***time passed afer saving answer to DB="+timeElapsed+timeTakenBefore);
2101: adata.setTimeElapsed(new Integer(timeElapsed
2102: + timeTakenBefore));
2103: GradingService gradingService = new GradingService();
2104: gradingService.saveOrUpdateAssessmentGrading(adata);
2105: setTimeElapse(adata.getTimeElapsed().toString());
2106: }
2107: } else {
2108: // if we are in other mode, timer need not be accurate
2109: // Anyway, we don't have adata, so we haven't been using the TimerTask to keep track of it.
2110: }
2111: }
2112:
2113: public void syncTimeElapsedWithServerLinear() {
2114: if (("takeAssessment").equals(actionString)
2115: || ("takeAssessmentViaUrl").equals(actionString)) {
2116: TimedAssessmentQueue queue = TimedAssessmentQueue
2117: .getInstance();
2118: TimedAssessmentGradingModel timedAG = queue.get(adata
2119: .getAssessmentGradingId());
2120: if (timedAG != null) {
2121: int timeElapsed = Math
2122: .round(((new Date()).getTime() - timedAG
2123: .getBeginDate().getTime()) / 1000); //in sec
2124: // this is to cover the scenerio when user took an assessment, Save & Exit, Then returned at a
2125: // later time, we need to account for the time taht he used before
2126: int timeTakenBefore = Math.round(timedAG.getTimeLimit()
2127: - timedAG.getTimeLeft()); // in sec
2128: //log.debug("***time passed afer saving answer to DB="+timeElapsed+timeTakenBefore);
2129: adata.setTimeElapsed(new Integer(timeElapsed
2130: + timeTakenBefore));
2131: GradingService gradingService = new GradingService();
2132: gradingService.saveOrUpdateAssessmentGradingOnly(adata);
2133: setTimeElapse(adata.getTimeElapsed().toString());
2134: }
2135: } else {
2136: // if we are in other mode, timer need not be accurate
2137: // Anyway, we don't have adata, so we haven't been using the TimerTask to keep track of it.
2138: }
2139: }
2140:
2141: private String timeElapseAfterFileUpload;
2142:
2143: public String getTimeElapseAfterFileUpload() {
2144: return timeElapseAfterFileUpload;
2145: }
2146:
2147: public void setTimeElapseAfterFileUpload(
2148: String timeElapseAfterFileUpload) {
2149: this .timeElapseAfterFileUpload = timeElapseAfterFileUpload;
2150: if (timeElapseAfterFileUpload != null
2151: && !("").equals(timeElapseAfterFileUpload))
2152: setTimeElapseAfterFileUploadFloat((new Float(
2153: timeElapseAfterFileUpload)).floatValue());
2154: }
2155:
2156: private float timeElapseFloat = 0;
2157:
2158: public float getTimeElapseFloat() {
2159: return timeElapseFloat;
2160: }
2161:
2162: public void setTimeElapseFloat(float timeElapseFloat) {
2163: this .timeElapseFloat = timeElapseFloat;
2164: }
2165:
2166: private float timeElapseAfterFileUploadFloat;
2167:
2168: public float getTimeElapseAfterFileUploadFloat() {
2169: return timeElapseAfterFileUploadFloat;
2170: }
2171:
2172: public void setTimeElapseAfterFileUploadFloat(
2173: float timeElapseAfterFileUploadFloat) {
2174: this .timeElapseAfterFileUploadFloat = timeElapseAfterFileUploadFloat;
2175: }
2176:
2177: private String protocol;
2178:
2179: public String getProtocol() {
2180: return protocol;
2181: }
2182:
2183: public void setProtocol(String protocol) {
2184: this .protocol = protocol;
2185: }
2186:
2187: private long timeStamp;
2188:
2189: public long getTimeStamp() {
2190: return timeStamp;
2191: }
2192:
2193: public void setTimeStamp(long timeStamp) {
2194: this .timeStamp = timeStamp;
2195: }
2196:
2197: private HashMap publishedItemHash = new HashMap();
2198:
2199: public HashMap getPublishedItemHash() {
2200: if (this .publishedItemHash.size() == 0) {
2201: PublishedAssessmentService pubService = new PublishedAssessmentService();
2202: this .publishedItemHash = pubService
2203: .preparePublishedItemHash(getPublishedAssessment());
2204: }
2205: return this .publishedItemHash;
2206: }
2207:
2208: public void setPublishedItemHash(HashMap publishedItemHash) {
2209: this .publishedItemHash = publishedItemHash;
2210: }
2211:
2212: private HashMap publishedItemTextHash = new HashMap();
2213:
2214: public HashMap getPublishedItemTextHash() {
2215: if (this .publishedItemTextHash.size() == 0) {
2216: PublishedAssessmentService pubService = new PublishedAssessmentService();
2217: this .publishedItemTextHash = pubService
2218: .preparePublishedItemTextHash(getPublishedAssessment());
2219: }
2220: return this .publishedItemTextHash;
2221: }
2222:
2223: public void setPublishedItemTextHash(HashMap publishedItemTextHash) {
2224: this .publishedItemTextHash = publishedItemTextHash;
2225: }
2226:
2227: private HashMap publishedAnswerHash = new HashMap();
2228:
2229: public HashMap getPublishedAnswerHash() {
2230: if (this .publishedAnswerHash.size() == 0) {
2231: PublishedAssessmentService pubService = new PublishedAssessmentService();
2232: this .publishedAnswerHash = pubService
2233: .preparePublishedAnswerHash(getPublishedAssessment());
2234: }
2235: return this .publishedAnswerHash;
2236: }
2237:
2238: public void setPublishedAnswerHash(HashMap publishedAnswerHash) {
2239: this .publishedAnswerHash = publishedAnswerHash;
2240: }
2241:
2242: public boolean getIsMoreThanOneQuestion() {
2243: log.debug("getIsMoreThanOneQuestion() starts");
2244: ArrayList partsContents = this .pageContents.getPartsContents();
2245: if (partsContents.size() == 1) {
2246: String size = ((SectionContentsBean) partsContents.get(0))
2247: .getItemContentsSize();
2248: log.debug("ItemContentsSize = " + size);
2249: if (size.equals("1")) {
2250: log.debug("isMoreThanOneQuestion set to false");
2251: isMoreThanOneQuestion = false;
2252: }
2253: } else {
2254: log.debug("isMoreThanOneQuestion set to true");
2255: isMoreThanOneQuestion = true;
2256: }
2257: return isMoreThanOneQuestion;
2258: }
2259:
2260: private List attachmentList;
2261:
2262: public List getAttachmentList() {
2263: return attachmentList;
2264: }
2265:
2266: public void setAttachmentList(List attachmentList) {
2267: this .attachmentList = attachmentList;
2268: }
2269:
2270: private boolean hasAttachment = false;
2271:
2272: public boolean getHasAttachment() {
2273: boolean hasAttachment = false;
2274: if (attachmentList != null && attachmentList.size() > 0) {
2275: hasAttachment = true;
2276: }
2277: return hasAttachment;
2278: }
2279:
2280: public boolean getNoQuestions() {
2281: return noQuestions;
2282: }
2283:
2284: public void setNoQuestions(boolean noQuestions) {
2285: this .noQuestions = noQuestions;
2286: }
2287:
2288: public String checkBeforeProceed() {
2289: // public method, who know if publishedAssessment is set, so check
2290: // to be sure
2291: if (getPublishedAssessment() == null) {
2292: return "error";
2293: }
2294:
2295: GradingService service = new GradingService();
2296: AssessmentGradingData assessmentGrading = null;
2297: if (adata != null) {
2298: assessmentGrading = service.load(adata
2299: .getAssessmentGradingId().toString());
2300: }
2301: PublishedAssessmentService pubService = new PublishedAssessmentService();
2302: int totalSubmitted = (pubService.getTotalSubmission(AgentFacade
2303: .getAgentString(), getPublishedAssessment()
2304: .getPublishedAssessmentId().toString())).intValue();
2305: log.debug("***totalSubmitted=" + totalSubmitted);
2306:
2307: log.debug("check 0");
2308: // check 0: check for start date
2309: if (!isAvailable()) {
2310: return ("assessmentNotAvailable");
2311: }
2312:
2313: log.debug("check 1");
2314: // check 1: check for multiple window & browser trick
2315: if (assessmentGrading != null
2316: && !checkDataIntegrity(assessmentGrading)) {
2317: return ("discrepancyInData");
2318: }
2319:
2320: log.debug("check 2");
2321: // check 2: if workingassessment has been submiited?
2322: // this is to prevent student submit assessment and use a 2nd window to
2323: // continue working on the submitted work.
2324: if (assessmentGrading != null
2325: && getAssessmentHasBeenSubmitted(assessmentGrading)) {
2326: return "assessmentHasBeenSubmitted";
2327: }
2328:
2329: GradingService gradingService = new GradingService();
2330: int numberRetake = gradingService.getNumberRetake(
2331: publishedAssessment.getPublishedAssessmentId(),
2332: AgentFacade.getAgentString());
2333: log.debug("check 3");
2334: // check 3: any submission attempt left?
2335: if (!getHasSubmissionLeft(totalSubmitted, numberRetake)) {
2336: return "noSubmissionLeft";
2337: }
2338:
2339: log.debug("check 4");
2340: // check 4: accept late submission?
2341: boolean acceptLateSubmission = AssessmentAccessControlIfc.ACCEPT_LATE_SUBMISSION
2342: .equals(publishedAssessment
2343: .getAssessmentAccessControl().getLateHandling());
2344:
2345: log.debug("check 5");
2346: // check 5: has dueDate arrived? if so, does it allow late submission?
2347: // If it is a timed assessment and "No Late Submission", always go through. Because in this case the
2348: // assessment will be auto-submitted anyway - when time is up or
2349: // when current date reaches due date (if the time limited is longer than due date,) for either case, we
2350: // want to redirect to the normal "submision successful page" after submitting.
2351: if (pastDueDate()) {
2352: if (acceptLateSubmission) {
2353: if (totalSubmitted != 0) {
2354: int actualNumberRetake = gradingService
2355: .getActualNumberRetake(publishedAssessment
2356: .getPublishedAssessmentId(),
2357: AgentFacade.getAgentString());
2358: log.debug("actualNumberRetake ="
2359: + actualNumberRetake);
2360: if (actualNumberRetake == numberRetake) {
2361: return "noLateSubmission";
2362: }
2363: }
2364: } else {
2365: if (!this .isTimedAssessment()) {
2366: return "noLateSubmission";
2367: }
2368: }
2369: }
2370:
2371: log.debug("check 6");
2372: // check 6: is it still available?
2373: if (isRetracted()) {
2374: return "isRetracted";
2375: }
2376:
2377: log.debug("check 7");
2378: // check 7: is timed assessment? and time has expired?
2379: if (isTimeRunning() && timeExpired()) {
2380: return "timeExpired";
2381: } else
2382: return "safeToProceed";
2383: }
2384:
2385: private boolean getHasSubmissionLeft(int totalSubmitted,
2386: int numberRetake) {
2387: boolean hasSubmissionLeft = false;
2388: int maxSubmissionsAllowed = 9999;
2389: if ((Boolean.FALSE)
2390: .equals(publishedAssessment
2391: .getAssessmentAccessControl()
2392: .getUnlimitedSubmissions())) {
2393: maxSubmissionsAllowed = publishedAssessment
2394: .getAssessmentAccessControl()
2395: .getSubmissionsAllowed().intValue();
2396: }
2397: if (totalSubmitted < maxSubmissionsAllowed + numberRetake) {
2398: hasSubmissionLeft = true;
2399: }
2400: return hasSubmissionLeft;
2401: }
2402:
2403: private boolean isAvailable() {
2404: boolean isAvailable = true;
2405: Date currentDate = new Date();
2406: Date startDate = publishedAssessment
2407: .getAssessmentAccessControl().getStartDate();
2408: if (startDate != null && startDate.after(currentDate)) {
2409: isAvailable = false;
2410: }
2411: return isAvailable;
2412: }
2413:
2414: private boolean pastDueDate() {
2415: boolean pastDue = true;
2416: Date currentDate = new Date();
2417: Date dueDate = publishedAssessment.getAssessmentAccessControl()
2418: .getDueDate();
2419: if (dueDate == null || dueDate.after(currentDate)) {
2420: pastDue = false;
2421: }
2422: return pastDue;
2423: }
2424:
2425: private boolean isRetracted() {
2426: boolean isRetracted = true;
2427: Date currentDate = new Date();
2428: Date retractDate = publishedAssessment
2429: .getAssessmentAccessControl().getRetractDate();
2430: if (retractDate == null || retractDate.after(currentDate)) {
2431: isRetracted = false;
2432: }
2433: return isRetracted;
2434: }
2435:
2436: private boolean checkDataIntegrity(
2437: AssessmentGradingData assessmentGrading) {
2438: // get assessmentGrading from DB, this is to avoid same assessment being
2439: // opened in the differnt browser
2440: if (assessmentGrading != null) {
2441: long DBdate = 0;
2442: if (assessmentGrading.getSubmittedDate() != null) {
2443: DBdate = assessmentGrading.getSubmittedDate().getTime();
2444: }
2445: String browserDateString = ContextUtil
2446: .lookupParam("lastSubmittedDate1");
2447: if (browserDateString == null) {
2448: browserDateString = ContextUtil
2449: .lookupParam("lastSubmittedDate2");
2450: }
2451:
2452: // SAK-7106:jsf doesn't like id with same name even though there is a rendering condition there
2453: // so we have to use 2 differnt id and check it this way instead.
2454: long browserDate = 0;
2455: try {
2456: if (browserDateString != null) {
2457: browserDate = Long.parseLong(browserDateString);
2458: } else {
2459: return true;
2460: }
2461: } catch (Exception e) {
2462: log.warn(e.getMessage());
2463: }
2464:
2465: log.debug("last modified date in DB=" + DBdate);
2466: log.debug("last modified date in browser=" + browserDate);
2467: log.debug("date is equal=" + (DBdate == browserDate));
2468: return (DBdate == browserDate);
2469: } else
2470: return true;
2471: }
2472:
2473: private boolean getAssessmentHasBeenSubmitted(
2474: AssessmentGradingData assessmentGrading) {
2475: // get assessmentGrading from DB, this is to avoid same assessment being
2476: // opened in the differnt browser
2477: if (assessmentGrading != null) {
2478: return assessmentGrading.getForGrade().booleanValue();
2479: } else
2480: return false;
2481: }
2482:
2483: public String getPortal() {
2484: return ServerConfigurationService.getString("portalPath");
2485: }
2486:
2487: public String getSelectURL() {
2488: StringBuffer url = new StringBuffer(ServerConfigurationService
2489: .getString("portalPath"));
2490: url.append("/site/");
2491: PublishedAssessmentService publishedAssessmentService = new PublishedAssessmentService();
2492: String currentSiteId = publishedAssessmentService
2493: .getPublishedAssessmentSiteId(getAssessmentId());
2494: url.append(currentSiteId);
2495: url.append("/page/");
2496: url.append(getCurrentPageId(currentSiteId));
2497: return url.toString();
2498: }
2499:
2500: public String getTimerId() {
2501: return timerId;
2502: }
2503:
2504: public void setTimerId(String timerId) {
2505: this .timerId = timerId;
2506: }
2507:
2508: private Site getCurrentSite(String id) {
2509: Site site = null;
2510: //Placement placement = ToolManager.getCurrentPlacement();
2511: //String currentSiteId = placement.getContext();
2512: try {
2513: site = SiteService.getSite(id);
2514: } catch (IdUnusedException e) {
2515: log.error(e.getMessage());
2516: e.printStackTrace();
2517: }
2518: return site;
2519: }
2520:
2521: private String getCurrentPageId(String id) {
2522: Site currentSite = getCurrentSite(id);
2523: if (currentSite == null) {
2524: return "";
2525: }
2526: SitePage page = null;
2527: String toolId = null;
2528: try {
2529: // get page
2530: List pageList = currentSite.getPages();
2531: for (int i = 0; i < pageList.size(); i++) {
2532: page = (SitePage) pageList.get(i);
2533: List pageToolList = page.getTools();
2534: toolId = ((ToolConfiguration) pageToolList.get(0))
2535: .getTool().getId();
2536: if (toolId.equalsIgnoreCase("sakai.samigo")) {
2537: return page.getId();
2538: }
2539: }
2540: } catch (Exception e) {
2541: log.warn(e.getMessage());
2542: }
2543: return "";
2544: }
2545:
2546: public Long getAssessmentGradingId() {
2547: return assessmentGradingId;
2548: }
2549:
2550: public void setAssessmentGradingId(Long assessmentGradingId) {
2551: this .assessmentGradingId = assessmentGradingId;
2552: }
2553:
2554: // This is for SAK-9505
2555: // We reset the time limit to the smaller one of
2556: // 1. assessment "time limit" and 2. the difference of due date and current.
2557: public String updateTimeLimit(String timeLimit) {
2558: boolean acceptLateSubmission = AssessmentAccessControlIfc.ACCEPT_LATE_SUBMISSION
2559: .equals(publishedAssessment
2560: .getAssessmentAccessControl().getLateHandling());
2561: if (this .dueDate != null && !acceptLateSubmission) {
2562: int timeBeforeDue = Math
2563: .round((this .dueDate.getTime() - (new Date())
2564: .getTime()) / 1000); //in sec
2565: if (timeBeforeDue < Integer.parseInt(timeLimit)) {
2566: return String.valueOf(timeBeforeDue);
2567: }
2568: }
2569: return timeLimit;
2570: }
2571:
2572: private boolean isTimedAssessment() {
2573: if (this .getPublishedAssessment().getAssessmentAccessControl()
2574: .getTimeLimit().equals(Integer.valueOf(0))) {
2575: return false;
2576: }
2577: return true;
2578: }
2579: }
|