/********************************************************************************** * $URL: https://source.sakaiproject.org/svn/sam/trunk/samigo-app/src/java/org/sakaiproject/tool/assessment/ui/listener/evaluation/QuestionScoreListener.java $ * $Id: QuestionScoreListener.java 130512 2013-10-15 23:46:40Z ktsao@stanford.edu $ *********************************************************************************** * * 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.evaluation; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.faces.event.AbortProcessingException; import javax.faces.event.ActionEvent; import javax.faces.event.ActionListener; import javax.faces.event.ValueChangeEvent; import javax.faces.event.ValueChangeListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.sakaiproject.tool.assessment.data.dao.assessment.AssessmentAccessControl; import org.sakaiproject.tool.assessment.data.dao.assessment.EvaluationModel; import org.sakaiproject.tool.assessment.data.dao.assessment.PublishedAnswer; import org.sakaiproject.tool.assessment.data.dao.grading.ItemGradingAttachment; import org.sakaiproject.tool.assessment.data.dao.grading.ItemGradingData; import org.sakaiproject.tool.assessment.data.dao.grading.MediaData; import org.sakaiproject.tool.assessment.data.ifc.assessment.AnswerIfc; import org.sakaiproject.tool.assessment.data.ifc.assessment.ItemDataIfc; import org.sakaiproject.tool.assessment.data.ifc.assessment.ItemTextIfc; import org.sakaiproject.tool.assessment.data.ifc.assessment.PublishedAssessmentIfc; import org.sakaiproject.tool.assessment.data.ifc.assessment.SectionDataIfc; import org.sakaiproject.tool.assessment.facade.AgentFacade; import org.sakaiproject.tool.assessment.services.GradingService; import org.sakaiproject.tool.assessment.services.assessment.PublishedAssessmentService; import org.sakaiproject.tool.assessment.ui.bean.evaluation.AgentResults; import org.sakaiproject.tool.assessment.ui.bean.evaluation.HistogramScoresBean; import org.sakaiproject.tool.assessment.ui.bean.evaluation.PartData; import org.sakaiproject.tool.assessment.ui.bean.evaluation.QuestionScoresBean; import org.sakaiproject.tool.assessment.ui.bean.evaluation.SubmissionStatusBean; import org.sakaiproject.tool.assessment.ui.bean.evaluation.TotalScoresBean; import org.sakaiproject.tool.assessment.ui.listener.util.ContextUtil; import org.sakaiproject.tool.assessment.util.BeanSort; import org.sakaiproject.util.FormattedText; import org.sakaiproject.util.ResourceLoader; import org.sakaiproject.component.cover.ServerConfigurationService; // end testing /** * <p> * This handles the selection of the Question Score entry page. * </p> * <p> * Description: Action Listener for Evaluation Question Score front door * </p> * <p> * Copyright: Copyright (c) 2004 * </p> * <p> * Organization: Sakai Project * </p> * * @author Ed Smiley * @version $Id: QuestionScoreListener.java 11438 2006-06-30 20:06:03Z * daisyf@stanford.edu $ */ public class QuestionScoreListener implements ActionListener, ValueChangeListener { private static Log log = LogFactory.getLog(QuestionScoreListener.class); // private static EvaluationListenerUtil util; private static BeanSort bs; private static final String noAnswer = (String) ContextUtil .getLocalizedString( "org.sakaiproject.tool.assessment.bundle.EvaluationMessages", "no_answer"); /** * Standard process action method. * * @param event * ActionEvent * @throws AbortProcessingException */ public void processAction(ActionEvent event) throws AbortProcessingException { log.debug("QuestionScore LISTENER."); QuestionScoresBean bean = (QuestionScoresBean) ContextUtil .lookupBean("questionScores"); // Reset the search field String defaultSearchString = ContextUtil.getLocalizedString( "org.sakaiproject.tool.assessment.bundle.EvaluationMessages", "search_default_student_search_string"); bean.setSearchString(defaultSearchString); // we probably want to change the poster to be consistent String publishedId = ContextUtil.lookupParam("publishedId"); if (!questionScores(publishedId, bean, false)) { throw new RuntimeException("failed to call questionScores."); } } /** * Process a value change. */ public void processValueChange(ValueChangeEvent event) { log.debug("QuestionScore CHANGE LISTENER."); QuestionScoresBean bean = (QuestionScoresBean) ContextUtil.lookupBean("questionScores"); TotalScoresBean totalBean = (TotalScoresBean) ContextUtil.lookupBean("totalScores"); HistogramScoresBean histogramBean = (HistogramScoresBean) ContextUtil.lookupBean("histogramScores"); SubmissionStatusBean submissionbean = (SubmissionStatusBean) ContextUtil.lookupBean("submissionStatus"); // we probably want to change the poster to be consistent String publishedId = ContextUtil.lookupParam("publishedId"); boolean toggleSubmissionSelection = false; String selectedvalue = (String) event.getNewValue(); if ((selectedvalue != null) && (!selectedvalue.equals(""))) { if (event.getComponent().getId().indexOf("sectionpicker") > -1) { bean.setSelectedSectionFilterValue(selectedvalue); // changed totalBean.setSelectedSectionFilterValue(selectedvalue); submissionbean.setSelectedSectionFilterValue(selectedvalue); } else if (event.getComponent().getId().indexOf("allSubmissions") > -1) { bean.setAllSubmissions(selectedvalue); // changed submission // pulldown totalBean.setAllSubmissions(selectedvalue); // changed for total // score bean histogramBean.setAllSubmissions(selectedvalue); // changed for // histogram // score bean toggleSubmissionSelection = true; } else // inline or popup { bean.setSelectedSARationaleView(selectedvalue); // changed // submission // pulldown } } if (!questionScores(publishedId, bean, toggleSubmissionSelection)) { throw new RuntimeException("failed to call questionScores."); } } /** * This will populate the QuestionScoresBean with the data associated with * the particular versioned assessment based on the publishedId. * * @todo Some of this code will change when we move this to Hibernate * persistence. * @param publishedId * String * @param bean * QuestionScoresBean * @return boolean */ public boolean questionScores(String publishedId, QuestionScoresBean bean, boolean isValueChange) { log.debug("questionScores()"); try { PublishedAssessmentService pubService = new PublishedAssessmentService(); // get the PublishedAssessment based on publishedId QuestionScoresBean questionBean = (QuestionScoresBean) ContextUtil .lookupBean("questionScores"); PublishedAssessmentIfc publishedAssessment = questionBean .getPublishedAssessment(); if (publishedAssessment == null) { publishedAssessment = pubService .getPublishedAssessment(publishedId); questionBean.setPublishedAssessment(publishedAssessment); } // build a hashMap (publishedItemId, publishedItem) HashMap publishedItemHash = pubService .preparePublishedItemHash(publishedAssessment); log.debug("questionScores(): publishedItemHash.size = " + publishedItemHash.size()); // build a hashMap (publishedItemTextId, publishedItemText) HashMap publishedItemTextHash = pubService .preparePublishedItemTextHash(publishedAssessment); log.debug("questionScores(): publishedItemTextHash.size = " + publishedItemTextHash.size()); HashMap publishedAnswerHash = pubService .preparePublishedAnswerHash(publishedAssessment); log.debug("questionScores(): publishedAnswerHash.size = " + publishedAnswerHash.size()); HashMap agentResultsByItemGradingIdMap = new HashMap(); GradingService delegate = new GradingService(); TotalScoresBean totalBean = (TotalScoresBean) ContextUtil .lookupBean("totalScores"); if (ContextUtil.lookupParam("sortBy") != null && !ContextUtil.lookupParam("sortBy").trim().equals("")) bean.setSortType(ContextUtil.lookupParam("sortBy")); String itemId = ContextUtil.lookupParam("itemId"); if (ContextUtil.lookupParam("newItemId") != null && !ContextUtil.lookupParam("newItemId").trim().equals("") && !ContextUtil.lookupParam("newItemId").trim().equals("null")) itemId = ContextUtil.lookupParam("newItemId"); if (ContextUtil.lookupParam("sortAscending") != null && !ContextUtil.lookupParam("sortAscending").trim().equals( "")) { bean.setSortAscending(Boolean.valueOf( ContextUtil.lookupParam("sortAscending")) .booleanValue()); } String which = bean.getAllSubmissions(); if (which == null && totalBean.getAllSubmissions() != null) { // use totalscore's selection which = totalBean.getAllSubmissions(); bean.setAllSubmissions(which); } totalBean.setSelectedSectionFilterValue(bean .getSelectedSectionFilterValue()); // set section pulldown if (bean.getSelectedSARationaleView() == null) { // if bean.showSARationaleInLine is null, then set inline to be // the default bean.setSelectedSARationaleView(QuestionScoresBean.SHOW_SA_RATIONALE_RESPONSES_INLINE); } if ("true".equalsIgnoreCase(totalBean.getAnonymous())) { // reset sectionaware pulldown to -1 all sections //totalBean // .setSelectedSectionFilterValue(TotalScoresBean.ALL_SECTIONS_SELECT_VALUE); // changed from above by gopalrc - Jan 2008 //PublishedAssessmentService publishedAssessmentService = new PublishedAssessmentService(); //boolean groupRelease = publishedAssessmentService.isReleasedToGroups(publishedId); boolean groupRelease = publishedAssessment.getAssessmentAccessControl().getReleaseTo().equals(AssessmentAccessControl.RELEASE_TO_SELECTED_GROUPS); if (groupRelease) { totalBean.setSelectedSectionFilterValue(TotalScoresBean.RELEASED_SECTIONS_GROUPS_SELECT_VALUE); } else { totalBean.setSelectedSectionFilterValue(TotalScoresBean.ALL_SECTIONS_SELECT_VALUE); } } bean.setPublishedId(publishedId); Date dueDate = null; HashMap map = getItemScores(Long.valueOf(publishedId), Long .valueOf(itemId), which, isValueChange); log.debug("questionScores(): map .size = " + map.size()); ResourceLoader rb = null; ArrayList allscores = new ArrayList(); Iterator keyiter = map.keySet().iterator(); while (keyiter.hasNext()) { allscores.addAll((ArrayList) map.get(keyiter.next())); } log.debug("questionScores(): allscores.size = " + allscores.size()); // / // now we need filter by sections selected ArrayList scores = new ArrayList(); // filtered list Map useridMap = totalBean.getUserIdMap(TotalScoresBean.CALLED_FROM_QUESTION_SCORE_LISTENER); bean.setUserIdMap(useridMap); log.debug("questionScores(): useridMap.size = " + useridMap.size()); /* * if ("true".equalsIgnoreCase(totalBean.getAnonymous())){ // skip * section filter if it is anonymous grading, SAK-4395, * scores.addAll(allscores); } */ if (totalBean.getReleaseToAnonymous()) { // skip section filter if it's published to anonymous users scores.addAll(allscores); } else { Iterator allscores_iter = allscores.iterator(); // get the Map of all users(keyed on userid) belong to the // selected sections while (allscores_iter.hasNext()) { // AssessmentGradingData data = (AssessmentGradingData) // allscores_iter.next(); ItemGradingData idata = (ItemGradingData) allscores_iter .next(); // String agentid = // idata.getAssessmentGrading().getAgentId(); String agentid = idata.getAgentId(); // now we only include scores of users belong to the // selected sections if (useridMap.containsKey(agentid)) { scores.add(idata); } } } log.debug("questionScores(): scores.size = " + scores.size()); Iterator iter = scores.iterator(); ArrayList agents = new ArrayList(); log.debug("questionScores(): calling populateSections "); populateSections(publishedAssessment, bean, totalBean, scores, pubService); // set up the Q1, Q2... links if (!iter.hasNext()) { // this section has no students log.debug("questionScores(): this section has no students"); bean.setAgents(agents); bean.setAllAgents(agents); bean.setTotalPeople(Integer.toString(bean.getAgents().size())); bean.setAnonymous(totalBean.getAnonymous()); //return true; } // List them by item and assessmentgradingid, so we can // group answers by item and save them for update use. HashMap scoresByItem = new HashMap(); while (iter.hasNext()) { ItemGradingData idata = (ItemGradingData) iter.next(); ItemTextIfc pubItemText = (ItemTextIfc) publishedItemTextHash .get(idata.getPublishedItemTextId()); AnswerIfc pubAnswer = (AnswerIfc) publishedAnswerHash.get(idata .getPublishedAnswerId()); ArrayList temp = (ArrayList) scoresByItem.get(idata .getAssessmentGradingId() + ":" + idata.getPublishedItemId()); if (temp == null) temp = new ArrayList(); // Very small numbers, so bubblesort is fast Iterator iter2 = temp.iterator(); ArrayList newList = new ArrayList(); boolean added = false; while (iter2.hasNext()) { ItemGradingData tmpData = (ItemGradingData) iter2.next(); ItemTextIfc tmpPublishedText = (ItemTextIfc) publishedItemTextHash .get(tmpData.getPublishedItemTextId()); AnswerIfc tmpAnswer = (AnswerIfc) publishedAnswerHash .get(tmpData.getPublishedAnswerId()); if (pubAnswer != null && tmpAnswer != null && !added && (pubItemText.getSequence().intValue() < tmpPublishedText .getSequence().intValue() || (pubItemText .getSequence().intValue() == tmpPublishedText .getSequence().intValue() && pubAnswer .getSequence().intValue() < tmpAnswer .getSequence().intValue()))) { newList.add(idata); added = true; } newList.add(tmpData); } if (!added) newList.add(idata); scoresByItem.put(idata.getAssessmentGradingId() + ":" + idata.getPublishedItemId(), newList); } log.debug("questionScores(): scoresByItem.size = " + scoresByItem.size()); bean.setScoresByItem(scoresByItem); try { bean.setAnonymous(publishedAssessment.getEvaluationModel() .getAnonymousGrading().equals( EvaluationModel.ANONYMOUS_GRADING) ? "true" : "false"); } catch (RuntimeException e) { // log.info("No evaluation model."); bean.setAnonymous("false"); } // below properties don't seem to be used in jsf pages, try { bean.setLateHandling(publishedAssessment .getAssessmentAccessControl().getLateHandling() .toString()); } catch (Exception e) { // log.info("No access control model."); bean .setLateHandling(AssessmentAccessControl.NOT_ACCEPT_LATE_SUBMISSION .toString()); } try { bean.setDueDate(publishedAssessment .getAssessmentAccessControl().getDueDate().toString()); dueDate = publishedAssessment.getAssessmentAccessControl() .getDueDate(); } catch (RuntimeException e) { // log.info("No due date."); bean.setDueDate(new Date().toString()); } try { bean.setMaxScore(publishedAssessment.getEvaluationModel() .getFixedTotalScore().toString()); } catch (RuntimeException e) { double score = (double) 0.0; Iterator iter2 = publishedAssessment.getSectionArraySorted() .iterator(); while (iter2.hasNext()) { SectionDataIfc sdata = (SectionDataIfc) iter2.next(); Iterator iter3 = sdata.getItemArraySortedForGrading() .iterator(); while (iter3.hasNext()) { ItemDataIfc idata = (ItemDataIfc) iter3.next(); if (idata.getItemId().equals(Long.valueOf(itemId))) score = idata.getScore().doubleValue(); } } bean.setMaxScore(Double.toString(score)); } // need to get id from somewhere else, not from data. data only // contains answered items , we want to return all items. // ItemDataIfc item = (ItemDataIfc) publishedItemHash.get(data.getPublishedItemId()); ItemDataIfc item = (ItemDataIfc) publishedItemHash.get(Long.valueOf(itemId)); if (item != null) { log.debug("item!=null steting type id = " + item.getTypeId().toString()); bean.setTypeId(item.getTypeId().toString()); bean.setItemId(item.getItemId().toString()); bean.setPartName(item.getSection().getSequence().toString()); bean.setItemName(item.getSequence().toString()); item.setHint("***"); // Keyword to not show student answer // for short answer/ essey question, if there is a model short // answer for this question // set haveModelShortAnswer to true if (item.getTypeId().equals(Long.valueOf(5))) { Iterator iterator = publishedAnswerHash.values().iterator(); while (iterator.hasNext()) { PublishedAnswer publishedAnswer = (PublishedAnswer) iterator .next(); if (publishedAnswer.getItem().getItemId().equals( item.getItemId())) { if (publishedAnswer.getText() == null || publishedAnswer.getText().equals("")) { bean.setHaveModelShortAnswer(false); } else { bean.setHaveModelShortAnswer(true); } break; } } } } else { log.debug("item==null "); } ArrayList deliveryItems = new ArrayList(); // so we can use the var if (item != null) deliveryItems.add(item); bean.setDeliveryItem(deliveryItems); if (ContextUtil.lookupParam("roleSelection") != null) { bean.setRoleSelection(ContextUtil.lookupParam("roleSelection")); } if (bean.getSortType() == null) { if (bean.getAnonymous().equals("true")) { bean.setSortType("totalAutoScore"); } else { bean.setSortType("lastName"); } } // recordingData encapsulates the inbeanation needed for recording. // set recording agent, agent assessmentId, // set course_assignment_context value // set max tries (0=unlimited), and 30 seconds max length // String courseContext = bean.getAssessmentName() + " total "; // Note this is HTTP-centric right now, we can't use in Faces // AuthoringHelper authoringHelper = new AuthoringHelper(); // authoringHelper.getRemoteUserID() needs servlet stuff // authoringHelper.getRemoteUserName() needs servlet stuff /* Dump the grading and agent information into AgentResults */ iter = scoresByItem.values().iterator(); while (iter.hasNext()) { AgentResults results = new AgentResults(); // Get all the answers for this question to put in one grading // row ArrayList answerList = (ArrayList) iter.next(); results.setItemGradingArrayList(answerList); Iterator iter2 = answerList.iterator(); ArrayList itemGradingAttachmentList = new ArrayList(); HashMap<Long, Set<String>> fibmap = new HashMap<Long, Set<String>>(); while (iter2.hasNext()) { ItemGradingData gdata = (ItemGradingData) iter2.next(); results.setItemGrading(gdata); itemGradingAttachmentList.addAll(gdata.getItemGradingAttachmentList()); agentResultsByItemGradingIdMap.put(gdata.getItemGradingId(), results); ItemTextIfc gdataPubItemText = (ItemTextIfc) publishedItemTextHash .get(gdata.getPublishedItemTextId()); AnswerIfc gdataAnswer = (AnswerIfc) publishedAnswerHash .get(gdata.getPublishedAnswerId()); // This all just gets the text of the answer to display String answerText = noAnswer; String rationale = ""; String fullAnswerText = noAnswer; // if question type = MC, MR, Survey, TF, Matching, if user // has not submit an answer // answerText = noAnswer. These question type do not use the // itemGrading.answerText field for // storing answers, thye use temGrading.publishedAnswerId to // make their selection if (bean.getTypeId().equals("1") || bean.getTypeId().equals("2") || bean.getTypeId().equals("12") || bean.getTypeId().equals("3") || bean.getTypeId().equals("4") || bean.getTypeId().equals("9") || bean.getTypeId().equals("13")) { if (gdataAnswer != null) answerText = gdataAnswer.getText(); } else { // this handles the other question types: SAQ, File // upload, Audio, FIB, Fill in Numeric // These question type use itemGrading.answetText to // store information about their answer if ((bean.getTypeId().equals("8") || bean.getTypeId().equals("11")) && gdataAnswer == null) { answerText = ""; } else { answerText = gdata.getAnswerText(); } } if ("4".equals(bean.getTypeId())) { if (rb == null) { rb = new ResourceLoader("org.sakaiproject.tool.assessment.bundle.EvaluationMessages"); } if ("true".equals(answerText)) { answerText = rb.getString("true_msg"); } else if ("false".equals(answerText)) { answerText = rb.getString("false_msg"); } } if (bean.getTypeId().equals("9")) { if (gdataPubItemText == null) { // the matching pair is deleted answerText = ""; } else { answerText = gdataPubItemText.getSequence() + ":" + answerText; } } if (bean.getTypeId().equals("8")) { if (gdataAnswer != null && gdataAnswer.getSequence() != null) { answerText = gdataAnswer.getSequence() + ":" + answerText; } } if (bean.getTypeId().equals("11")) { if (gdataAnswer != null && gdataAnswer.getSequence() != null) { answerText = gdataAnswer.getSequence() + ":" + answerText; } } if (bean.getTypeId().equals("13")) { if (gdataPubItemText == null) { answerText = ""; } else { int answerNo = gdataPubItemText.getSequence().intValue(); answerText = answerNo + ":" + answerText; } } // file upload if (bean.getTypeId().equals("6")) { gdata.setMediaArray(delegate.getMediaArray2(gdata .getItemGradingId().toString())); } // audio recording if (bean.getTypeId().equals("7")) { ArrayList mediaList = delegate.getMediaArray2(gdata .getItemGradingId().toString()); setDurationIsOver(item, mediaList); gdata.setMediaArray(mediaList); } if (answerText == null) answerText = noAnswer; else { if (gdata.getRationale() != null && !gdata.getRationale().trim().equals("")) rationale = "\nRationale: " + gdata.getRationale(); } // Huong's temp commandout // answerText = answerText.replaceAll("<.*?>", ""); answerText = answerText.replaceAll("(\r\n|\r)", "<br/>"); rationale = rationale.replaceAll("<.*?>", ""); rationale = rationale.replaceAll("(\r\n|\r)", "<br/>"); fullAnswerText = answerText; // this is the // non-abbreviated answers // for essay questions int answerTextLength = 1000; if (!bean.getTypeId().equals("5")) { String s = ServerConfigurationService.getString("samigo.questionScore.answerText.length"); if (s != null) { try { answerTextLength = Integer.parseInt(s); } catch (NumberFormatException e) { log.warn("NumberFormatException. Use the default value for answerTextLength"); } } } else { answerTextLength = 35; } // Fix for SAK-6932: Strip out all HTML tags except image tags if (answerText.length() > answerTextLength) { String noHTMLAnswerText; noHTMLAnswerText = answerText.replaceAll( "<((..?)|([^iI][^mM][^gG].*?))>", ""); int index = noHTMLAnswerText.toLowerCase().indexOf( "<img"); if (index != -1) { answerText = noHTMLAnswerText; } else { if (noHTMLAnswerText.length() > answerTextLength) { answerText = noHTMLAnswerText.substring(0, answerTextLength) + "..."; } else { answerText = noHTMLAnswerText; } } } /* * // no need to shorten it if (rationale.length() > 35) * rationale = rationale.substring(0, 35) + "..."; */ //SAM-755-"checkmark" indicates right, add "X" to indicate wrong if (gdataAnswer != null) { String checkmarkGif = "<img src='/samigo-app/images/delivery/checkmark.gif'>"; String crossmarkGif = "<img src='/samigo-app/images/crossmark.gif'>"; if (bean.getTypeId().equals("8") || bean.getTypeId().equals("11")) { if (gdata.getIsCorrect() == null) { boolean result = false; if (bean.getTypeId().equals("8")) { result = delegate.getFIBResult(gdata, fibmap, item, publishedAnswerHash); } else { result = delegate.getFINResult(gdata, item, publishedAnswerHash); } if (result) { answerText = checkmarkGif + answerText; } else { answerText = crossmarkGif + answerText; } } else { if (gdata.getIsCorrect().booleanValue()) { answerText = checkmarkGif + answerText; } else { answerText = crossmarkGif + answerText; } } } else if (bean.getTypeId().equals("15")) { // CALCULATED_QUESTION //need to do something here for fill in the blanks if(gdataAnswer.getScore() > 0){ //if score is 0, there is no way to tell if user got the correct answer //by using "autoscore"... wish there was a better way to tell if its correct or not Double autoscore = gdata.getAutoScore(); if (!(Double.valueOf(0)).equals(autoscore)) { answerText = checkmarkGif + answerText; }else if(Double.valueOf(0).equals(autoscore)){ answerText = crossmarkGif + answerText; } } } else if(!bean.getTypeId().equals("3")){ if((gdataAnswer.getIsCorrect() != null && gdataAnswer.getIsCorrect()) || (gdataAnswer.getPartialCredit() != null && gdataAnswer.getPartialCredit() > 0)){ answerText = checkmarkGif + answerText; }else if(gdataAnswer.getIsCorrect() != null && !gdataAnswer.getIsCorrect()){ answerText = crossmarkGif + answerText; } } } // -- Got the answer text -- if (!answerList.get(0).equals(gdata)) { // We already have // an agentResults // for this one results.setAnswer(results.getAnswer() + "<br/>" + answerText); if (gdata.getAutoScore() != null) { results.setTotalAutoScore(Double.toString((Double.valueOf( results.getExactTotalAutoScore())).doubleValue() + gdata.getAutoScore().doubleValue())); } else { results.setTotalAutoScore(Double.toString((Double.valueOf( results.getExactTotalAutoScore())).doubleValue())); } results.setItemGradingAttachmentList(itemGradingAttachmentList); } else { results.setItemGradingId(gdata.getItemGradingId()); results.setAssessmentGradingId(gdata .getAssessmentGradingId()); if (gdata.getAutoScore() != null) { // for example, if an assessment has one fileupload // question, the autoscore = null results.setTotalAutoScore(gdata.getAutoScore() .toString()); } else { results.setTotalAutoScore(Double.toString(0)); } results.setComments(FormattedText.convertFormattedTextToPlaintext(gdata.getComments())); results.setAnswer(answerText); results.setFullAnswer(fullAnswerText); results.setRationale(rationale); results.setSubmittedDate(gdata.getSubmittedDate()); AgentFacade agent = new AgentFacade(gdata.getAgentId()); // log.info("Rachel: agentid = " + gdata.getAgentId()); results.setLastName(agent.getLastName()); results.setFirstName(agent.getFirstName()); results.setEmail(agent.getEmail()); if (results.getLastName() != null && results.getLastName().length() > 0) results.setLastInitial(results.getLastName() .substring(0, 1)); else if (results.getFirstName() != null && results.getFirstName().length() > 0) results.setLastInitial(results.getFirstName() .substring(0, 1)); else results.setLastInitial("Anonymous"); results.setIdString(agent.getIdString()); results.setAgentEid(agent.getEidString()); results.setAgentDisplayId(agent.getDisplayIdString()); log.debug("testing agent getEid agent.getFirstname= " + agent.getFirstName()); log.debug("testing agent getEid agent.getid= " + agent.getIdString()); log.debug("testing agent getEid agent.geteid = " + agent.getEidString()); log.debug("testing agent getDisplayId agent.getdisplayid = " + agent.getDisplayIdString()); results.setRole(agent.getRole()); results.setItemGradingAttachmentList(itemGradingAttachmentList); agents.add(results); } } } // log.info("Sort type is " + bean.getSortType() + "."); bs = new BeanSort(agents, bean.getSortType()); if ((bean.getSortType()).equals("assessmentGradingId") || (bean.getSortType()).equals("totalAutoScore") || (bean.getSortType()).equals("totalOverrideScore") || (bean.getSortType()).equals("finalScore")) { bs.toNumericSort(); } else { bs.toStringSort(); } if (bean.isSortAscending()) { log.debug("sortAscending"); agents = (ArrayList) bs.sort(); } else { log.debug("!sortAscending"); agents = (ArrayList) bs.sortDesc(); } // log.info("Listing agents."); bean.setAgents(agents); bean.setAllAgents(agents); bean .setTotalPeople(Integer.valueOf(bean.getAgents().size()) .toString()); bean.setAgentResultsByItemGradingId(agentResultsByItemGradingIdMap); } catch (RuntimeException e) { e.printStackTrace(); return false; } return true; } /** * getting a list of itemGrading for a publishedItemId is a lot of work, * read the code in GradingService.getItemScores() after we get the list, we * are saving it in QuestionScoreBean.itemScoresMap itemScoresMap = * (publishedItemId, HashMap) = (Long publishedItemId, (Long * publishedItemId, Array itemGradings)) itemScoresMap will be refreshed * when the next QuestionScore link is click */ private HashMap getItemScores(Long publishedId, Long itemId, String which, boolean isValueChange) { log.debug("getItemScores"); GradingService delegate = new GradingService(); QuestionScoresBean questionScoresBean = (QuestionScoresBean) ContextUtil .lookupBean("questionScores"); HashMap itemScoresMap = questionScoresBean.getItemScoresMap(); log.debug("getItemScores: itemScoresMap ==null ?" + itemScoresMap); log.debug("getItemScores: isValueChange ?" + isValueChange); if (itemScoresMap == null || isValueChange || questionScoresBean.getIsAnyItemGradingAttachmentListModified()) { log .debug("getItemScores: itemScoresMap == null or isValueChange == true "); log.debug("getItemScores: isValueChange = " + isValueChange); itemScoresMap = new HashMap(); questionScoresBean.setItemScoresMap(itemScoresMap); // reset this anyway (because the itemScoresMap will be refreshed as well as the // attachment list) questionScoresBean.setIsAnyItemGradingAttachmentListModified(false); } log .debug("getItemScores: itemScoresMap.size() " + itemScoresMap.size()); HashMap map = (HashMap) itemScoresMap.get(itemId); if (map == null) { log.debug("getItemScores: map == null "); map = delegate.getItemScores(publishedId, itemId, which, true); log.debug("getItemScores: map size " + map.size()); itemScoresMap.put(itemId, map); } return map; } private void setDurationIsOver(ItemDataIfc item, ArrayList mediaList) { try { int maxDurationAllowed = item.getDuration().intValue(); for (int i = 0; i < mediaList.size(); i++) { MediaData m = (MediaData) mediaList.get(i); double duration = (Double.valueOf(m.getDuration())).doubleValue(); if (duration > maxDurationAllowed) { m.setDurationIsOver(true); m.setTimeAllowed(String.valueOf(maxDurationAllowed)); } else m.setDurationIsOver(false); } } catch (Exception e) { log.warn("**duration recorded is not an integer value=" + e.getMessage()); } } private void populateSections(PublishedAssessmentIfc publishedAssessment, QuestionScoresBean bean, TotalScoresBean totalBean, ArrayList scores, PublishedAssessmentService pubService) { ArrayList sections = new ArrayList(); log .debug("questionScores(): populate sctions publishedAssessment.getSectionArraySorted size = " + publishedAssessment.getSectionArraySorted().size()); Iterator iter = publishedAssessment.getSectionArraySorted().iterator(); int i = 1; while (iter.hasNext()) { SectionDataIfc section = (SectionDataIfc) iter.next(); ArrayList items = new ArrayList(); PartData part = new PartData(); boolean isRandomDrawPart = pubService.isRandomDrawPart( publishedAssessment.getPublishedAssessmentId(), section .getSectionId()); part.setIsRandomDrawPart(isRandomDrawPart); part.setPartNumber("" + i); part.setId(section.getSectionId().toString()); if (isRandomDrawPart) { if (section.getSectionMetaDataByLabel(SectionDataIfc.NUM_QUESTIONS_DRAWN) !=null ) { int numberToBeDrawn = Integer.parseInt(section.getSectionMetaDataByLabel(SectionDataIfc.NUM_QUESTIONS_DRAWN)); part.setNumberQuestionsDraw(numberToBeDrawn); } PublishedAssessmentService publishedAssessmentService = new PublishedAssessmentService(); HashSet itemSet = publishedAssessmentService.getPublishedItemSet(publishedAssessment .getPublishedAssessmentId(), section.getSectionId()); section.setItemSet(itemSet); } else { GradingService gradingService = new GradingService(); HashSet itemSet = gradingService.getItemSet(publishedAssessment .getPublishedAssessmentId(), section.getSectionId()); section.setItemSet(itemSet); } Iterator iter2 = section.getItemArraySortedForGrading().iterator(); int j = 1; while (iter2.hasNext()) { ItemDataIfc item = (ItemDataIfc) iter2.next(); PartData partitem = new PartData(); partitem.setPartNumber("" + j); partitem.setId(item.getItemId().toString()); log.debug("* item.getId = " + item.getItemId()); partitem.setLinked(true); // Iterator iter3 = scores.iterator(); items.add(partitem); j++; } log.debug("questionScores(): items size = " + items.size()); part.setQuestionNumberList(items); sections.add(part); i++; } log.debug("questionScores(): sections size = " + sections.size()); bean.setSections(sections); } }