/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/sam/trunk/samigo-app/src/java/org/sakaiproject/tool/assessment/ui/listener/author/SavePublishedSettingsListener.java $
* $Id: SavePublishedSettingsListener.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.listener.author;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.event.cover.EventTrackingService;
import org.sakaiproject.service.gradebook.shared.GradebookExternalAssessmentService;
import org.sakaiproject.service.gradebook.shared.GradebookService;
import org.sakaiproject.spring.SpringBeanLocator;
import org.sakaiproject.tool.assessment.api.SamigoApiFactory;
import org.sakaiproject.tool.assessment.data.dao.assessment.AssessmentAccessControl;
import org.sakaiproject.tool.assessment.data.dao.assessment.AssessmentFeedback;
import org.sakaiproject.tool.assessment.data.dao.assessment.EvaluationModel;
import org.sakaiproject.tool.assessment.data.dao.assessment.PublishedAccessControl;
import org.sakaiproject.tool.assessment.data.dao.assessment.PublishedAssessmentData;
import org.sakaiproject.tool.assessment.data.dao.assessment.PublishedEvaluationModel;
import org.sakaiproject.tool.assessment.data.dao.assessment.PublishedSecuredIPAddress;
import org.sakaiproject.tool.assessment.data.dao.assessment.SecuredIPAddress;
import org.sakaiproject.tool.assessment.data.dao.grading.AssessmentGradingData;
import org.sakaiproject.tool.assessment.data.ifc.assessment.AssessmentAccessControlIfc;
import org.sakaiproject.tool.assessment.data.ifc.assessment.AssessmentBaseIfc;
import org.sakaiproject.tool.assessment.data.ifc.assessment.AssessmentFeedbackIfc;
import org.sakaiproject.tool.assessment.data.ifc.assessment.AssessmentIfc;
import org.sakaiproject.tool.assessment.data.ifc.assessment.AssessmentMetaDataIfc;
import org.sakaiproject.tool.assessment.data.ifc.assessment.EvaluationModelIfc;
import org.sakaiproject.tool.assessment.facade.AgentFacade;
import org.sakaiproject.tool.assessment.facade.AssessmentFacade;
import org.sakaiproject.tool.assessment.facade.GradebookFacade;
import org.sakaiproject.tool.assessment.facade.PublishedAssessmentFacade;
import org.sakaiproject.tool.assessment.facade.PublishedAssessmentFacadeQueries;
import org.sakaiproject.tool.assessment.integration.context.IntegrationContextFactory;
import org.sakaiproject.tool.assessment.integration.helper.ifc.GradebookServiceHelper;
import org.sakaiproject.tool.assessment.services.GradingService;
import org.sakaiproject.tool.assessment.services.PersistenceService;
import org.sakaiproject.tool.assessment.services.assessment.AssessmentService;
import org.sakaiproject.tool.assessment.services.assessment.PublishedAssessmentService;
import org.sakaiproject.tool.assessment.shared.api.assessment.SecureDeliveryServiceAPI;
import org.sakaiproject.tool.assessment.ui.bean.author.AssessmentBean;
import org.sakaiproject.tool.assessment.ui.bean.author.AuthorBean;
import org.sakaiproject.tool.assessment.ui.bean.author.PublishedAssessmentSettingsBean;
import org.sakaiproject.tool.assessment.ui.listener.util.ContextUtil;
import org.sakaiproject.tool.assessment.util.TextFormat;
import org.sakaiproject.util.ResourceLoader;
import org.sakaiproject.tool.assessment.integration.helper.ifc.CalendarServiceHelper;
import org.sakaiproject.tool.assessment.ui.bean.author.PublishRepublishNotificationBean;
/**
* <p>Title: Samigo</p>2
* <p>Description: Sakai Assessment Manager</p>
* @author Ed Smiley
* @version $Id: SavePublishedSettingsListener.java 121258 2013-03-15 15:03:36Z ottenhoff@longsight.com $
*/
public class SavePublishedSettingsListener
implements ActionListener
{
private static Log log = LogFactory.getLog(SavePublishedSettingsListener.class);
private static final GradebookServiceHelper gbsHelper =
IntegrationContextFactory.getInstance().getGradebookServiceHelper();
private static final boolean integrated =
IntegrationContextFactory.getInstance().isIntegrated();
private CalendarServiceHelper calendarService = IntegrationContextFactory.getInstance().getCalendarServiceHelper();
private ResourceLoader rb= new ResourceLoader("org.sakaiproject.tool.assessment.bundle.AssessmentSettingsMessages");
public SavePublishedSettingsListener()
{
}
public void processAction(ActionEvent ae) throws AbortProcessingException
{
FacesContext context = FacesContext.getCurrentInstance();
PublishedAssessmentSettingsBean assessmentSettings = (PublishedAssessmentSettingsBean) ContextUtil.lookupBean(
"publishedSettings");
// #1 - set Assessment
Long assessmentId = assessmentSettings.getAssessmentId();
log.debug("**** save assessment assessmentId ="+assessmentId.toString());
PublishedAssessmentService assessmentService = new PublishedAssessmentService();
PublishedAssessmentFacade assessment = assessmentService.getPublishedAssessment(
assessmentId.toString());
boolean retractNow = false;
String id = ae.getComponent().getId();
// Check if the action is clicking the the "Retract" button on Assessment Retract Confirmation button
if ("retract".equals(id)) {
retractNow = true;
}
EventTrackingService.post(EventTrackingService.newEvent("sam.pubsetting.edit", "siteId=" + AgentFacade.getCurrentSiteId() + ", publishedAssessmentId=" + assessmentId, true));
boolean error = checkPublishedSettings(assessmentService, assessmentSettings, context);
if (error){
assessmentSettings.setOutcome("editPublishedAssessmentSettings");
return;
}
boolean isTitleChanged = isTitleChanged(assessmentSettings, assessment);
boolean isScoringTypeChanged = isScoringTypeChanged(assessmentSettings, assessment);
SaveAssessmentSettings saveAssessmentSettings = new SaveAssessmentSettings();
setPublishedSettings(assessmentSettings, assessment, retractNow, saveAssessmentSettings);
boolean gbError = checkScore(assessmentSettings, assessment, context);
if (gbError){
assessmentSettings.setOutcome("editPublishedAssessmentSettings");
return;
}
boolean gbUpdated = updateGB(assessmentSettings, assessment, isTitleChanged, isScoringTypeChanged, context);
if (!gbUpdated){
assessmentSettings.setOutcome("editPublishedAssessmentSettings");
return;
}
assessment.setLastModifiedBy(AgentFacade.getAgentString());
assessment.setLastModifiedDate(new Date());
assessmentService.saveAssessment(assessment);
// jj. save assessment first, then deal with ip
assessmentService.saveAssessment(assessment);
assessmentService.deleteAllSecuredIP(assessment);
// k. set ipAddresses
HashSet ipSet = new HashSet();
String ipAddresses = assessmentSettings.getIpAddresses();
if (ipAddresses == null)
ipAddresses = "";
String[] ip = ipAddresses.split("\\n");
for (int j=0; j<ip.length;j++){
if (ip[j]!=null && !ip[j].equals("\r")) {
ipSet.add(new PublishedSecuredIPAddress(assessment.getData(),null,ip[j]));
}
}
assessment.setSecuredIPAddressSet(ipSet);
// k. secure delivery settings
SecureDeliveryServiceAPI secureDeliveryService = SamigoApiFactory.getInstance().getSecureDeliveryServiceAPI();
assessment.updateAssessmentMetaData(SecureDeliveryServiceAPI.MODULE_KEY, assessmentSettings.getSecureDeliveryModule() );
String encryptedPassword = secureDeliveryService.encryptPassword( assessmentSettings.getSecureDeliveryModule(), assessmentSettings.getSecureDeliveryModuleExitPassword() );
assessment.updateAssessmentMetaData(SecureDeliveryServiceAPI.EXITPWD_KEY, TextFormat.convertPlaintextToFormattedTextNoHighUnicode(log, encryptedPassword ));
// kk. remove the existing title decoration (if any) and then add the new one (if any)
String titleDecoration = assessment.getAssessmentMetaDataByLabel( SecureDeliveryServiceAPI.TITLE_DECORATION );
String newTitle;
if ( titleDecoration != null )
newTitle = assessment.getTitle().replace( titleDecoration, "");
else
newTitle = assessment.getTitle();
// getTitleDecoration() returns "" if null or NONE module is passed
titleDecoration = secureDeliveryService.getTitleDecoration( assessmentSettings.getSecureDeliveryModule(), new ResourceLoader().getLocale() );
newTitle = newTitle + " " + titleDecoration;
assessment.setTitle( newTitle );
assessment.updateAssessmentMetaData(SecureDeliveryServiceAPI.TITLE_DECORATION, titleDecoration );
// l. FINALLY: save the assessment
assessmentService.saveAssessment(assessment);
saveAssessmentSettings.updateAttachment(assessment.getAssessmentAttachmentList(), assessmentSettings.getAttachmentList(),(AssessmentIfc)assessment.getData(), false);
EventTrackingService.post(EventTrackingService.newEvent("sam.pubSetting.edit", "siteId=" + AgentFacade.getCurrentSiteId() + ", pubAssessmentId=" + assessmentSettings.getAssessmentId(), true));
AuthorBean author = (AuthorBean) ContextUtil.lookupBean("author");
if ("editAssessment".equals(author.getFromPage())) {
// If go back to edit assessment page, need to refresh the title
AssessmentBean assessmentBean = (AssessmentBean) ContextUtil.lookupBean("assessmentBean");
assessmentBean.setTitle(assessmentSettings.getTitle());
}
else {
resetPublishedAssessmentsList(author, assessmentService);
}
assessmentSettings.setOutcome(author.getFromPage());
//update calendar event dates:
//need to add the calendar even back on the calendar if there already exists one (user opted to have it added to calendar)
boolean addDueDateToCalendar = assessment.getAssessmentMetaDataByLabel(AssessmentMetaDataIfc.CALENDAR_DUE_DATE_EVENT_ID) != null;
PublishAssessmentListener publishAssessmentListener = new PublishAssessmentListener();
PublishRepublishNotificationBean publishRepublishNotification = (PublishRepublishNotificationBean) ContextUtil.lookupBean("publishRepublishNotification");
String notificationMessage = publishAssessmentListener.getNotificationMessage(publishRepublishNotification, assessmentSettings.getTitle(), assessmentSettings.getReleaseTo(), assessmentSettings.getStartDateString(), assessmentSettings.getPublishedUrl(),
assessmentSettings.getReleaseToGroupsAsString(), assessmentSettings.getDueDateString(), assessmentSettings.getTimedHours(), assessmentSettings.getTimedMinutes(),
assessmentSettings.getUnlimitedSubmissions(), assessmentSettings.getSubmissionsAllowed(), assessmentSettings.getScoringType(), assessmentSettings.getFeedbackDelivery(), assessmentSettings.getFeedbackDateString());
calendarService.updateAllCalendarEvents(assessment, assessmentSettings.getReleaseTo(), assessmentSettings.getGroupsAuthorized(), rb.getString("calendarDueDatePrefix") + " ", addDueDateToCalendar, notificationMessage);
}
public boolean checkPublishedSettings(PublishedAssessmentService assessmentService, PublishedAssessmentSettingsBean assessmentSettings, FacesContext context) {
boolean error = false;
// Title
String assessmentName = assessmentSettings.getTitle();
// check if name is empty
if(assessmentName == null || (assessmentName.trim()).equals("")){
String nameEmpty_err=ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.AssessmentSettingsMessages","assessmentName_empty");
context.addMessage(null, new FacesMessage(nameEmpty_err));
error=true;
}
else {
assessmentName = TextFormat.convertPlaintextToFormattedTextNoHighUnicode(log, assessmentName.trim());
// check if name is unique
if(!assessmentService.publishedAssessmentTitleIsUnique(assessmentSettings.getAssessmentId().toString(), assessmentName)){
String nameUnique_err = ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.AssessmentSettingsMessages","assessmentName_error");
context.addMessage(null, new FacesMessage(nameUnique_err));
error=true;
}
}
// check if start date is valid
if(!assessmentSettings.getIsValidStartDate()){
String startDateErr = ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.GeneralMessages","invalid_start_date");
context.addMessage(null, new FacesMessage(startDateErr));
error=true;
}
// check if due date is valid
if(!assessmentSettings.getIsValidDueDate()){
String dueDateErr = ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.GeneralMessages","invalid_due_date");
context.addMessage(null,new FacesMessage(dueDateErr));
error=true;
}
// check if retract date is valid
if(!assessmentSettings.getIsValidRetractDate()){
String retractDateErr = ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.GeneralMessages","invalid_retrack_date");
context.addMessage(null,new FacesMessage(retractDateErr));
error=true;
}
Date startDate = assessmentSettings.getStartDate();
Date dueDate = assessmentSettings.getDueDate();
Date retractDate = assessmentSettings.getRetractDate();
boolean isRetractEarlierThanAvaliable = false;
if ((dueDate != null && startDate != null && dueDate.before(startDate)) ||
(dueDate != null && startDate == null && dueDate.before(new Date()))) {
String dateError1 = ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.AssessmentSettingsMessages","due_earlier_than_avaliable");
context.addMessage(null,new FacesMessage(FacesMessage.SEVERITY_WARN, dateError1, null));
error=true;
assessmentSettings.setStartDate(new Date());
}
if ((retractDate != null && startDate != null && retractDate.before(startDate)) ||
(retractDate != null && startDate == null && retractDate.before(new Date()))) {
String dateError2 = ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.AssessmentSettingsMessages","retract_earlier_than_avaliable");
context.addMessage(null,new FacesMessage(FacesMessage.SEVERITY_WARN, dateError2, null));
error=true;
isRetractEarlierThanAvaliable = true;
assessmentSettings.setStartDate(new Date());
}
if (!isRetractEarlierThanAvaliable && (retractDate != null && dueDate != null && retractDate.before(dueDate))) {
String dateError3 = ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.AssessmentSettingsMessages","retract_earlier_than_due");
context.addMessage(null,new FacesMessage(FacesMessage.SEVERITY_WARN, dateError3, null));
error=true;
}
// SAM-1088
// if late submissions not allowed and retract date is null, set retract date to due date
if (assessmentSettings.getLateHandling() != null && AssessmentAccessControlIfc.NOT_ACCEPT_LATE_SUBMISSION.equals(assessmentSettings.getLateHandling()) &&
retractDate == null && dueDate != null && assessmentSettings.getAutoSubmit()) {
assessmentSettings.setRetractDate(dueDate);
}
// if auto-submit is enabled, make sure retract date is set
if (assessmentSettings.getAutoSubmit() && retractDate == null) {
String dateError4 = ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.AssessmentSettingsMessages","retract_required_with_auto_submit");
context.addMessage(null,new FacesMessage(FacesMessage.SEVERITY_WARN, dateError4, null));
error=true;
}
// if timed assessment, does it has value for time
Object time = assessmentSettings.getValueMap().get("hasTimeAssessment");
boolean isTime = false;
try
{
if (time != null)
{
isTime = ((Boolean) time).booleanValue();
}
}
catch (Exception ex)
{
// keep default
log.warn("Expecting Boolean hasTimeAssessment, got: " + time + ", exception: " + ex);
}
if(isTime && (assessmentSettings.getTimeLimit().intValue())==0){
String time_err = ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.AssessmentSettingsMessages", "timeSelect_error");
context.addMessage(null, new FacesMessage(time_err));
error = true;
}
// check submissions
String unlimitedSubmissions = assessmentSettings.getUnlimitedSubmissions();
if (unlimitedSubmissions != null && unlimitedSubmissions.equals(AssessmentAccessControlIfc.LIMITED_SUBMISSIONS.toString())) {
try {
String submissionsAllowed = assessmentSettings.getSubmissionsAllowed().trim();
int submissionAllowed = Integer.parseInt(submissionsAllowed);
if (submissionAllowed < 1) {
throw new RuntimeException();
}
}
catch (RuntimeException e){
error=true;
String submission_err = ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.AssessmentSettingsMessages","submissions_allowed_error");
context.addMessage(null,new FacesMessage(submission_err));
}
}
String scoringType=assessmentSettings.getScoringType();
if ((scoringType).equals(EvaluationModelIfc.AVERAGE_SCORE.toString()) && "0".equals(assessmentSettings.getUnlimitedSubmissions())) {
try {
String submissionsAllowed = assessmentSettings.getSubmissionsAllowed().trim();
int submissionAllowed = Integer.parseInt(submissionsAllowed);
if (submissionAllowed < 2) {
throw new RuntimeException();
}
}
catch (RuntimeException e){
error=true;
String submission_err = ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.AssessmentSettingsMessages","averag_grading_single_submission");
context.addMessage(null,new FacesMessage(submission_err));
}
}
// check feedback - if at specific time then time should be defined.
if((assessmentSettings.getFeedbackDelivery()).equals("2")) {
if (assessmentSettings.getFeedbackDateString()==null || assessmentSettings.getFeedbackDateString().equals("")) {
error=true;
String date_err=ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.AssessmentSettingsMessages","date_error");
context.addMessage(null,new FacesMessage(date_err));
}
else if(!assessmentSettings.getIsValidFeedbackDate()){
String feedbackDateErr = ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.GeneralMessages","invalid_feedback_date");
context.addMessage(null,new FacesMessage(feedbackDateErr));
error=true;
}
}
// check secure delivery exit password
SecureDeliveryServiceAPI secureDeliveryService = SamigoApiFactory.getInstance().getSecureDeliveryServiceAPI();
if ( secureDeliveryService.isSecureDeliveryAvaliable() ) {
String moduleId = assessmentSettings.getSecureDeliveryModule();
if ( ! SecureDeliveryServiceAPI.NONE_ID.equals( moduleId ) ) {
String exitPassword = assessmentSettings.getSecureDeliveryModuleExitPassword();
if ( exitPassword != null && exitPassword.length() > 0 ) {
for ( int i = 0; i < exitPassword.length(); i++ ) {
char c = exitPassword.charAt(i);
if ( ! (( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || ( c >= '0' && c <= '9' )) ) {
error = true;
String submission_err = ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.AssessmentSettingsMessages","exit_password_error");
context.addMessage(null,new FacesMessage(submission_err));
break;
}
}
}
}
}
return error;
}
// Check if title has been changed. If yes, update it.
private boolean isTitleChanged(PublishedAssessmentSettingsBean assessmentSettings, PublishedAssessmentFacade assessment) {
if (assessment.getTitle() != null && assessmentSettings.getTitle() != null) {
String assessmentTitle = TextFormat.convertPlaintextToFormattedTextNoHighUnicode(log, assessmentSettings.getTitle().trim());
if (!assessment.getTitle().trim().equals(assessmentTitle)) {
assessment.setTitle(assessmentTitle);
return true;
}
}
return false;
}
// Check if scoring type has been changed.
private boolean isScoringTypeChanged(PublishedAssessmentSettingsBean assessmentSettings, PublishedAssessmentFacade assessment) {
if (assessment.getEvaluationModel() != null && assessment.getEvaluationModel().getScoringType() != null && assessmentSettings.getScoringType() != null) {
Integer oldScoringType = assessment.getEvaluationModel().getScoringType();
String newScoringType = assessmentSettings.getScoringType().trim();
if (newScoringType.equals(oldScoringType.toString())) {
return false;
}
}
return true;
}
private void setPublishedSettings(PublishedAssessmentSettingsBean assessmentSettings, PublishedAssessmentFacade assessment, boolean retractNow, SaveAssessmentSettings saveAssessmentSettings) {
// Title is set in isTitleChanged()
assessment.setDescription(assessmentSettings.getDescription());
assessment.updateAssessmentMetaData(AssessmentMetaDataIfc.AUTHORS, assessmentSettings.getAuthors());
PublishedAccessControl control = (PublishedAccessControl)assessment.getAssessmentAccessControl();
if (control == null){
control = new PublishedAccessControl();
// need to fix accessControl so it can take AssessmentFacade later
control.setAssessmentBase(assessment.getData());
}
// set startDate, dueDate, retractDate
control.setStartDate(assessmentSettings.getStartDate());
control.setDueDate(assessmentSettings.getDueDate());
if (retractNow)
{
control.setRetractDate(new Date());
}
else {
control.setRetractDate(assessmentSettings.getRetractDate());
}
// set Assessment Orgainzation
if (assessmentSettings.getItemNavigation()!=null ) {
String nav = assessmentSettings.getItemNavigation();
if ("1".equals(nav)) {
assessmentSettings.setAssessmentFormat("1");
}
control.setItemNavigation(Integer.valueOf(nav));
}
if (assessmentSettings.getAssessmentFormat() != null ) {
control.setAssessmentFormat(new Integer(assessmentSettings.getAssessmentFormat()));
}
if (assessmentSettings.getItemNumbering() != null) {
control.setItemNumbering(new Integer(assessmentSettings.getItemNumbering()));
}
// set Timed Assessment
control.setTimeLimit(assessmentSettings.getTimeLimit());
if (assessmentSettings.getTimedAssessment()) {
control.setTimedAssessment(AssessmentAccessControl.TIMED_ASSESSMENT);
}
else {
control.setTimedAssessment(AssessmentAccessControl.DO_NOT_TIMED_ASSESSMENT);
}
if (assessmentSettings.getIsMarkForReview())
control.setMarkForReview(AssessmentAccessControl.MARK_FOR_REVIEW);
else {
control.setMarkForReview(AssessmentAccessControl.NOT_MARK_FOR_REVIEW);
}
// set Submissions
if (assessmentSettings.getUnlimitedSubmissions()!=null){
if (!assessmentSettings.getUnlimitedSubmissions().
equals(AssessmentAccessControlIfc.UNLIMITED_SUBMISSIONS.toString())) {
control.setUnlimitedSubmissions(Boolean.FALSE);
if (assessmentSettings.getSubmissionsAllowed() != null)
control.setSubmissionsAllowed(new Integer(assessmentSettings.
getSubmissionsAllowed()));
else
control.setSubmissionsAllowed(Integer.valueOf("1"));
}
else {
control.setUnlimitedSubmissions(Boolean.TRUE);
control.setSubmissionsAllowed(null);
}
}
if (assessmentSettings.getLateHandling()!=null){
control.setLateHandling(new Integer(assessmentSettings.
getLateHandling()));
}
if (assessmentSettings.getSubmissionsSaved()!=null){
control.setSubmissionsSaved(new Integer(assessmentSettings.getSubmissionsSaved()));
}
if (assessmentSettings.getAutoSubmit())
control.setAutoSubmit(AssessmentAccessControl.AUTO_SUBMIT);
else {
control.setAutoSubmit(AssessmentAccessControl.DO_NOT_AUTO_SUBMIT);
}
assessment.setAssessmentAccessControl(control);
// e. set Submission Messages
control.setSubmissionMessage(assessmentSettings.getSubmissionMessage());
// f. set username
control.setUsername(TextFormat.convertPlaintextToFormattedTextNoHighUnicode(log, assessmentSettings.getUsername()));
// g. set password
control.setPassword(TextFormat.convertPlaintextToFormattedTextNoHighUnicode(log, assessmentSettings.getPassword()));
// h. set finalPageUrl
String finalPageUrl = "";
if (assessmentSettings.getFinalPageUrl() != null) {
finalPageUrl = TextFormat.convertPlaintextToFormattedTextNoHighUnicode(log, assessmentSettings.getFinalPageUrl().trim());
if (finalPageUrl.length() != 0 && !finalPageUrl.toLowerCase().startsWith("http")) {
finalPageUrl = "http://" + finalPageUrl;
}
}
control.setFinalPageUrl(finalPageUrl);
// set Feedback
AssessmentFeedbackIfc feedback = (AssessmentFeedbackIfc) assessment.getAssessmentFeedback();
if (feedback == null){
feedback = new AssessmentFeedback();
// need to fix feeback so it can take AssessmentFacade later
feedback.setAssessmentBase(assessment.getData());
}
// Feedback authoring
if (assessmentSettings.getFeedbackAuthoring()!=null)
feedback.setFeedbackAuthoring(new Integer(assessmentSettings.getFeedbackAuthoring()));
// Feedback delivery
if (assessmentSettings.getFeedbackDelivery()!=null)
feedback.setFeedbackDelivery(new Integer(assessmentSettings.getFeedbackDelivery()));
if (assessmentSettings.getFeedbackComponentOption()!=null)
feedback.setFeedbackComponentOption(new Integer(assessmentSettings.getFeedbackComponentOption()));
control.setFeedbackDate(assessmentSettings.getFeedbackDate());
// Feedback Components Students Can See
feedback.setShowStudentResponse(Boolean.valueOf(assessmentSettings.getShowStudentResponse()));
feedback.setShowCorrectResponse(Boolean.valueOf(assessmentSettings.getShowCorrectResponse()));
feedback.setShowStudentScore(Boolean.valueOf(assessmentSettings.getShowStudentScore()));
feedback.setShowStudentQuestionScore(Boolean.valueOf(assessmentSettings.getShowStudentQuestionScore()));
feedback.setShowQuestionLevelFeedback(Boolean.valueOf(assessmentSettings.getShowQuestionLevelFeedback()));
feedback.setShowSelectionLevelFeedback(Boolean.valueOf(assessmentSettings.getShowSelectionLevelFeedback()));
feedback.setShowGraderComments(Boolean.valueOf(assessmentSettings.getShowGraderComments()));
feedback.setShowStatistics(Boolean.valueOf(assessmentSettings.getShowStatistics()));
assessment.setAssessmentFeedback(feedback);
// set Grading
EvaluationModelIfc evaluation = (EvaluationModelIfc) assessment.getEvaluationModel();
if (evaluation == null){
evaluation = new EvaluationModel();
evaluation.setAssessmentBase(assessment.getData());
}
if (assessmentSettings.getAnonymousGrading() != null) {
evaluation.setAnonymousGrading(new Integer(assessmentSettings.getAnonymousGrading()));
}
// If there is value set for toDefaultGradebook, we reset it
// Otherwise, do nothing
if (assessmentSettings.getToDefaultGradebook() != null) {
evaluation.setToGradeBook(assessmentSettings.getToDefaultGradebook());
}
if (assessmentSettings.getScoringType() != null) {
evaluation.setScoringType(new Integer(assessmentSettings.getScoringType()));
}
assessment.setEvaluationModel(evaluation);
// update ValueMap: it contains value for thh checkboxes in
// publishedSettings.jsp for: hasAvailableDate, hasDueDate,
// hasRetractDate, hasAnonymous, hasAuthenticatedUser, hasIpAddress,
// hasUsernamePassword, hasTimeAssessment,hasAutoSubmit, hasPartMetaData,
// hasQuestionMetaData
HashMap h = assessmentSettings.getValueMap();
saveAssessmentSettings.updateMetaWithValueMap(assessment, h);
// i. set Graphics
assessment.updateAssessmentMetaData(AssessmentMetaDataIfc.BGCOLOR, TextFormat.convertPlaintextToFormattedTextNoHighUnicode(log, assessmentSettings.getBgColor()));
assessment.updateAssessmentMetaData(AssessmentMetaDataIfc.BGIMAGE, TextFormat.convertPlaintextToFormattedTextNoHighUnicode(log, assessmentSettings.getBgImage()));
// j. set objectives,rubrics,keywords
assessment.updateAssessmentMetaData(AssessmentMetaDataIfc.KEYWORDS, TextFormat.convertPlaintextToFormattedTextNoHighUnicode(log, assessmentSettings.getKeywords()));
assessment.updateAssessmentMetaData(AssessmentMetaDataIfc.OBJECTIVES, TextFormat.convertPlaintextToFormattedTextNoHighUnicode(log, assessmentSettings.getObjectives()));
assessment.updateAssessmentMetaData(AssessmentMetaDataIfc.RUBRICS, TextFormat.convertPlaintextToFormattedTextNoHighUnicode(log, assessmentSettings.getRubrics()));
}
public boolean checkScore(PublishedAssessmentSettingsBean assessmentSettings, PublishedAssessmentFacade assessment, FacesContext context) {
// check if the score is > 0, Gradebook doesn't allow assessments with total
// point = 0.
boolean gbError = false;
if (assessmentSettings.getToDefaultGradebook() != null && assessmentSettings.getToDefaultGradebook().equals("1")) {
if (assessment.getTotalScore().doubleValue() <= 0) {
String gb_err = (String) ContextUtil.getLocalizedString(
"org.sakaiproject.tool.assessment.bundle.AuthorMessages","gradebook_exception_min_points");
context.addMessage(null, new FacesMessage(gb_err));
gbError = true;
}
}
return gbError;
}
public boolean updateGB(PublishedAssessmentSettingsBean assessmentSettings, PublishedAssessmentFacade assessment, boolean isTitleChanged, boolean isScoringTypeChanged, FacesContext context) {
//#3 - add or remove external assessment to gradebook
// a. if Gradebook does not exists, do nothing, 'cos setting should have been hidden
// b. if Gradebook exists, just call addExternal and removeExternal and swallow any exception. The
// exception are indication that the assessment is already in the Gradebook or there is nothing
// to remove.
GradebookExternalAssessmentService g = null;
if (integrated)
{
g = (GradebookExternalAssessmentService) SpringBeanLocator.getInstance().
getBean("org.sakaiproject.service.gradebook.GradebookExternalAssessmentService");
}
if (gbsHelper.gradebookExists(GradebookFacade.getGradebookUId(), g)){ // => something to do
PublishedEvaluationModel evaluation = (PublishedEvaluationModel)assessment.getEvaluationModel();
//Integer scoringType = EvaluationModelIfc.HIGHEST_SCORE;
if (evaluation == null){
evaluation = new PublishedEvaluationModel();
evaluation.setAssessmentBase(assessment.getData());
}
String assessmentName = "";
boolean gbItemExists = false;
try{
assessmentName = TextFormat.convertPlaintextToFormattedTextNoHighUnicode(log, assessmentSettings.getTitle().trim());
gbItemExists = gbsHelper.isAssignmentDefined(assessmentName, g);
if (assessmentSettings.getToDefaultGradebook()!=null && assessmentSettings.getToDefaultGradebook().equals(EvaluationModelIfc.TO_DEFAULT_GRADEBOOK.toString()) &&
gbItemExists && isTitleChanged){
String gbConflict_error=ContextUtil.getLocalizedString("org.sakaiproject.tool.assessment.bundle.AssessmentSettingsMessages","gbConflict_error");
context.addMessage(null,new FacesMessage(gbConflict_error));
return false;
}
}
catch(Exception e){
log.warn("external assessment in GB has the same title:"+e.getMessage());
}
// If there is value set for toDefaultGradebook, we reset it
// Otherwise, do nothing
if (assessmentSettings.getToDefaultGradebook() != null) {
evaluation.setToGradeBook(assessmentSettings.getToDefaultGradebook());
}
// If the assessment is retracted for edit, we don't sync with gradebook (only until it is republished)
if(AssessmentBaseIfc.RETRACT_FOR_EDIT_STATUS.equals(assessment.getStatus())) {
return true;
}
Integer scoringType = evaluation.getScoringType();
if (evaluation.getToGradeBook()!=null &&
evaluation.getToGradeBook().equals(EvaluationModelIfc.TO_DEFAULT_GRADEBOOK.toString())){
if (isTitleChanged || isScoringTypeChanged) {
// Because GB use title instead of id, we remove and re-add to GB if title changes.
try {
log.debug("before gbsHelper.removeGradebook()");
gbsHelper.removeExternalAssessment(GradebookFacade.getGradebookUId(), assessment.getPublishedAssessmentId().toString(), g);
} catch (Exception e1) {
// Should be the external assessment doesn't exist in GB. So we quiet swallow the exception. Please check the log for the actual error.
log.info("Exception thrown in updateGB():" + e1.getMessage());
}
}
if(gbItemExists && !(isTitleChanged || isScoringTypeChanged)){
try {
gbsHelper.updateGradebook(assessment, g);
} catch (Exception e) {
log.warn("Exception thrown in updateGB():" + e.getMessage());
}
}
else{
try{
log.debug("before gbsHelper.addToGradebook()");
gbsHelper.addToGradebook((PublishedAssessmentData)assessment.getData(), g);
// any score to copy over? get all the assessmentGradingData and copy over
GradingService gradingService = new GradingService();
// need to decide what to tell gradebook
List list = null;
if ((scoringType).equals(EvaluationModelIfc.HIGHEST_SCORE)){
list = gradingService.getHighestSubmittedOrGradedAssessmentGradingList(assessment.getPublishedAssessmentId());
}
else {
list = gradingService.getLastSubmittedOrGradedAssessmentGradingList(assessment.getPublishedAssessmentId());
}
//ArrayList list = gradingService.getAllSubmissions(assessment.getPublishedAssessmentId().toString());
log.debug("list size =" + list.size() );
for (int i=0; i<list.size();i++){
try {
AssessmentGradingData ag = (AssessmentGradingData)list.get(i);
log.debug("ag.scores " + ag.getTotalAutoScore());
// Send the average score if average was selected for multiple submissions
if (scoringType.equals(EvaluationModelIfc.AVERAGE_SCORE)) {
// status = 5: there is no submission but grader update something in the score page
if(ag.getStatus() ==5) {
ag.setFinalScore(ag.getFinalScore());
} else {
Double averageScore = PersistenceService.getInstance().getAssessmentGradingFacadeQueries().
getAverageSubmittedAssessmentGrading(Long.valueOf(assessment.getPublishedAssessmentId()), ag.getAgentId());
ag.setFinalScore(averageScore);
}
}
gbsHelper.updateExternalAssessmentScore(ag, g);
}
catch (Exception e) {
log.warn("Exception occues in " + i + "th record. Message:" + e.getMessage());
}
}
}
catch(Exception e){
log.warn("oh well, must have been added already:"+e.getMessage());
}
}
}
else{ //remove
try{
gbsHelper.removeExternalAssessment(
GradebookFacade.getGradebookUId(),
assessment.getPublishedAssessmentId().toString(), g);
}
catch(Exception e){
log.warn("*** oh well, looks like there is nothing to remove:"+e.getMessage());
}
}
}
return true;
}
public void resetPublishedAssessmentsList(AuthorBean author,
PublishedAssessmentService assessmentService) {
AuthorActionListener authorActionListener = new AuthorActionListener();
GradingService gradingService = new GradingService();
ArrayList publishedAssessmentList = assessmentService.getBasicInfoOfAllPublishedAssessments2(
PublishedAssessmentFacadeQueries.TITLE, true, AgentFacade.getCurrentSiteId());
authorActionListener.prepareAllPublishedAssessmentsList(author, gradingService, publishedAssessmentList);
}
}