Java tutorial
/********************************************************************************** * $URL$ * $Id$ *********************************************************************************** * * Copyright (c) 2008, 2009, 2010, 2013, 2014 Etudes, Inc. * * Portions completed before September 1, 2008 * Copyright (c) 2007, 2008 The Regents of the University of Michigan & Foothill College, ETUDES Project * * Licensed under the Apache 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.apache.org/licenses/LICENSE-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.etudes.mneme.impl; import java.text.DateFormat; import java.text.ParseException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.etudes.mneme.api.Assessment; import org.etudes.mneme.api.AssessmentAccess; import org.etudes.mneme.api.AssessmentService; import org.etudes.mneme.api.AssessmentType; import org.etudes.mneme.api.Part; import org.etudes.mneme.api.PartDetail; import org.etudes.mneme.api.Pool; import org.etudes.mneme.api.PoolDraw; import org.etudes.mneme.api.PoolService; import org.etudes.mneme.api.Question; import org.etudes.mneme.api.QuestionGrouping; import org.etudes.mneme.api.QuestionPick; import org.etudes.mneme.api.QuestionService; import org.etudes.mneme.api.ReviewShowCorrect; import org.etudes.mneme.api.ReviewTiming; import org.etudes.mneme.api.SecurityService; import org.etudes.mneme.api.SubmissionService; import org.sakaiproject.i18n.InternationalizedMessages; import org.sakaiproject.user.api.UserDirectoryService; import org.sakaiproject.util.ResourceLoader; import org.sakaiproject.util.StringUtil; /** * QuestionStorageSample defines a sample storage for questions. */ public class AssessmentStorageSample implements AssessmentStorage { /** Our logger. */ private static Log M_log = LogFactory.getLog(AssessmentStorageSample.class); protected Map<String, AssessmentImpl> assessments = new LinkedHashMap<String, AssessmentImpl>(); protected AssessmentService assessmentService = null; /** Messages bundle name. */ protected String bundle = null; protected boolean fakedAlready = false; protected Object idGenerator = new Object(); /** Messages. */ protected transient InternationalizedMessages messages = null; protected long nextAccessId = 100; protected long nextAssessmentId = 100; protected long nextPartId = 100; protected PoolService poolService = null; protected QuestionService questionService = null; /** Dependency: SecuritySevice. */ protected SecurityService securityService = null; protected SubmissionService submissionService = null; /** Dependency: UserDirectoryService. */ protected UserDirectoryService userDirectoryService = null; /** * {@inheritDoc} */ public void applyBaseDate(String context, int days_diff) { // TODO: could be implemented return; } /** * {@inheritDoc} */ public List<String> clearStaleMintAssessments(Date stale) { List<String> rv = new ArrayList<String>(); // find them List<String> delete = new ArrayList<String>(); for (AssessmentImpl assessment : this.assessments.values()) { if (assessment.getMint() && assessment.getCreatedBy().getDate().before(stale)) { delete.add(assessment.getId()); } } // remove them for (String id : delete) { this.assessments.remove(id); rv.add(id); } return rv; } /** * {@inheritDoc} */ public AssessmentImpl clone(AssessmentImpl assessment) { return new AssessmentImpl(assessment); } /** * {@inheritDoc} */ public Integer countAssessments(String context) { fakeIt(); int i = 0; for (AssessmentImpl assessment : this.assessments.values()) { if (assessment.getContext().equals(context) && !assessment.getArchived() && !assessment.getMint()) { i++; } } return i; } /** * Returns to uninitialized state. */ public void destroy() { M_log.info("destroy()"); } /** * {@inheritDoc} */ public Boolean existsAssessment(String id) { fakeIt(); return (this.assessments.get(id) != null); } /** * {@inheritDoc} */ public List<AssessmentImpl> getArchivedAssessments(String context) { fakeIt(); List<AssessmentImpl> rv = new ArrayList<AssessmentImpl>(); for (AssessmentImpl assessment : this.assessments.values()) { if (assessment.getContext().equals(context) && assessment.getArchived()) { rv.add(new AssessmentImpl(assessment)); } } // sort - archive date ascending Collections.sort(rv, new Comparator() { public int compare(Object arg0, Object arg1) { int rv = ((Assessment) arg0).getDates().getArchivedDate() .compareTo(((Assessment) arg1).getDates().getArchivedDate()); return rv; } }); return rv; } /** * {@inheritDoc} */ public AssessmentImpl getAssessment(String id) { if (id == null) return null; fakeIt(); AssessmentImpl rv = this.assessments.get(id); if (rv != null) { rv = new AssessmentImpl(rv); } return rv; } public List<AssessmentImpl> getAssessmentsNeedingResultsEmail() { // TODO: return new ArrayList<AssessmentImpl>(); } /** * {@inheritDoc} */ public List<AssessmentImpl> getContextAssessments(String context, final AssessmentService.AssessmentsSort sort, Boolean publishedOnly) { fakeIt(); List<AssessmentImpl> rv = new ArrayList<AssessmentImpl>(); for (AssessmentImpl assessment : this.assessments.values()) { if (assessment.getContext().equals(context) && !assessment.getArchived() && !assessment.getMint()) { // filter out unpublished if requested (also ignoring invalid) if (publishedOnly) { if ((!assessment.getPublished()) || (!assessment.getIsValid())) continue; } rv.add(new AssessmentImpl(assessment)); } } // sort - use title as a secondary sort (or for title, use create date as secondary sort) // sort ascending first - reverse if descending Collections.sort(rv, new Comparator() { public int compare(Object arg0, Object arg1) { int rv = 0; AssessmentService.AssessmentsSort secondary = null; switch (sort) { case published_a: case published_d: { rv = ((Assessment) arg0).getPublished().compareTo(((Assessment) arg1).getPublished()); secondary = AssessmentService.AssessmentsSort.title_a; break; } case title_a: case title_d: { String s0 = StringUtil.trimToZero(((Assessment) arg0).getTitle()); String s1 = StringUtil.trimToZero(((Assessment) arg1).getTitle()); rv = s0.compareToIgnoreCase(s1); secondary = AssessmentService.AssessmentsSort.cdate_a; break; } case type_a: case type_d: { rv = ((Assessment) arg0).getType().getSortValue() .compareTo(((Assessment) arg1).getType().getSortValue()); secondary = AssessmentService.AssessmentsSort.title_a; break; } case odate_a: case odate_d: { // no open date sorts low if (((Assessment) arg0).getDates().getOpenDate() == null) { if (((Assessment) arg1).getDates().getOpenDate() == null) { rv = 0; } else { rv = -1; } } else if (((Assessment) arg1).getDates().getOpenDate() == null) { rv = 1; } else { rv = ((Assessment) arg0).getDates().getOpenDate() .compareTo(((Assessment) arg1).getDates().getOpenDate()); } secondary = AssessmentService.AssessmentsSort.title_a; break; } case ddate_a: case ddate_d: { // no open date sorts high if (((Assessment) arg0).getDates().getDueDate() == null) { if (((Assessment) arg1).getDates().getDueDate() == null) { rv = 0; } else { rv = 1; } } else if (((Assessment) arg1).getDates().getDueDate() == null) { rv = -1; } else { rv = ((Assessment) arg0).getDates().getDueDate() .compareTo(((Assessment) arg1).getDates().getDueDate()); } secondary = AssessmentService.AssessmentsSort.title_a; break; } case cdate_a: case cdate_d: { rv = ((Assessment) arg0).getCreatedBy().getDate() .compareTo(((Assessment) arg1).getCreatedBy().getDate()); break; } } // kick in the secondary if needed AssessmentService.AssessmentsSort third = null; if ((rv == 0) && (secondary != null)) { switch (secondary) { case title_a: case title_d: { String s0 = StringUtil.trimToZero(((Assessment) arg0).getTitle()); String s1 = StringUtil.trimToZero(((Assessment) arg1).getTitle()); rv = s0.compareToIgnoreCase(s1); third = AssessmentService.AssessmentsSort.cdate_a; break; } case cdate_a: case cdate_d: { rv = ((Assessment) arg0).getCreatedBy().getDate() .compareTo(((Assessment) arg1).getCreatedBy().getDate()); break; } } } // third sort if ((rv == 0) && (third != null)) { switch (third) { case cdate_a: case cdate_d: { rv = ((Assessment) arg0).getCreatedBy().getDate() .compareTo(((Assessment) arg1).getCreatedBy().getDate()); break; } } } return rv; } }); // reverse for descending switch (sort) { case cdate_d: case ddate_d: case odate_d: case published_d: case title_d: case type_d: { Collections.reverse(rv); } } return rv; } /** * {@inheritDoc} */ public List<AssessmentImpl> getContextGbInvalidAssessments(String context) { fakeIt(); List<AssessmentImpl> rv = new ArrayList<AssessmentImpl>(); for (AssessmentImpl assessment : this.assessments.values()) { if (assessment.getContext().equals(context)) { // filter out all but gb invalid if (assessment.getGrading().getGradebookRejectedAssessment()) { rv.add(new AssessmentImpl(assessment)); } } } return rv; } public List<AssessmentImpl> getFormalEvaluationsNeedingNotification() { // TODO: return new ArrayList<AssessmentImpl>(); } /** * {@inheritDoc} */ public Date getMaxStartDate(String context) { // TODO: could be implemented return null; } /** * {@inheritDoc} */ public Date getMinStartDate(String context) { // TODO: could be implemented return null; } /** * Final initialization, once all dependencies are set. */ public void init() { // messages if (this.bundle != null) this.messages = new ResourceLoader(this.bundle); M_log.info("init()"); } /** * {@inheritDoc} */ public void makeLive(Assessment assessment) { AssessmentImpl rv = this.assessments.get(assessment.getId()); if (rv != null) { rv.initLive(Boolean.TRUE); } } /** * {@inheritDoc} */ public AssessmentImpl newAssessment() { return new AssessmentImpl(this.assessmentService, this.poolService, this.questionService, this.submissionService, this.securityService, this.userDirectoryService, this.messages); } /** * {@inheritDoc} */ public void removeAssessment(AssessmentImpl assessment) { fakeIt(); this.assessments.remove(assessment.getId()); } /** * {@inheritDoc} */ public void removeDependency(Pool pool) { for (AssessmentImpl assessment : this.assessments.values()) { if (assessment.getContext().equals(pool.getContext()) && (!assessment.getIsLocked())) { for (Part part : assessment.getParts().getParts()) { for (Iterator<PartDetail> i = part.getDetails().iterator(); i.hasNext();) { PartDetail detail = i.next(); if (detail instanceof PoolDraw) { PoolDraw draw = (PoolDraw) detail; if (draw.getPoolId().equals(pool.getId())) { i.remove(); } } } } } } } /** * {@inheritDoc} */ public void removeDependency(Question question) { for (AssessmentImpl assessment : this.assessments.values()) { if (assessment.getContext().equals(question.getContext()) && (!assessment.getIsLocked())) { for (Part part : assessment.getParts().getParts()) { for (Iterator<PartDetail> i = part.getDetails().iterator(); i.hasNext();) { PartDetail detail = i.next(); if (detail instanceof QuestionPick) { QuestionPick pick = (QuestionPick) detail; if (pick.getQuestionId().equals(question.getId())) { i.remove(); } } } } } } } /** * {@inheritDoc} */ public void saveAssessment(AssessmentImpl assessment) { fakeIt(); // clear changed assessment.clearChanged(); for (AssessmentAccess access : assessment.getSpecialAccess().getAccess()) { ((AssessmentAccessImpl) access).clearChanged(); } ((AssessmentSpecialAccessImpl) assessment.getSpecialAccess()).clearDeleted(); for (Part part : assessment.getParts().getParts()) { ((PartImpl) part).clearChanged(); ((PartImpl) part).clearDeleted(); for (PartDetail detail : part.getDetails()) { ((PartDetailImpl) detail).clearChanged(); } } ((AssessmentPartsImpl) assessment.getParts()).clearDeleted(); // assign an id boolean idsNeeded = false; if (assessment.getId() == null) { long id = 0; synchronized (this.idGenerator) { id = this.nextAssessmentId; this.nextAssessmentId++; } assessment.initId("a" + Long.toString(id)); // we will generate new ids for parts even if they have old ones (for making copies of assessments) idsNeeded = true; } // assign part ids for (Part part : assessment.getParts().getParts()) { if (idsNeeded || (part.getId() == null)) { long id = 0; synchronized (this.idGenerator) { id = this.nextPartId; this.nextPartId++; } ((PartImpl) part).initId("p" + Long.toString(id)); } } // assign special access ids for (AssessmentAccess access : assessment.getSpecialAccess().getAccess()) { if (idsNeeded || (access.getId() == null)) { long id = 0; synchronized (this.idGenerator) { id = this.nextAccessId; this.nextAccessId++; } ((AssessmentAccessImpl) access).initId("x" + Long.toString(id)); } } // TODO: assign part detail ids // save a copy AssessmentImpl copy = new AssessmentImpl(assessment); this.assessments.put(assessment.getId(), copy); } /** * Set the AssessmentService. * * @param service * The AssessmentService. */ public void setAssessmentService(AssessmentService service) { this.assessmentService = service; } /** * Set the message bundle. * * @param bundle * The message bundle. */ public void setBundle(String name) { this.bundle = name; } /** * {@inheritDoc} */ public void setEvaluationSent(String id, Date date) { // TODO: } /** * Set the PoolService. * * @param service * The PoolService. */ public void setPoolService(PoolService service) { this.poolService = service; } /** * Set the QuestionService. * * @param service * The QuestionService. */ public void setQuestionService(QuestionService service) { this.questionService = service; } /** * {@inheritDoc} */ public void setResultsSent(String id, Date date) { // TODO: } /** * Set the SecurityService. * * @param service * The PoolService. */ public void setSecurityService(SecurityService service) { this.securityService = service; } /** * Set the SubmissionService. * * @param service * The SubmissionService. */ public void setSubmissionService(SubmissionService service) { this.submissionService = service; } /** * Set the UserDirectoryService. * * @param service * The UserDirectoryService. */ public void setUserDirectoryService(UserDirectoryService service) { this.userDirectoryService = service; } protected void fakeIt() { if (!fakedAlready) { fakedAlready = true; Date now = new Date(); AssessmentImpl a = newAssessment(); a.initId("a1"); a.setPublished(Boolean.TRUE); a.setContext("mercury"); a.getCreatedBy().setUserId("admin"); a.setTries(3); a.setQuestionGrouping(QuestionGrouping.question); a.setRandomAccess(Boolean.TRUE); a.setTimeLimit(1200l * 1000l); a.setTitle("Ann Arbor"); a.setType(AssessmentType.test); // a.getAccess().setPassword("password"); a.getCreatedBy().setUserId("admin"); a.getCreatedBy().setDate(now); a.getModifiedBy().setUserId("admin"); a.getModifiedBy().setDate(now); try { a.getDates().setOpenDate(DateFormat.getDateInstance(DateFormat.SHORT).parse("10/01/07")); ((AssessmentDatesImpl) a.getDates()) .initDueDate(DateFormat.getDateInstance(DateFormat.SHORT).parse("12/22/07")); } catch (ParseException e) { } a.getGrading().setAutoRelease(Boolean.FALSE); a.getGrading().setGradebookIntegration(Boolean.FALSE); a.getGrading().setAnonymous(Boolean.FALSE); a.getPresentation().setText("This is assessment one."); a.getReview().setShowCorrectAnswer(ReviewShowCorrect.yes); a.getReview().setShowFeedback(Boolean.TRUE); a.getReview().setShowSummary(Boolean.FALSE); a.getReview().setTiming(ReviewTiming.graded); a.setMinScoreSet(Boolean.FALSE); a.getSubmitPresentation().setText("Thanks for all the fish!"); Part p = a.getParts().addPart(); p.setRandomize(Boolean.FALSE); p.setTitle("Part one"); ((PartImpl) p).initId("p1"); p.addPickDetail(this.questionService.getQuestion("q1")); p.addPickDetail(this.questionService.getQuestion("q3")); p.addPickDetail(this.questionService.getQuestion("q4")); p.getPresentation().setText("This is part one."); p = a.getParts().addPart(); p.setRandomize(Boolean.FALSE); p.setTitle("Part two"); ((PartImpl) p).initId("p2"); p.addPickDetail(this.questionService.getQuestion("q5")); p.addPickDetail(this.questionService.getQuestion("q7")); p.addPickDetail(this.questionService.getQuestion("q8")); p.getPresentation().setText("This is part two."); a.clearChanged(); a.clearMint(); ((AssessmentGradingImpl) (a.getGrading())).initAutoRelease(a.getGrading().getAutoRelease()); ((AssessmentGradingImpl) (a.getGrading())) .initGradebookIntegration(a.getGrading().getGradebookIntegration()); a.initTitle(a.getTitle()); a.initPublished(a.getPublished()); this.assessments.put(a.getId(), a); // a = newAssessment(); a.setType(AssessmentType.assignment); a.initId("a2"); a.setPublished(Boolean.TRUE); a.setContext("mercury"); a.getCreatedBy().setUserId("admin"); a.setTries(5); a.setQuestionGrouping(QuestionGrouping.question); a.setRandomAccess(Boolean.TRUE); // a.setTimeLimit(1200l * 1000l); a.setTitle("Boston"); // a.getAccess().setPassword("password"); a.getCreatedBy().setUserId("admin"); a.getCreatedBy().setDate(now); a.getModifiedBy().setUserId("admin"); a.getModifiedBy().setDate(now); try { a.getDates().setOpenDate(DateFormat.getDateInstance(DateFormat.SHORT).parse("09/01/07")); ((AssessmentDatesImpl) a.getDates()) .initDueDate(DateFormat.getDateInstance(DateFormat.SHORT).parse("12/15/07")); } catch (ParseException e) { } a.getGrading().setAutoRelease(Boolean.TRUE); a.getGrading().setGradebookIntegration(Boolean.FALSE); a.getGrading().setAnonymous(Boolean.TRUE); a.getPresentation().setText("This is assessment two."); a.getReview().setShowCorrectAnswer(ReviewShowCorrect.yes); a.getReview().setShowFeedback(Boolean.TRUE); a.getReview().setShowSummary(Boolean.FALSE); a.getReview().setTiming(ReviewTiming.submitted); a.setMinScoreSet(Boolean.FALSE); a.getSubmitPresentation().setText("Have a nice day!"); Part p2 = a.getParts().addPart(); p2.addDrawDetail(this.poolService.getPool("b1"), 2); p2.setTitle("Part one"); ((PartImpl) p2).initId("p3"); p2.getPresentation().setText("This is part one."); a.clearChanged(); a.clearMint(); ((AssessmentGradingImpl) (a.getGrading())).initAutoRelease(a.getGrading().getAutoRelease()); ((AssessmentGradingImpl) (a.getGrading())) .initGradebookIntegration(a.getGrading().getGradebookIntegration()); a.initTitle(a.getTitle()); a.initPublished(a.getPublished()); this.assessments.put(a.getId(), a); // a = newAssessment(); a.setType(AssessmentType.test); a.initId("a3"); a.setPublished(Boolean.TRUE); a.setContext("mercury"); a.getCreatedBy().setUserId("admin"); a.setTries(5); a.setQuestionGrouping(QuestionGrouping.question); a.setRandomAccess(Boolean.TRUE); // a.setTimeLimit(1200l * 1000l); a.setTitle("Detroit"); // a.getAccess().setPassword("password"); a.getCreatedBy().setUserId("admin"); a.getCreatedBy().setDate(now); a.getModifiedBy().setUserId("admin"); a.getModifiedBy().setDate(now); a.getGrading().setAutoRelease(Boolean.TRUE); a.getGrading().setGradebookIntegration(Boolean.FALSE); a.getGrading().setAnonymous(Boolean.TRUE); a.getPresentation().setText("This is assessment three."); a.getReview().setShowCorrectAnswer(ReviewShowCorrect.yes); a.getReview().setShowFeedback(Boolean.TRUE); a.getReview().setShowSummary(Boolean.FALSE); a.getReview().setTiming(ReviewTiming.submitted); a.setMinScoreSet(Boolean.FALSE); a.getSubmitPresentation().setText("Have a nice day!"); p = a.getParts().addPart(); p.addPickDetail(this.questionService.getQuestion("q3")); p.addPickDetail(this.questionService.getQuestion("q4")); p.setTitle("Part one"); ((PartImpl) p).initId("p4"); p.getPresentation().setText("This is part 1."); a.clearChanged(); a.clearMint(); ((AssessmentGradingImpl) (a.getGrading())).initAutoRelease(a.getGrading().getAutoRelease()); ((AssessmentGradingImpl) (a.getGrading())) .initGradebookIntegration(a.getGrading().getGradebookIntegration()); a.initTitle(a.getTitle()); a.initPublished(a.getPublished()); this.assessments.put(a.getId(), a); } } }