001: /**********************************************************************************
002: * $URL$
003: * $Id$
004: ***********************************************************************************
005: *
006: * Copyright (c) 2004, 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the"License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.tool.assessment.ui.bean.evaluation;
021:
022: import java.io.Serializable;
023: import java.util.ArrayList;
024: import java.util.Collection;
025: import java.util.HashMap;
026: import java.util.Iterator;
027:
028: import javax.faces.event.ActionEvent;
029:
030: import org.apache.commons.lang.StringUtils;
031: import org.apache.commons.logging.Log;
032: import org.apache.commons.logging.LogFactory;
033:
034: import org.sakaiproject.jsf.model.PhaseAware;
035: import org.sakaiproject.tool.assessment.business.entity.RecordingData;
036: import org.sakaiproject.tool.assessment.ui.bean.util.Validator;
037: import org.sakaiproject.tool.assessment.ui.listener.evaluation.SubmissionStatusListener;
038: import org.sakaiproject.tool.assessment.ui.listener.util.ContextUtil;
039:
040: /**
041: * <p>Description: class form for evaluating submission status</p>
042: *
043: *
044: */
045: public class SubmissionStatusBean implements Serializable, PhaseAware {
046: private String assessmentId;
047: private String publishedId;
048:
049: /** Use serialVersionUID for interoperability. */
050: private final static long serialVersionUID = 5517587781720762296L;
051: private String assessmentName;
052: private String anonymous;
053: private String groupName;
054: private String maxScore;
055: private Collection agents;
056: private Collection sortedAgents;
057: private String totalScore;
058: private String adjustmentTotalScore;
059: private String totalScoreComments;
060: private String sortProperty;
061: private String lateHandling; // read-only property set for UI late handling
062: private String dueDate;
063: private String sortType;
064: private boolean sortAscending = true;
065: private String roleSelection;
066: private String allSubmissions;
067: private RecordingData recordingData;
068: private String totalPeople;
069: private String firstItem;
070: private HashMap answeredItems;
071: private static Log log = LogFactory
072: .getLog(SubmissionStatusBean.class);
073: private String selectedSectionFilterValue = TotalScoresBean.ALL_SECTIONS_SELECT_VALUE;
074: private ArrayList allAgents;
075:
076: // Paging.
077: private int firstScoreRow;
078: private int maxDisplayedScoreRows;
079: private int scoreDataRows;
080:
081: // Searching
082: private String searchString;
083: private String defaultSearchString;
084:
085: /**
086: * Creates a new SubmissionStatusBean object.
087: */
088: public SubmissionStatusBean() {
089: log.debug("Creating a new SubmissionStatusBean");
090: resetFields();
091: }
092:
093: protected void init() {
094: defaultSearchString = ContextUtil
095: .getLocalizedString(
096: "org.sakaiproject.tool.assessment.bundle.EvaluationMessages",
097: "search_default_student_search_string");
098: if (searchString == null) {
099: searchString = defaultSearchString;
100: }
101:
102: // Get allAgents only at the first time
103: if (allAgents == null) {
104: allAgents = getAllAgents();
105: }
106:
107: ArrayList matchingAgents;
108: if (isFilteredSearch()) {
109: matchingAgents = findMatchingAgents(searchString);
110: } else {
111: matchingAgents = allAgents;
112: }
113: scoreDataRows = matchingAgents.size();
114: ArrayList newAgents = new ArrayList();
115: if (maxDisplayedScoreRows == 0) {
116: newAgents = matchingAgents;
117: } else {
118: int nextPageRow = Math.min(firstScoreRow
119: + maxDisplayedScoreRows, scoreDataRows);
120: newAgents = new ArrayList(matchingAgents.subList(
121: firstScoreRow, nextPageRow));
122: log.debug("init(): subList " + firstScoreRow + ", "
123: + nextPageRow);
124: }
125:
126: agents = newAgents;
127: }
128:
129: // Following three methods are for interface PhaseAware
130: public void endProcessValidators() {
131: log.debug("endProcessValidators");
132: }
133:
134: public void endProcessUpdates() {
135: log.debug("endProcessUpdates");
136: }
137:
138: public void startRenderResponse() {
139: log.debug("startRenderResponse");
140: init();
141: }
142:
143: /**
144: * get assessment name
145: *
146: * @return the name
147: */
148: public String getAssessmentName() {
149: return Validator.check(assessmentName, "N/A");
150: }
151:
152: /**
153: * set assessment name
154: *
155: * @param passessmentName the name
156: */
157: public void setAssessmentName(String passessmentName) {
158: assessmentName = passessmentName;
159: }
160:
161: /**
162: * get assessment id
163: *
164: * @return the assessment id
165: */
166: public String getAssessmentId() {
167: return Validator.check(assessmentId, "0");
168: }
169:
170: /**
171: * set assessment id
172: *
173: * @param passessmentId the id
174: */
175: public void setAssessmentId(String passessmentId) {
176: assessmentId = passessmentId;
177: }
178:
179: /**
180: * get published id
181: *
182: * @return the published id
183: */
184: public String getPublishedId() {
185: return Validator.check(publishedId, "0");
186: }
187:
188: /**
189: * set published id
190: *
191: * @param passessmentId the id
192: */
193: public void setPublishedId(String ppublishedId) {
194: publishedId = ppublishedId;
195: }
196:
197: /**
198: * Is this anonymous grading?
199: *
200: * @return anonymous grading? true or false
201: */
202: public String getAnonymous() {
203: return Validator.check(anonymous, "false");
204: }
205:
206: /**
207: * Set switch if this is anonymous grading.
208: *
209: * @param panonymous anonymous grading? true or false
210: */
211: public void setAnonymous(String panonymous) {
212: anonymous = panonymous;
213: }
214:
215: /**
216: * Get the group name
217: * @return group name
218: */
219: public String getGroupName() {
220: return Validator.check(groupName, "N/A");
221: }
222:
223: /**
224: * set the group name
225: *
226: * @param pgroupName the name
227: */
228: public void setGroupName(String pgroupName) {
229: groupName = pgroupName;
230: }
231:
232: /**
233: * get the max score
234: *
235: * @return the max score
236: */
237: public String getMaxScore() {
238: return Validator.check(maxScore, "N/A");
239: }
240:
241: /**
242: * set max score
243: *
244: * @param pmaxScore set the max score
245: */
246: public void setMaxScore(String pmaxScore) {
247: maxScore = pmaxScore;
248: }
249:
250: /**
251: * get an agent result collection
252: *
253: * @return the collection
254: */
255: public Collection getAgents() {
256: if (agents == null)
257: return new ArrayList();
258: return agents;
259: }
260:
261: /**
262: * set the agent collection
263: *
264: * @param pagents the collection
265: */
266: public void setAgents(Collection pagents) {
267: agents = pagents;
268: }
269:
270: /** This is a read-only calculated property.
271: * @return list of uppercase student initials
272: */
273: public String getAgentInitials() {
274: Collection c = getAgents();
275: String initials = "";
276: if (c.isEmpty()) {
277: return "";
278: }
279:
280: Iterator it = c.iterator();
281:
282: while (it.hasNext()) {
283: try {
284: AgentResults ar = (AgentResults) it.next();
285: String initial = ar.getLastInitial();
286: initials = initials + initial;
287: } catch (Exception ex) {
288: // if there is any problem, we skip, and go on
289: log.warn(ex.getMessage());
290: }
291: }
292:
293: return initials.toUpperCase();
294: }
295:
296: /**
297: * get agent resutls as an array
298: *
299: * @return the array
300: */
301: public Object[] getAgentArray() {
302: if (agents == null)
303: return new Object[0];
304: return agents.toArray();
305: }
306:
307: /**
308: * get the total number of students for this assessment
309: *
310: * @return the number
311: */
312: public String getTotalPeople() {
313: return Validator.check(totalPeople, "N/A");
314: }
315:
316: /**
317: * set the total number of people
318: *
319: * @param ptotalPeople the total
320: */
321: public void setTotalPeople(String ptotalPeople) {
322: totalPeople = ptotalPeople;
323: }
324:
325: /**
326: *
327: * @return the total score
328: */
329: public String getTotalScore() {
330: return Validator.check(totalScore, "N/A");
331: }
332:
333: /**
334: * set the total score
335: *
336: * @param pTotalScore the total score
337: */
338: public void setTotalScore(String pTotalScore) {
339: totalScore = pTotalScore;
340: }
341:
342: /**
343: * get the adjustment to the total score
344: *
345: * @return the total score
346: */
347: public String getAdjustmentTotalScore() {
348: return Validator.check(adjustmentTotalScore, "N/A");
349: }
350:
351: /**
352: * set the adjustment to total score
353: *
354: * @param pAdjustmentTotalScore the adjustment
355: */
356: public void setAdjustmentTotalScore(String pAdjustmentTotalScore) {
357: adjustmentTotalScore = pAdjustmentTotalScore;
358: }
359:
360: /**
361: * get total score
362: *
363: * @return the total score
364: */
365: public String getTotalScoreComments() {
366: return Validator.check(totalScoreComments, "");
367: }
368:
369: /**
370: * set comments for totals score
371: *
372: * @param pTotalScoreComments the comments
373: */
374: public void setTotalScoreComments(String pTotalScoreComments) {
375: log.debug("setting total score comments to "
376: + pTotalScoreComments);
377: totalScoreComments = pTotalScoreComments;
378: }
379:
380: /**
381: * get late handling
382: *
383: * @return late handlign
384: */
385: public String getLateHandling() {
386: return Validator.check(lateHandling, "1");
387: }
388:
389: /**
390: * set late handling
391: *
392: * @param plateHandling the late handling
393: */
394: public void setLateHandling(String plateHandling) {
395: lateHandling = plateHandling;
396: }
397:
398: /**
399: * get the due date
400: *
401: * @return the due date as a String
402: */
403: public String getDueDate() {
404: return Validator.check(dueDate, "N/A");
405: }
406:
407: /**
408: * set due date string
409: *
410: * @param dateString the date string
411: */
412: public void setDueDate(String dateString) {
413: dueDate = dateString;
414: }
415:
416: /**
417: * get sort type
418: * @return sort type
419: */
420: public String getSortType() {
421: return Validator.check(sortType, "lastName");
422: }
423:
424: /**
425: * set sort type, trigger property sorts
426: * @param psortType the type
427: */
428: public void setSortType(String psortType) {
429: sortType = psortType;
430: }
431:
432: /**
433: * is scores table sorted in ascending order
434: * @return true if it is
435: */
436: public boolean isSortAscending() {
437: return sortAscending;
438: }
439:
440: /**
441: *
442: * @param sortAscending is scores table sorted in ascending order
443: */
444: public void setSortAscending(boolean sortAscending) {
445: this .sortAscending = sortAscending;
446: }
447:
448: /**
449: * Is this an all submissions or, just the largest
450: * @return true if is is, else false
451: */
452: public String getAllSubmissions() {
453: return Validator.check(allSubmissions, "false");
454: }
455:
456: /**
457: * set whether all submissions are to be exposed
458: * @param pallSubmissions true if it is
459: */
460: public void setAllSubmissions(String pallSubmissions) {
461: allSubmissions = pallSubmissions;
462: }
463:
464: /**
465: * DOCUMENTATION PENDING
466: *
467: * @return DOCUMENTATION PENDING
468: */
469: public String getRoleSelection() {
470: return Validator.check(roleSelection, "N/A");
471: }
472:
473: /**
474: * DOCUMENTATION PENDING
475: *
476: * @param proleSelection DOCUMENTATION PENDING
477: */
478: public void setRoleSelection(String proleSelection) {
479: roleSelection = proleSelection;
480: }
481:
482: /**
483: * DOCUMENTATION PENDING
484: *
485: * @return DOCUMENTATION PENDING
486: */
487: public String getFirstItem() {
488: return Validator.check(firstItem, "");
489: }
490:
491: /**
492: * DOCUMENTATION PENDING
493: *
494: * @param proleSelection DOCUMENTATION PENDING
495: */
496: public void setFirstItem(String pfirstItem) {
497: firstItem = pfirstItem;
498: }
499:
500: /**
501: * reset the fields
502: */
503: public void resetFields() {
504: agents = new ArrayList();
505: setAgents(agents);
506: }
507:
508: /**
509: * encapsulates audio recording info
510: * @return recording data
511: */
512: public RecordingData getRecordingData() {
513: return this .recordingData;
514: }
515:
516: /**
517: * encapsulates audio recording info
518: * @param rd
519: */
520: public void setRecordingData(RecordingData rd) {
521: this .recordingData = rd;
522: }
523:
524: /**
525: * This returns a map of which items actually have answers.
526: * Used by QuestionScores.
527: */
528: public HashMap getAnsweredItems() {
529: return answeredItems;
530: }
531:
532: /**
533: * This stores a map of which items actually have answers.
534: * Used by QuestionScores.
535: */
536: public void setAnsweredItems(HashMap newItems) {
537: answeredItems = newItems;
538: }
539:
540: public String getSelectedSectionFilterValue() {
541: return selectedSectionFilterValue;
542: }
543:
544: public void setSelectedSectionFilterValue(String param) {
545: if (!param.equals(this .selectedSectionFilterValue)) {
546: this .selectedSectionFilterValue = param;
547: setFirstRow(0); // clear the paging when we update the search
548: }
549: }
550:
551: public int getFirstRow() {
552: return firstScoreRow;
553: }
554:
555: public void setFirstRow(int firstRow) {
556: firstScoreRow = firstRow;
557: }
558:
559: public int getMaxDisplayedRows() {
560: return maxDisplayedScoreRows;
561: }
562:
563: public void setMaxDisplayedRows(int maxDisplayedRows) {
564: maxDisplayedScoreRows = maxDisplayedRows;
565: }
566:
567: public int getDataRows() {
568: return scoreDataRows;
569: }
570:
571: public void setAllAgents(ArrayList allAgents) {
572: this .allAgents = allAgents;
573: }
574:
575: public ArrayList getAllAgents() {
576: log.debug("getAllAgents()");
577: TotalScoresBean totalScoresBean = (TotalScoresBean) ContextUtil
578: .lookupBean("totalScores");
579: String publishedId = ContextUtil.lookupParam("publishedId");
580: SubmissionStatusListener submissionStatusListener = new SubmissionStatusListener();
581:
582: if (!submissionStatusListener.submissionStatus(publishedId,
583: this , totalScoresBean, false)) {
584: throw new RuntimeException("failed to call questionScores.");
585: }
586: return allAgents;
587: }
588:
589: public String getSearchString() {
590: return searchString;
591: }
592:
593: public void setSearchString(String searchString) {
594: if (StringUtils.trimToNull(searchString) == null) {
595: searchString = defaultSearchString;
596: }
597: if (!StringUtils.equals(searchString, this .searchString)) {
598: log.debug("setSearchString " + searchString);
599: this .searchString = searchString;
600: setFirstRow(0); // clear the paging when we update the search
601: }
602: }
603:
604: public void search(ActionEvent event) {
605: // We don't need to do anything special here, since init will handle the search
606: log.debug("search");
607: }
608:
609: public void clear(ActionEvent event) {
610: log.debug("clear");
611: setSearchString(null);
612: }
613:
614: private boolean isFilteredSearch() {
615: return !StringUtils.equals(searchString, defaultSearchString);
616: }
617:
618: public ArrayList findMatchingAgents(final String pattern) {
619: ArrayList filteredList = new ArrayList();
620: // name1 example: John Doe
621: StringBuffer name1;
622: // name2 example: Doe, John
623: StringBuffer name2;
624: for (Iterator iter = allAgents.iterator(); iter.hasNext();) {
625: AgentResults result = (AgentResults) iter.next();
626: // name1 example: John Doe
627: name1 = new StringBuffer(result.getFirstName());
628: name1.append(" ");
629: name1.append(result.getLastName());
630: // name2 example: Doe, John
631: name2 = new StringBuffer(result.getLastName());
632: name2.append(", ");
633: name2.append(result.getFirstName());
634: if (result.getFirstName().toLowerCase().startsWith(
635: pattern.toLowerCase())
636: || result.getLastName().toLowerCase().startsWith(
637: pattern.toLowerCase())
638: || result.getAgentEid().toLowerCase().startsWith(
639: pattern.toLowerCase())
640: || name1.toString().toLowerCase().startsWith(
641: pattern.toLowerCase())
642: || name2.toString().toLowerCase().startsWith(
643: pattern.toLowerCase())) {
644: filteredList.add(result);
645: }
646: }
647: return filteredList;
648: }
649: }
|