0001: /**********************************************************************************
0002: * $URL: https://source.sakaiproject.org/svn/assignment/tags/sakai_2-4-1/assignment-impl/impl/src/java/org/sakaiproject/assignment/impl/BaseAssignmentService.java $
0003: * $Id: BaseAssignmentService.java 19645 2006-12-18 14:23:57Z lance@indiana.edu $
0004: ***********************************************************************************
0005: *
0006: * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
0007: *
0008: * Licensed under the Educational Community License, Version 1.0 (the "License");
0009: * you may not use this file except in compliance with the License.
0010: * You may obtain a copy of the License at
0011: *
0012: * http://www.opensource.org/licenses/ecl1.php
0013: *
0014: * Unless required by applicable law or agreed to in writing, software
0015: * distributed under the License is distributed on an "AS IS" BASIS,
0016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017: * See the License for the specific language governing permissions and
0018: * limitations under the License.
0019: *
0020: **********************************************************************************/package org.sakaiproject.assignment.impl;
0021:
0022: import java.io.BufferedInputStream;
0023: import java.io.InputStream;
0024: import java.io.IOException;
0025: import java.io.OutputStream;
0026: import java.util.Collection;
0027: import java.util.Comparator;
0028: import java.util.Hashtable;
0029: import java.util.Iterator;
0030: import java.util.List;
0031: import java.util.Map;
0032: import java.util.Set;
0033: import java.util.Stack;
0034: import java.util.Vector;
0035: import java.util.zip.ZipEntry;
0036: import java.util.zip.ZipOutputStream;
0037:
0038: import javax.servlet.http.HttpServletRequest;
0039: import javax.servlet.http.HttpServletResponse;
0040:
0041: import org.apache.commons.logging.Log;
0042: import org.apache.commons.logging.LogFactory;
0043: import org.apache.poi.hssf.usermodel.HSSFCell;
0044: import org.apache.poi.hssf.usermodel.HSSFCellStyle;
0045: import org.apache.poi.hssf.usermodel.HSSFFont;
0046: import org.apache.poi.hssf.usermodel.HSSFRow;
0047: import org.apache.poi.hssf.usermodel.HSSFSheet;
0048: import org.apache.poi.hssf.usermodel.HSSFWorkbook;
0049: import org.sakaiproject.assignment.api.Assignment;
0050: import org.sakaiproject.assignment.api.AssignmentContent;
0051: import org.sakaiproject.assignment.api.AssignmentContentEdit;
0052: import org.sakaiproject.assignment.api.AssignmentContentNotEmptyException;
0053: import org.sakaiproject.assignment.api.AssignmentEdit;
0054: import org.sakaiproject.assignment.api.AssignmentService;
0055: import org.sakaiproject.assignment.api.AssignmentSubmission;
0056: import org.sakaiproject.assignment.api.AssignmentSubmissionEdit;
0057: import org.sakaiproject.authz.api.AuthzGroup;
0058: import org.sakaiproject.authz.api.AuthzPermissionException;
0059: import org.sakaiproject.authz.api.GroupNotDefinedException;
0060: import org.sakaiproject.authz.cover.AuthzGroupService;
0061: import org.sakaiproject.authz.cover.FunctionManager;
0062: import org.sakaiproject.authz.cover.SecurityService;
0063: import org.sakaiproject.component.api.ServerConfigurationService;
0064: import org.sakaiproject.content.api.ContentResource;
0065: import org.sakaiproject.content.api.ContentResourceEdit;
0066: import org.sakaiproject.content.cover.ContentHostingService;
0067: import org.sakaiproject.entity.api.AttachmentContainer;
0068: import org.sakaiproject.entity.api.Edit;
0069: import org.sakaiproject.entity.api.Entity;
0070: import org.sakaiproject.entity.api.EntityAccessOverloadException;
0071: import org.sakaiproject.entity.api.EntityCopyrightException;
0072: import org.sakaiproject.entity.api.EntityManager;
0073: import org.sakaiproject.entity.api.EntityNotDefinedException;
0074: import org.sakaiproject.entity.api.EntityPermissionException;
0075: import org.sakaiproject.entity.api.EntityPropertyNotDefinedException;
0076: import org.sakaiproject.entity.api.EntityPropertyTypeException;
0077: import org.sakaiproject.entity.api.EntityTransferrer;
0078: import org.sakaiproject.entity.api.HttpAccess;
0079: import org.sakaiproject.entity.api.Reference;
0080: import org.sakaiproject.entity.api.ResourceProperties;
0081: import org.sakaiproject.entity.api.ResourcePropertiesEdit;
0082: import org.sakaiproject.event.api.Event;
0083: import org.sakaiproject.event.api.SessionState;
0084: import org.sakaiproject.event.api.UsageSession;
0085: import org.sakaiproject.event.cover.EventTrackingService;
0086: import org.sakaiproject.event.cover.NotificationService;
0087: import org.sakaiproject.event.cover.UsageSessionService;
0088: import org.sakaiproject.exception.IdInvalidException;
0089: import org.sakaiproject.exception.IdUnusedException;
0090: import org.sakaiproject.exception.IdUsedException;
0091: import org.sakaiproject.exception.InUseException;
0092: import org.sakaiproject.exception.PermissionException;
0093: import org.sakaiproject.exception.ServerOverloadException;
0094: import org.sakaiproject.exception.TypeException;
0095: import org.sakaiproject.id.cover.IdManager;
0096: import org.sakaiproject.memory.api.Cache;
0097: import org.sakaiproject.memory.api.CacheRefresher;
0098: import org.sakaiproject.memory.api.MemoryService;
0099: import org.sakaiproject.site.api.Group;
0100: import org.sakaiproject.site.api.Site;
0101: import org.sakaiproject.site.cover.SiteService;
0102: import org.sakaiproject.time.api.Time;
0103: import org.sakaiproject.time.cover.TimeService;
0104: import org.sakaiproject.tool.api.SessionBindingEvent;
0105: import org.sakaiproject.tool.api.SessionBindingListener;
0106: import org.sakaiproject.tool.cover.SessionManager;
0107: import org.sakaiproject.tool.cover.ToolManager;
0108: import org.sakaiproject.user.api.User;
0109: import org.sakaiproject.user.cover.UserDirectoryService;
0110: import org.sakaiproject.util.BaseResourcePropertiesEdit;
0111: import org.sakaiproject.util.Blob;
0112: import org.sakaiproject.util.EmptyIterator;
0113: import org.sakaiproject.util.EntityCollections;
0114: import org.sakaiproject.util.FormattedText;
0115: import org.sakaiproject.util.ResourceLoader;
0116: import org.sakaiproject.util.SortedIterator;
0117: import org.sakaiproject.util.StorageUser;
0118: import org.sakaiproject.util.StringUtil;
0119: import org.sakaiproject.util.Validator;
0120: import org.sakaiproject.util.Xml;
0121: import org.w3c.dom.Document;
0122: import org.w3c.dom.Element;
0123: import org.w3c.dom.Node;
0124: import org.w3c.dom.NodeList;
0125:
0126: /**
0127: * <p>
0128: * BaseAssignmentService is the abstract service class for Assignments.
0129: * </p>
0130: * <p>
0131: * The Concrete Service classes extending this are the XmlFile and DbCached storage classes.
0132: * </p>
0133: */
0134: public abstract class BaseAssignmentService implements
0135: AssignmentService, EntityTransferrer {
0136: /** Our logger. */
0137: private static Log M_log = LogFactory
0138: .getLog(BaseAssignmentService.class);
0139:
0140: /** the resource bundle */
0141: private static ResourceLoader rb = new ResourceLoader("assignment");
0142:
0143: /** A Storage object for persistent storage of Assignments. */
0144: protected AssignmentStorage m_assignmentStorage = null;
0145:
0146: /** A Storage object for persistent storage of Assignments. */
0147: protected AssignmentContentStorage m_contentStorage = null;
0148:
0149: /** A Storage object for persistent storage of Assignments. */
0150: protected AssignmentSubmissionStorage m_submissionStorage = null;
0151:
0152: /** A Cache for this service - Assignments keyed by reference. */
0153: protected Cache m_assignmentCache = null;
0154:
0155: /** A Cache for this service - AssignmentContents keyed by reference. */
0156: protected Cache m_contentCache = null;
0157:
0158: /** A Cache for this service - AssignmentSubmissions keyed by reference. */
0159: protected Cache m_submissionCache = null;
0160:
0161: /** The access point URL. */
0162: protected String m_relativeAccessPoint = null;
0163:
0164: /**********************************************************************************************************************************************************************************************************************************************************
0165: * EVENT STRINGS
0166: *********************************************************************************************************************************************************************************************************************************************************/
0167:
0168: /** Event for adding an assignment. */
0169: public static final String EVENT_ADD_ASSIGNMENT = "asn.new.assignment";
0170:
0171: /** Event for adding an assignment. */
0172: public static final String EVENT_ADD_ASSIGNMENT_CONTENT = "asn.new.assignmentcontent";
0173:
0174: /** Event for adding an assignment submission. */
0175: public static final String EVENT_ADD_ASSIGNMENT_SUBMISSION = "asn.new.submission";
0176:
0177: /** Event for removing an assignment. */
0178: public static final String EVENT_REMOVE_ASSIGNMENT = "asn.delete.assignment";
0179:
0180: /** Event for removing an assignment content. */
0181: public static final String EVENT_REMOVE_ASSIGNMENT_CONTENT = "asn.delete.assignmentcontent";
0182:
0183: /** Event for removing an assignment submission. */
0184: public static final String EVENT_REMOVE_ASSIGNMENT_SUBMISSION = "asn.delete.submission";
0185:
0186: /** Event for accessing an assignment. */
0187: public static final String EVENT_ACCESS_ASSIGNMENT = "asn.read.assignment";
0188:
0189: /** Event for accessing an assignment content. */
0190: public static final String EVENT_ACCESS_ASSIGNMENT_CONTENT = "asn.read.assignmentcontent";
0191:
0192: /** Event for accessing an assignment submission. */
0193: public static final String EVENT_ACCESS_ASSIGNMENT_SUBMISSION = "asn.read.submission";
0194:
0195: /** Event for updating an assignment. */
0196: public static final String EVENT_UPDATE_ASSIGNMENT = "asn.revise.assignment";
0197:
0198: /** Event for updating an assignment content. */
0199: public static final String EVENT_UPDATE_ASSIGNMENT_CONTENT = "asn.revise.assignmentcontent";
0200:
0201: /** Event for updating an assignment submission. */
0202: public static final String EVENT_UPDATE_ASSIGNMENT_SUBMISSION = "asn.revise.submission";
0203:
0204: /** Event for saving an assignment submission. */
0205: public static final String EVENT_SAVE_ASSIGNMENT_SUBMISSION = "asn.save.submission";
0206:
0207: /** Event for submitting an assignment submission. */
0208: public static final String EVENT_SUBMIT_ASSIGNMENT_SUBMISSION = "asn.submit.submission";
0209:
0210: /** Event for grading an assignment submission. */
0211: public static final String EVENT_GRADE_ASSIGNMENT_SUBMISSION = "asn.grade.submission";
0212:
0213: /**********************************************************************************************************************************************************************************************************************************************************
0214: * Abstractions, etc.
0215: *********************************************************************************************************************************************************************************************************************************************************/
0216:
0217: /**
0218: * Construct a Storage object for Assignments.
0219: *
0220: * @return The new storage object.
0221: */
0222: protected abstract AssignmentStorage newAssignmentStorage();
0223:
0224: /**
0225: * Construct a Storage object for AssignmentContents.
0226: *
0227: * @return The new storage object.
0228: */
0229: protected abstract AssignmentContentStorage newContentStorage();
0230:
0231: /**
0232: * Construct a Storage object for AssignmentSubmissions.
0233: *
0234: * @return The new storage object.
0235: */
0236: protected abstract AssignmentSubmissionStorage newSubmissionStorage();
0237:
0238: /**
0239: * Access the partial URL that forms the root of resource URLs.
0240: *
0241: * @param relative -
0242: * if true, form within the access path only (i.e. starting with /msg)
0243: * @return the partial URL that forms the root of resource URLs.
0244: */
0245: protected String getAccessPoint(boolean relative) {
0246: return (relative ? "" : m_serverConfigurationService
0247: .getAccessUrl())
0248: + m_relativeAccessPoint;
0249:
0250: } // getAccessPoint
0251:
0252: /**
0253: * Access the internal reference which can be used to assess security clearance.
0254: *
0255: * @param id
0256: * The assignment id string.
0257: * @return The the internal reference which can be used to access the resource from within the system.
0258: */
0259: public String assignmentReference(String context, String id) {
0260: String retVal = null;
0261: if (context == null)
0262: retVal = getAccessPoint(true) + Entity.SEPARATOR + "a"
0263: + Entity.SEPARATOR + id;
0264: else
0265: retVal = getAccessPoint(true) + Entity.SEPARATOR + "a"
0266: + Entity.SEPARATOR + context + Entity.SEPARATOR
0267: + id;
0268: return retVal;
0269:
0270: } // assignmentReference
0271:
0272: /**
0273: * Access the internal reference which can be used to access the resource from within the system.
0274: *
0275: * @param id
0276: * The content id string.
0277: * @return The the internal reference which can be used to access the resource from within the system.
0278: */
0279: public String contentReference(String context, String id) {
0280: String retVal = null;
0281: if (context == null)
0282: retVal = getAccessPoint(true) + Entity.SEPARATOR + "c"
0283: + Entity.SEPARATOR + id;
0284: else
0285: retVal = getAccessPoint(true) + Entity.SEPARATOR + "c"
0286: + Entity.SEPARATOR + context + Entity.SEPARATOR
0287: + id;
0288: return retVal;
0289:
0290: } // contentReference
0291:
0292: /**
0293: * Access the internal reference which can be used to access the resource from within the system.
0294: *
0295: * @param id
0296: * The submission id string.
0297: * @return The the internal reference which can be used to access the resource from within the system.
0298: */
0299: public String submissionReference(String context, String id,
0300: String assignmentId) {
0301: String retVal = null;
0302: if (context == null)
0303: retVal = getAccessPoint(true) + Entity.SEPARATOR + "s"
0304: + Entity.SEPARATOR + id;
0305: else
0306: retVal = getAccessPoint(true) + Entity.SEPARATOR + "s"
0307: + Entity.SEPARATOR + context + Entity.SEPARATOR
0308: + assignmentId + Entity.SEPARATOR + id;
0309: return retVal;
0310:
0311: } // submissionReference
0312:
0313: /**
0314: * Access the assignment id extracted from an assignment reference.
0315: *
0316: * @param ref
0317: * The assignment reference string.
0318: * @return The the assignment id extracted from an assignment reference.
0319: */
0320: protected String assignmentId(String ref) {
0321: int i = ref.lastIndexOf(Entity.SEPARATOR);
0322: if (i == -1)
0323: return ref;
0324: String id = ref.substring(i + 1);
0325: return id;
0326:
0327: } // assignmentId
0328:
0329: /**
0330: * Access the content id extracted from a content reference.
0331: *
0332: * @param ref
0333: * The content reference string.
0334: * @return The the content id extracted from a content reference.
0335: */
0336: protected String contentId(String ref) {
0337: int i = ref.lastIndexOf(Entity.SEPARATOR);
0338: if (i == -1)
0339: return ref;
0340: String id = ref.substring(i + 1);
0341: return id;
0342:
0343: } // contentId
0344:
0345: /**
0346: * Access the submission id extracted from a submission reference.
0347: *
0348: * @param ref
0349: * The submission reference string.
0350: * @return The the submission id extracted from a submission reference.
0351: */
0352: protected String submissionId(String ref) {
0353: int i = ref.lastIndexOf(Entity.SEPARATOR);
0354: if (i == -1)
0355: return ref;
0356: String id = ref.substring(i + 1);
0357: return id;
0358:
0359: } // submissionId
0360:
0361: /**
0362: * Check security permission.
0363: *
0364: * @param lock -
0365: * The lock id string.
0366: * @param resource -
0367: * The resource reference string, or null if no resource is involved.
0368: * @return true if allowed, false if not
0369: */
0370: protected boolean unlockCheck(String lock, String resource) {
0371: if (!SecurityService.unlock(lock, resource)) {
0372: return false;
0373: }
0374:
0375: return true;
0376:
0377: }// unlockCheck
0378:
0379: /**
0380: * Check security permission.
0381: *
0382: * @param lock1
0383: * The lock id string.
0384: * @param lock2
0385: * The lock id string.
0386: * @param resource
0387: * The resource reference string, or null if no resource is involved.
0388: * @return true if either allowed, false if not
0389: */
0390: protected boolean unlockCheck2(String lock1, String lock2,
0391: String resource) {
0392: // check the first lock
0393: if (SecurityService.unlock(lock1, resource))
0394: return true;
0395:
0396: // if the second is different, check that
0397: if ((lock1 != lock2)
0398: && (SecurityService.unlock(lock2, resource)))
0399: return true;
0400:
0401: return false;
0402:
0403: } // unlockCheck2
0404:
0405: /**
0406: * Check security permission.
0407: *
0408: * @param lock -
0409: * The lock id string.
0410: * @param resource -
0411: * The resource reference string, or null if no resource is involved.
0412: * @exception PermissionException
0413: * Thrown if the user does not have access
0414: */
0415: protected void unlock(String lock, String resource)
0416: throws PermissionException {
0417: if (!unlockCheck(lock, resource)) {
0418: throw new PermissionException(SessionManager
0419: .getCurrentSessionUserId(), lock, resource);
0420: }
0421:
0422: } // unlock
0423:
0424: /**
0425: * Check security permission.
0426: *
0427: * @param lock1
0428: * The lock id string.
0429: * @param lock2
0430: * The lock id string.
0431: * @param resource
0432: * The resource reference string, or null if no resource is involved.
0433: * @exception PermissionException
0434: * Thrown if the user does not have access to either.
0435: */
0436: protected void unlock2(String lock1, String lock2, String resource)
0437: throws PermissionException {
0438: if (!unlockCheck2(lock1, lock2, resource)) {
0439: throw new PermissionException(SessionManager
0440: .getCurrentSessionUserId(), lock1 + "/" + lock2,
0441: resource);
0442: }
0443:
0444: } // unlock2
0445:
0446: /**********************************************************************************************************************************************************************************************************************************************************
0447: * Dependencies and their setter methods
0448: *********************************************************************************************************************************************************************************************************************************************************/
0449:
0450: /** Dependency: MemoryService. */
0451: protected MemoryService m_memoryService = null;
0452:
0453: /**
0454: * Dependency: MemoryService.
0455: *
0456: * @param service
0457: * The MemoryService.
0458: */
0459: public void setMemoryService(MemoryService service) {
0460: m_memoryService = service;
0461: }
0462:
0463: /** Configuration: cache, or not. */
0464: protected boolean m_caching = false;
0465:
0466: /**
0467: * Configuration: set the locks-in-db
0468: *
0469: * @param path
0470: * The storage path.
0471: */
0472: public void setCaching(String value) {
0473: m_caching = new Boolean(value).booleanValue();
0474: }
0475:
0476: /** Dependency: EntityManager. */
0477: protected EntityManager m_entityManager = null;
0478:
0479: /**
0480: * Dependency: EntityManager.
0481: *
0482: * @param service
0483: * The EntityManager.
0484: */
0485: public void setEntityManager(EntityManager service) {
0486: m_entityManager = service;
0487: }
0488:
0489: /** Dependency: ServerConfigurationService. */
0490: protected ServerConfigurationService m_serverConfigurationService = null;
0491:
0492: /**
0493: * Dependency: ServerConfigurationService.
0494: *
0495: * @param service
0496: * The ServerConfigurationService.
0497: */
0498: public void setServerConfigurationService(
0499: ServerConfigurationService service) {
0500: m_serverConfigurationService = service;
0501: }
0502:
0503: /** Dependency: allowGroupAssignments setting */
0504: protected boolean m_allowGroupAssignments = true;
0505:
0506: /**
0507: * Dependency: allowGroupAssignments
0508: *
0509: * @param allowGroupAssignments
0510: * the setting
0511: */
0512: public void setAllowGroupAssignments(boolean allowGroupAssignments) {
0513: m_allowGroupAssignments = allowGroupAssignments;
0514: }
0515:
0516: /**
0517: * Get
0518: *
0519: * @return allowGroupAssignments
0520: */
0521: public boolean getAllowGroupAssignments() {
0522: return m_allowGroupAssignments;
0523: }
0524:
0525: /** Dependency: allowGroupAssignmentsInGradebook setting */
0526: protected boolean m_allowGroupAssignmentsInGradebook = true;
0527:
0528: /**
0529: * Dependency: allowGroupAssignmentsInGradebook
0530: *
0531: * @param allowGroupAssignmentsInGradebook
0532: */
0533: public void setAllowGroupAssignmentsInGradebook(
0534: boolean allowGroupAssignmentsInGradebook) {
0535: m_allowGroupAssignmentsInGradebook = allowGroupAssignmentsInGradebook;
0536: }
0537:
0538: /**
0539: * Get
0540: *
0541: * @return allowGroupAssignmentsGradebook
0542: */
0543: public boolean getAllowGroupAssignmentsInGradebook() {
0544: return m_allowGroupAssignmentsInGradebook;
0545: }
0546:
0547: /**********************************************************************************************************************************************************************************************************************************************************
0548: * Init and Destroy
0549: *********************************************************************************************************************************************************************************************************************************************************/
0550:
0551: /**
0552: * Final initialization, once all dependencies are set.
0553: */
0554: public void init() {
0555: m_relativeAccessPoint = REFERENCE_ROOT;
0556: M_log.info("init()");
0557:
0558: // construct storage helpers and read
0559: m_assignmentStorage = newAssignmentStorage();
0560: m_assignmentStorage.open();
0561: m_contentStorage = newContentStorage();
0562: m_contentStorage.open();
0563: m_submissionStorage = newSubmissionStorage();
0564: m_submissionStorage.open();
0565:
0566: // make the cache
0567: if (m_caching) {
0568: m_assignmentCache = m_memoryService.newCache(
0569: new AssignmentCacheRefresher(),
0570: assignmentReference(null, ""));
0571: m_contentCache = m_memoryService.newCache(
0572: new AssignmentContentCacheRefresher(),
0573: contentReference(null, ""));
0574: m_submissionCache = m_memoryService.newCache(
0575: new AssignmentSubmissionCacheRefresher(),
0576: submissionReference(null, "", ""));
0577: }
0578:
0579: // register as an entity producer
0580: m_entityManager.registerEntityProducer(this , REFERENCE_ROOT);
0581:
0582: // register functions
0583: FunctionManager.registerFunction(SECURE_ALL_GROUPS);
0584: FunctionManager.registerFunction(SECURE_ADD_ASSIGNMENT);
0585: FunctionManager
0586: .registerFunction(SECURE_ADD_ASSIGNMENT_SUBMISSION);
0587: FunctionManager.registerFunction(SECURE_REMOVE_ASSIGNMENT);
0588: FunctionManager.registerFunction(SECURE_ACCESS_ASSIGNMENT);
0589: FunctionManager.registerFunction(SECURE_UPDATE_ASSIGNMENT);
0590: FunctionManager
0591: .registerFunction(SECURE_GRADE_ASSIGNMENT_SUBMISSION);
0592:
0593: } // init
0594:
0595: /**
0596: * Returns to uninitialized state.
0597: */
0598: public void destroy() {
0599: if (m_caching) {
0600: if (m_assignmentCache != null) {
0601: m_assignmentCache.destroy();
0602: m_assignmentCache = null;
0603: }
0604: if (m_contentCache != null) {
0605: m_contentCache.destroy();
0606: m_contentCache = null;
0607: }
0608: if (m_submissionCache != null) {
0609: m_submissionCache.destroy();
0610: m_submissionCache = null;
0611: }
0612: }
0613:
0614: m_assignmentStorage.close();
0615: m_assignmentStorage = null;
0616: m_contentStorage.close();
0617: m_contentStorage = null;
0618: m_submissionStorage.close();
0619: m_submissionStorage = null;
0620:
0621: M_log.info("destroy()");
0622: }
0623:
0624: /**********************************************************************************************************************************************************************************************************************************************************
0625: * AssignmentService implementation
0626: *********************************************************************************************************************************************************************************************************************************************************/
0627:
0628: /**
0629: * Creates and adds a new Assignment to the service.
0630: *
0631: * @param context -
0632: * Describes the portlet context - generated with DefaultId.getChannel().
0633: * @return The new Assignment object.
0634: * @throws IdInvalidException
0635: * if the id contains prohibited characers.
0636: * @throws IdUsedException
0637: * if the id is already used in the service.
0638: * @throws PermissionException
0639: * if current User does not have permission to do this.
0640: */
0641: public AssignmentEdit addAssignment(String context)
0642: throws PermissionException {
0643: if (M_log.isDebugEnabled())
0644: M_log
0645: .debug("ASSIGNMENT : BASE SERVICE : ENTERING ADD ASSIGNMENT : CONTEXT : "
0646: + context);
0647:
0648: String assignmentId = null;
0649: boolean badId = false;
0650:
0651: do {
0652: badId = !Validator.checkResourceId(assignmentId);
0653: assignmentId = IdManager.createUuid();
0654:
0655: if (m_assignmentStorage.check(assignmentId))
0656: badId = true;
0657: } while (badId);
0658:
0659: String key = assignmentReference(context, assignmentId);
0660:
0661: unlock(SECURE_ADD_ASSIGNMENT, key);
0662:
0663: // storage
0664: AssignmentEdit assignment = m_assignmentStorage.put(
0665: assignmentId, context);
0666:
0667: // event for tracking
0668: ((BaseAssignmentEdit) assignment)
0669: .setEvent(EVENT_ADD_ASSIGNMENT);
0670:
0671: if (M_log.isDebugEnabled())
0672: M_log
0673: .debug("ASSIGNMENT : BASE SERVICE : LEAVING ADD ASSIGNMENT WITH : ID : "
0674: + assignment.getId());
0675:
0676: return assignment;
0677:
0678: } // addAssignment
0679:
0680: /**
0681: * Add a new assignment to the directory, from a definition in XML. Must commitEdit() to make official, or cancelEdit() when done!
0682: *
0683: * @param el
0684: * The XML DOM Element defining the assignment.
0685: * @return A locked AssignmentEdit object (reserving the id).
0686: * @exception IdInvalidException
0687: * if the assignment id is invalid.
0688: * @exception IdUsedException
0689: * if the assignment id is already used.
0690: * @exception PermissionException
0691: * if the current user does not have permission to add an assignnment.
0692: */
0693: public AssignmentEdit mergeAssignment(Element el)
0694: throws IdInvalidException, IdUsedException,
0695: PermissionException {
0696: // construct from the XML
0697: Assignment assignmentFromXml = new BaseAssignment(el);
0698:
0699: // check for a valid assignment name
0700: if (!Validator.checkResourceId(assignmentFromXml.getId()))
0701: throw new IdInvalidException(assignmentFromXml.getId());
0702:
0703: // check security (throws if not permitted)
0704: unlock(SECURE_ADD_ASSIGNMENT, assignmentFromXml.getReference());
0705:
0706: // reserve a assignment with this id from the info store - if it's in use, this will return null
0707: AssignmentEdit assignment = m_assignmentStorage.put(
0708: assignmentFromXml.getId(), assignmentFromXml
0709: .getContext());
0710: if (assignment == null) {
0711: throw new IdUsedException(assignmentFromXml.getId());
0712: }
0713:
0714: // transfer from the XML read assignment object to the AssignmentEdit
0715: ((BaseAssignmentEdit) assignment).set(assignmentFromXml);
0716:
0717: ((BaseAssignmentEdit) assignment)
0718: .setEvent(EVENT_ADD_ASSIGNMENT);
0719:
0720: ResourcePropertiesEdit propertyEdit = (BaseResourcePropertiesEdit) assignment
0721: .getProperties();
0722: try {
0723: Time createTime = propertyEdit
0724: .getTimeProperty(ResourceProperties.PROP_CREATION_DATE);
0725: } catch (EntityPropertyNotDefinedException epnde) {
0726: String now = TimeService.newTime().toString();
0727: propertyEdit.addProperty(
0728: ResourceProperties.PROP_CREATION_DATE, now);
0729: } catch (EntityPropertyTypeException epte) {
0730: M_log.error(epte);
0731: }
0732:
0733: return assignment;
0734: }
0735:
0736: /**
0737: * Creates and adds a new Assignment to the service which is a copy of an existing Assignment.
0738: *
0739: * @param assignmentId -
0740: * The Assignment to be duplicated.
0741: * @return The new Assignment object, or null if the original Assignment does not exist.
0742: * @throws PermissionException
0743: * if current User does not have permission to do this.
0744: */
0745: public AssignmentEdit addDuplicateAssignment(String context,
0746: String assignmentReference) throws PermissionException,
0747: IdInvalidException, IdUsedException, IdUnusedException {
0748: if (M_log.isDebugEnabled())
0749: M_log
0750: .debug("ASSIGNMENT : BASE SERVICE : ENTERING ADD DUPLICATE ASSIGNMENT WITH ID : "
0751: + assignmentReference);
0752:
0753: AssignmentEdit retVal = null;
0754: AssignmentContentEdit newContent = null;
0755:
0756: if (assignmentReference != null) {
0757: String assignmentId = assignmentId(assignmentReference);
0758: if (!m_assignmentStorage.check(assignmentId))
0759: throw new IdUnusedException(assignmentId);
0760: else {
0761: if (M_log.isDebugEnabled())
0762: M_log
0763: .debug("ASSIGNMENT : BASE SERVICE : addDuplicateAssignment : assignment exists - will copy");
0764:
0765: Assignment existingAssignment = getAssignment(assignmentReference);
0766: newContent = addDuplicateAssignmentContent(context,
0767: existingAssignment.getContentReference());
0768: commitEdit(newContent);
0769:
0770: retVal = addAssignment(context);
0771: retVal.setContentReference(newContent.getReference());
0772: retVal.setTitle(existingAssignment.getTitle()
0773: + " - Copy");
0774: retVal.setSection(existingAssignment.getSection());
0775: retVal.setOpenTime(existingAssignment.getOpenTime());
0776: retVal.setDueTime(existingAssignment.getDueTime());
0777: retVal.setDropDeadTime(existingAssignment
0778: .getDropDeadTime());
0779: retVal.setCloseTime(existingAssignment.getCloseTime());
0780: retVal.setDraft(true);
0781: ResourcePropertiesEdit pEdit = (BaseResourcePropertiesEdit) retVal
0782: .getProperties();
0783: pEdit.addAll(existingAssignment.getProperties());
0784: addLiveProperties(pEdit);
0785: }
0786: }
0787:
0788: if (M_log.isDebugEnabled())
0789: M_log
0790: .debug("ASSIGNMENT : BASE SERVICE : ADD DUPLICATE ASSIGNMENT : LEAVING ADD DUPLICATE ASSIGNMENT WITH ID : "
0791: + retVal.getId());
0792:
0793: return retVal;
0794: }
0795:
0796: /**
0797: * Access the Assignment with the specified reference.
0798: *
0799: * @param assignmentReference -
0800: * The reference of the Assignment.
0801: * @return The Assignment corresponding to the reference, or null if it does not exist.
0802: * @throws IdUnusedException
0803: * if there is no object with this reference.
0804: * @throws PermissionException
0805: * if the current user is not allowed to access this.
0806: */
0807: public Assignment getAssignment(String assignmentReference)
0808: throws IdUnusedException, PermissionException {
0809: if (M_log.isDebugEnabled())
0810: M_log
0811: .debug("ASSIGNMENT : BASE SERVICE : GET ASSIGNMENT : REF : "
0812: + assignmentReference);
0813:
0814: // check security on the assignment
0815: unlockCheck(SECURE_ACCESS_ASSIGNMENT, assignmentReference);
0816:
0817: Assignment assignment = findAssignment(assignmentReference);
0818:
0819: if (assignment == null)
0820: throw new IdUnusedException(assignmentReference);
0821:
0822: // track event
0823: // EventTrackingService.post(EventTrackingService.newEvent(EVENT_ACCESS_ASSIGNMENT, assignment.getReference(), false));
0824:
0825: return assignment;
0826:
0827: }// getAssignment
0828:
0829: protected Assignment findAssignment(String assignmentReference) {
0830: Assignment assignment = null;
0831:
0832: String assignmentId = assignmentId(assignmentReference);
0833:
0834: if ((m_caching) && (m_assignmentCache != null)
0835: && (!m_assignmentCache.disabled())) {
0836: // if we have it in the cache, use it
0837: if (m_assignmentCache.containsKey(assignmentReference))
0838: assignment = (Assignment) m_assignmentCache
0839: .get(assignmentReference);
0840: else {
0841: assignment = m_assignmentStorage.get(assignmentId);
0842:
0843: // cache the result
0844: m_assignmentCache.put(assignmentReference, assignment);
0845: }
0846: } else {
0847: assignment = m_assignmentStorage.get(assignmentId);
0848: }
0849:
0850: return assignment;
0851: }
0852:
0853: /**
0854: * Access all assignment objects - known to us (not from external providers).
0855: *
0856: * @return A list of assignment objects.
0857: */
0858: protected List getAssignments(String context) {
0859: List assignments = new Vector();
0860:
0861: if ((m_caching) && (m_assignmentCache != null)
0862: && (!m_assignmentCache.disabled())) {
0863: // if the cache is complete, use it
0864: if (m_assignmentCache.isComplete()) {
0865: assignments = m_assignmentCache.getAll();
0866: // TODO: filter by context
0867: }
0868:
0869: // otherwise get all the assignments from storage
0870: else {
0871: // Note: while we are getting from storage, storage might change. These can be processed
0872: // after we get the storage entries, and put them in the cache, and mark the cache complete.
0873: // -ggolden
0874: synchronized (m_assignmentCache) {
0875: // if we were waiting and it's now complete...
0876: if (m_assignmentCache.isComplete()) {
0877: assignments = m_assignmentCache.getAll();
0878: return assignments;
0879: }
0880:
0881: // save up any events to the cache until we get past this load
0882: m_assignmentCache.holdEvents();
0883:
0884: assignments = m_assignmentStorage.getAll(context);
0885:
0886: // update the cache, and mark it complete
0887: for (int i = 0; i < assignments.size(); i++) {
0888: Assignment assignment = (Assignment) assignments
0889: .get(i);
0890: m_assignmentCache.put(
0891: assignment.getReference(), assignment);
0892: }
0893:
0894: m_assignmentCache.setComplete();
0895: // TODO: not reall, just for context
0896:
0897: // now we are complete, process any cached events
0898: m_assignmentCache.processEvents();
0899: }
0900: }
0901: }
0902:
0903: else {
0904: // // if we have done this already in this thread, use that
0905: // assignments = (List) CurrentService.getInThread(context+".assignment.assignments");
0906: // if (assignments == null)
0907: // {
0908: assignments = m_assignmentStorage.getAll(context);
0909: //
0910: // // "cache" the assignments in the current service in case they are needed again in this thread...
0911: // if (assignments != null)
0912: // {
0913: // CurrentService.setInThread(context+".assignment.assignments", assignments);
0914: // }
0915: // }
0916: }
0917:
0918: List rv = new Vector();
0919:
0920: // check for the allowed groups of the current end use if we need it, and only once
0921: Collection allowedGroups = null;
0922: Site site = null;
0923: try {
0924: site = SiteService.getSite(context);
0925: } catch (IdUnusedException e) {
0926: M_log.warn(this + e.getMessage() + " context=" + context);
0927: }
0928:
0929: for (int x = 0; x < assignments.size(); x++) {
0930: Assignment tempAssignment = (Assignment) assignments.get(x);
0931: if (tempAssignment.getAccess() == Assignment.AssignmentAccess.GROUPED) {
0932:
0933: // Can at least one of the designated groups been found
0934: boolean groupFound = false;
0935:
0936: // if grouped, check that the end user has get access to any of this assignment's groups; reject if not
0937:
0938: // check the assignment's groups to the allowed (get) groups for the current user
0939: Collection asgGroups = tempAssignment.getGroups();
0940:
0941: for (Iterator iAsgGroups = asgGroups.iterator(); site != null
0942: && !groupFound && iAsgGroups.hasNext();) {
0943: String groupId = (String) iAsgGroups.next();
0944: try {
0945: if (site.getGroup(groupId) != null) {
0946: groupFound = true;
0947: }
0948: } catch (Exception ee) {
0949: M_log.warn(this + ee.getMessage() + groupId);
0950: }
0951:
0952: }
0953:
0954: if (!groupFound) {
0955: // if none of the group exists, mark the assignment as draft and list it
0956: String assignmentId = tempAssignment.getId();
0957: try {
0958: AssignmentEdit aEdit = editAssignment(assignmentReference(
0959: context, assignmentId));
0960: aEdit.setDraft(true);
0961: commitEdit(aEdit);
0962: rv.add(getAssignment(assignmentId));
0963: } catch (Exception e) {
0964: M_log.warn(this + e.getMessage()
0965: + " assignment id =" + assignmentId);
0966: continue;
0967: }
0968: } else {
0969: // we need the allowed groups, so get it if we have not done so yet
0970: if (allowedGroups == null) {
0971: allowedGroups = getGroupsAllowGetAssignment(context);
0972: }
0973:
0974: // reject if there is no intersection
0975: if (!isIntersectionGroupRefsToGroups(asgGroups,
0976: allowedGroups))
0977: continue;
0978:
0979: rv.add(tempAssignment);
0980: }
0981: } else {
0982: /// if not reject, add it
0983: rv.add(tempAssignment);
0984: }
0985: }
0986:
0987: return rv;
0988:
0989: } // getAssignments
0990:
0991: /**
0992: * See if the collection of group reference strings has at least one group that is in the collection of Group objects.
0993: *
0994: * @param groupRefs
0995: * The collection (String) of group references.
0996: * @param groups
0997: * The collection (Group) of group objects.
0998: * @return true if there is interesection, false if not.
0999: */
1000: protected boolean isIntersectionGroupRefsToGroups(
1001: Collection groupRefs, Collection groups) {
1002: for (Iterator iRefs = groupRefs.iterator(); iRefs.hasNext();) {
1003: String findThisGroupRef = (String) iRefs.next();
1004: for (Iterator iGroups = groups.iterator(); iGroups
1005: .hasNext();) {
1006: String this GroupRef = ((Group) iGroups.next())
1007: .getReference();
1008: if (this GroupRef.equals(findThisGroupRef)) {
1009: return true;
1010: }
1011: }
1012: }
1013:
1014: return false;
1015: }
1016:
1017: /**
1018: * Get a locked assignment object for editing. Must commitEdit() to make official, or cancelEdit() when done!
1019: *
1020: * @param id
1021: * The assignment id string.
1022: * @return An AssignmentEdit object for editing.
1023: * @exception IdUnusedException
1024: * if not found, or if not an AssignmentEdit object
1025: * @exception PermissionException
1026: * if the current user does not have permission to edit this assignment.
1027: * @exception InUseException
1028: * if the assignment is being edited by another user.
1029: */
1030: public AssignmentEdit editAssignment(String assignmentReference)
1031: throws IdUnusedException, PermissionException,
1032: InUseException {
1033: // check security (throws if not permitted)
1034: unlock(SECURE_UPDATE_ASSIGNMENT, assignmentReference);
1035:
1036: String assignmentId = assignmentId(assignmentReference);
1037:
1038: // check for existance
1039: if (!m_assignmentStorage.check(assignmentId)) {
1040: throw new IdUnusedException(assignmentId);
1041: }
1042:
1043: // ignore the cache - get the assignment with a lock from the info store
1044: AssignmentEdit assignmentEdit = m_assignmentStorage
1045: .edit(assignmentId);
1046: if (assignmentEdit == null)
1047: throw new InUseException(assignmentId);
1048:
1049: ((BaseAssignmentEdit) assignmentEdit)
1050: .setEvent(EVENT_UPDATE_ASSIGNMENT);
1051:
1052: return assignmentEdit;
1053:
1054: } // editAssignment
1055:
1056: /**
1057: * Commit the changes made to an AssignmentEdit object, and release the lock.
1058: *
1059: * @param assignment
1060: * The AssignmentEdit object to commit.
1061: */
1062: public void commitEdit(AssignmentEdit assignment) {
1063: // check for closed edit
1064: if (!assignment.isActiveEdit()) {
1065: try {
1066: throw new Exception();
1067: } catch (Exception e) {
1068: M_log.warn("commitEdit(): closed AssignmentEdit", e);
1069: }
1070: return;
1071: }
1072:
1073: // update the properties
1074: addLiveUpdateProperties(assignment.getPropertiesEdit());
1075:
1076: // complete the edit
1077: m_assignmentStorage.commit(assignment);
1078:
1079: // track it
1080: EventTrackingService.post(EventTrackingService.newEvent(
1081: ((BaseAssignmentEdit) assignment).getEvent(),
1082: assignment.getReference(), true));
1083:
1084: // close the edit object
1085: ((BaseAssignmentEdit) assignment).closeEdit();
1086:
1087: } // commitEdit
1088:
1089: /**
1090: * Cancel the changes made to a AssignmentEdit object, and release the lock.
1091: *
1092: * @param assignment
1093: * The AssignmentEdit object to commit.
1094: */
1095: public void cancelEdit(AssignmentEdit assignment) {
1096: // check for closed edit
1097: if (!assignment.isActiveEdit()) {
1098: try {
1099: throw new Exception();
1100: } catch (Exception e) {
1101: M_log.warn("cancelEdit(): closed AssignmentEdit", e);
1102: }
1103: return;
1104: }
1105:
1106: // release the edit lock
1107: m_assignmentStorage.cancel(assignment);
1108:
1109: // close the edit object
1110: ((BaseAssignmentEdit) assignment).closeEdit();
1111:
1112: } // cancelEdit(Assignment)
1113:
1114: /**
1115: * Removes this Assignment and all references to it.
1116: *
1117: * @param assignment -
1118: * The Assignment to remove.
1119: * @throws PermissionException
1120: * if current User does not have permission to do this.
1121: */
1122: public void removeAssignment(AssignmentEdit assignment)
1123: throws PermissionException {
1124: if (assignment != null) {
1125: if (M_log.isDebugEnabled())
1126: M_log
1127: .debug("BaseAssignmentService : removeAssignment with id : "
1128: + assignment.getId());
1129:
1130: if (!assignment.isActiveEdit()) {
1131: try {
1132: throw new Exception();
1133: } catch (Exception e) {
1134: M_log
1135: .warn(
1136: "removeAssignment(): closed AssignmentEdit",
1137: e);
1138: }
1139: return;
1140: }
1141:
1142: // CHECK PERMISSION
1143: unlock(SECURE_REMOVE_ASSIGNMENT, assignment.getReference());
1144:
1145: // complete the edit
1146: m_assignmentStorage.remove(assignment);
1147:
1148: // track event
1149: EventTrackingService.post(EventTrackingService.newEvent(
1150: EVENT_REMOVE_ASSIGNMENT, assignment.getReference(),
1151: true));
1152:
1153: // close the edit object
1154: ((BaseAssignmentEdit) assignment).closeEdit();
1155:
1156: // remove any realm defined for this resource
1157: try {
1158: AuthzGroupService.removeAuthzGroup(assignment
1159: .getReference());
1160: } catch (AuthzPermissionException e) {
1161: M_log.warn("removeAssignment: removing realm for : "
1162: + assignment.getReference() + " : " + e);
1163: }
1164: }
1165:
1166: }// removeAssignment
1167:
1168: /**
1169: * Creates and adds a new AssignmentContent to the service.
1170: *
1171: * @param context -
1172: * Describes the portlet context - generated with DefaultId.getChannel().
1173: * @return AssignmentContent The new AssignmentContent object.
1174: * @throws PermissionException
1175: * if current User does not have permission to do this.
1176: */
1177: public AssignmentContentEdit addAssignmentContent(String context)
1178: throws PermissionException {
1179: if (M_log.isDebugEnabled())
1180: M_log
1181: .debug("ASSIGNMENT : BASE SERVICE : ENTERING ADD ASSIGNMENT CONTENT");
1182:
1183: String contentId = null;
1184: boolean badId = false;
1185:
1186: do {
1187: badId = !Validator.checkResourceId(contentId);
1188: contentId = IdManager.createUuid();
1189:
1190: if (m_contentStorage.check(contentId))
1191: badId = true;
1192: } while (badId);
1193:
1194: unlock(SECURE_ADD_ASSIGNMENT_CONTENT, contentReference(context,
1195: contentId));
1196:
1197: AssignmentContentEdit content = m_contentStorage.put(contentId,
1198: context);
1199:
1200: if (M_log.isDebugEnabled())
1201: M_log
1202: .debug("ASSIGNMENT : BASE SERVICE : LEAVING ADD ASSIGNMENT CONTENT : ID : "
1203: + content.getId());
1204:
1205: // event for tracking
1206: ((BaseAssignmentContentEdit) content)
1207: .setEvent(EVENT_ADD_ASSIGNMENT_CONTENT);
1208:
1209: return content;
1210:
1211: }// addAssignmentContent
1212:
1213: /**
1214: * Add a new AssignmentContent to the directory, from a definition in XML. Must commitEdit() to make official, or cancelEdit() when done!
1215: *
1216: * @param el
1217: * The XML DOM Element defining the AssignmentContent.
1218: * @return A locked AssignmentContentEdit object (reserving the id).
1219: * @exception IdInvalidException
1220: * if the AssignmentContent id is invalid.
1221: * @exception IdUsedException
1222: * if the AssignmentContent id is already used.
1223: * @exception PermissionException
1224: * if the current user does not have permission to add an AssignnmentContent.
1225: */
1226: public AssignmentContentEdit mergeAssignmentContent(Element el)
1227: throws IdInvalidException, IdUsedException,
1228: PermissionException {
1229: // construct from the XML
1230: AssignmentContent contentFromXml = new BaseAssignmentContent(el);
1231:
1232: // check for a valid assignment name
1233: if (!Validator.checkResourceId(contentFromXml.getId()))
1234: throw new IdInvalidException(contentFromXml.getId());
1235:
1236: // check security (throws if not permitted)
1237: unlock(SECURE_ADD_ASSIGNMENT_CONTENT, contentFromXml
1238: .getReference());
1239:
1240: // reserve a content with this id from the info store - if it's in use, this will return null
1241: AssignmentContentEdit content = m_contentStorage.put(
1242: contentFromXml.getId(), contentFromXml.getContext());
1243: if (content == null) {
1244: throw new IdUsedException(contentFromXml.getId());
1245: }
1246:
1247: // transfer from the XML read content object to the AssignmentContentEdit
1248: ((BaseAssignmentContentEdit) content).set(contentFromXml);
1249:
1250: ((BaseAssignmentContentEdit) content)
1251: .setEvent(EVENT_ADD_ASSIGNMENT_CONTENT);
1252:
1253: return content;
1254: }
1255:
1256: /**
1257: * Creates and adds a new AssignmentContent to the service which is a copy of an existing AssignmentContent.
1258: *
1259: * @param context -
1260: * From DefaultId.getChannel(RunData)
1261: * @param contentReference -
1262: * The id of the AssignmentContent to be duplicated.
1263: * @return AssignmentContentEdit The new AssignmentContentEdit object, or null if the original does not exist.
1264: * @throws PermissionException
1265: * if current User does not have permission to do this.
1266: */
1267: public AssignmentContentEdit addDuplicateAssignmentContent(
1268: String context, String contentReference)
1269: throws PermissionException, IdInvalidException,
1270: IdUnusedException {
1271: if (M_log.isDebugEnabled())
1272: M_log
1273: .debug("ASSIGNMENT : BASE SERVICE : ENTERING ADD DUPLICATE ASSIGNMENT CONTENT : "
1274: + contentReference);
1275:
1276: AssignmentContentEdit retVal = null;
1277: AssignmentContent existingContent = null;
1278: List tempVector = null;
1279: Reference tempRef = null;
1280: Reference newRef = null;
1281:
1282: if (contentReference != null) {
1283: String contentId = contentId(contentReference);
1284: if (!m_contentStorage.check(contentId))
1285: throw new IdUnusedException(contentId);
1286: else {
1287: if (M_log.isDebugEnabled())
1288: M_log
1289: .debug("ASSIGNMENT : BASE SERVICE : ADD DUPL. CONTENT : found match - will copy");
1290:
1291: existingContent = getAssignmentContent(contentReference);
1292: retVal = addAssignmentContent(context);
1293: retVal.setTitle(existingContent.getTitle() + " - Copy");
1294: retVal.setInstructions(existingContent
1295: .getInstructions());
1296: retVal.setHonorPledge(existingContent.getHonorPledge());
1297: retVal.setTypeOfSubmission(existingContent
1298: .getTypeOfSubmission());
1299: retVal.setTypeOfGrade(existingContent.getTypeOfGrade());
1300: retVal.setMaxGradePoint(existingContent
1301: .getMaxGradePoint());
1302: retVal.setGroupProject(existingContent
1303: .getGroupProject());
1304: retVal.setIndividuallyGraded(existingContent
1305: .individuallyGraded());
1306: retVal
1307: .setReleaseGrades(existingContent
1308: .releaseGrades());
1309: retVal.setAllowAttachments(existingContent
1310: .getAllowAttachments());
1311:
1312: tempVector = existingContent.getAttachments();
1313: if (tempVector != null) {
1314: for (int z = 0; z < tempVector.size(); z++) {
1315: tempRef = (Reference) tempVector.get(z);
1316: if (tempRef != null) {
1317: String tempRefId = tempRef.getId();
1318: String tempRefCollectionId = ContentHostingService
1319: .getContainingCollectionId(tempRefId);
1320: try {
1321: // get the original attachment display name
1322: ResourceProperties p = ContentHostingService
1323: .getProperties(tempRefId);
1324: String displayName = p
1325: .getProperty(ResourceProperties.PROP_DISPLAY_NAME);
1326: // add another attachment instance
1327: String newItemId = ContentHostingService
1328: .copyIntoFolder(tempRefId,
1329: tempRefCollectionId);
1330: ContentResourceEdit copy = ContentHostingService
1331: .editResource(newItemId);
1332: // with the same display name
1333: ResourcePropertiesEdit pedit = copy
1334: .getPropertiesEdit();
1335: pedit
1336: .addProperty(
1337: ResourceProperties.PROP_DISPLAY_NAME,
1338: displayName);
1339: ContentHostingService.commitResource(
1340: copy,
1341: NotificationService.NOTI_NONE);
1342: newRef = m_entityManager
1343: .newReference(copy
1344: .getReference());
1345: retVal.addAttachment(newRef);
1346: } catch (Exception e) {
1347: if (M_log.isDebugEnabled())
1348: M_log
1349: .debug("ASSIGNMENT : BASE SERVICE : LEAVING ADD DUPLICATE CONTENT : "
1350: + e.toString());
1351: }
1352: }
1353: }
1354: }
1355:
1356: ResourcePropertiesEdit pEdit = (BaseResourcePropertiesEdit) retVal
1357: .getPropertiesEdit();
1358: pEdit.addAll(existingContent.getProperties());
1359: addLiveProperties(pEdit);
1360: }
1361: }
1362:
1363: if (M_log.isDebugEnabled())
1364: M_log
1365: .debug("ASSIGNMENT : BASE SERVICE : LEAVING ADD DUPLICATE CONTENT WITH ID : "
1366: + retVal.getId());
1367:
1368: return retVal;
1369: }
1370:
1371: /**
1372: * Access the AssignmentContent with the specified reference.
1373: *
1374: * @param contentReference -
1375: * The reference of the AssignmentContent.
1376: * @return The AssignmentContent corresponding to the reference, or null if it does not exist.
1377: * @throws IdUnusedException
1378: * if there is no object with this reference.
1379: * @throws PermissionException
1380: * if the current user is not allowed to access this.
1381: */
1382: public AssignmentContent getAssignmentContent(
1383: String contentReference) throws IdUnusedException,
1384: PermissionException {
1385: if (M_log.isDebugEnabled())
1386: M_log
1387: .debug("ASSIGNMENT : BASE SERVICE : GET CONTENT : ID : "
1388: + contentReference);
1389:
1390: // check security on the assignment content
1391: unlockCheck(SECURE_ACCESS_ASSIGNMENT_CONTENT, contentReference);
1392:
1393: AssignmentContent content = null;
1394:
1395: // if we have it in the cache, use it
1396: String contentId = contentId(contentReference);
1397:
1398: if ((m_caching) && (m_contentCache != null)
1399: && (!m_contentCache.disabled())) {
1400: if (m_contentCache.containsKey(contentReference))
1401: content = (AssignmentContent) m_contentCache
1402: .get(contentReference);
1403: else {
1404: content = m_contentStorage.get(contentId);
1405:
1406: // cache the result
1407: m_contentCache.put(contentReference, content);
1408: }
1409: }
1410:
1411: else {
1412: // // if we have done this already in this thread, use that
1413: // content = (AssignmentContent) CurrentService.getInThread(contentId+".assignment.content");
1414: // if (content == null)
1415: // {
1416: content = m_contentStorage.get(contentId);
1417: //
1418: // // "cache" the content in the current service in case they are needed again in this thread...
1419: // if (content != null)
1420: // {
1421: // CurrentService.setInThread(contentId+".assignment.content", contentId);
1422: // }
1423: // }
1424: }
1425:
1426: if (content == null)
1427: throw new IdUnusedException(contentId);
1428:
1429: if (M_log.isDebugEnabled())
1430: M_log
1431: .debug("ASSIGNMENT : BASE SERVICE : GOT ASSIGNMENT CONTENT : ID : "
1432: + content.getId());
1433:
1434: // track event
1435: // EventTrackingService.post(EventTrackingService.newEvent(EVENT_ACCESS_ASSIGNMENT_CONTENT, content.getReference(), false));
1436:
1437: return content;
1438:
1439: }// getAssignmentContent
1440:
1441: /**
1442: * Access all AssignmentContent objects - known to us (not from external providers).
1443: *
1444: * @return A list of AssignmentContent objects.
1445: */
1446: protected List getAssignmentContents(String context) {
1447: List contents = new Vector();
1448:
1449: if ((m_caching) && (m_contentCache != null)
1450: && (!m_contentCache.disabled())) {
1451: // if the cache is complete, use it
1452: if (m_contentCache.isComplete()) {
1453: contents = m_contentCache.getAll();
1454: // TODO: filter by context
1455: }
1456:
1457: // otherwise get all the contents from storage
1458: else {
1459: // Note: while we are getting from storage, storage might change. These can be processed
1460: // after we get the storage entries, and put them in the cache, and mark the cache complete.
1461: // -ggolden
1462: synchronized (m_contentCache) {
1463: // if we were waiting and it's now complete...
1464: if (m_contentCache.isComplete()) {
1465: contents = m_contentCache.getAll();
1466: return contents;
1467: }
1468:
1469: // save up any events to the cache until we get past this load
1470: m_contentCache.holdEvents();
1471:
1472: contents = m_contentStorage.getAll(context);
1473:
1474: // update the cache, and mark it complete
1475: for (int i = 0; i < contents.size(); i++) {
1476: AssignmentContent content = (AssignmentContent) contents
1477: .get(i);
1478: m_contentCache.put(content.getReference(),
1479: content);
1480: }
1481:
1482: m_contentCache.setComplete();
1483: // TODO: not really, just for context
1484:
1485: // now we are complete, process any cached events
1486: m_contentCache.processEvents();
1487: }
1488: }
1489: }
1490:
1491: else {
1492: // // if we have done this already in this thread, use that
1493: // contents = (List) CurrentService.getInThread(context+".assignment.contents");
1494: // if (contents == null)
1495: // {
1496: contents = m_contentStorage.getAll(context);
1497: //
1498: // // "cache" the contents in the current service in case they are needed again in this thread...
1499: // if (contents != null)
1500: // {
1501: // CurrentService.setInThread(context+".assignment.contents", contents);
1502: // }
1503: // }
1504: }
1505:
1506: return contents;
1507:
1508: } // getAssignmentContents
1509:
1510: /**
1511: * Get a locked AssignmentContent object for editing. Must commitEdit() to make official, or cancelEdit() when done!
1512: *
1513: * @param id
1514: * The content id string.
1515: * @return An AssignmentContentEdit object for editing.
1516: * @exception IdUnusedException
1517: * if not found, or if not an AssignmentContentEdit object
1518: * @exception PermissionException
1519: * if the current user does not have permission to edit this content.
1520: * @exception InUseException
1521: * if the assignment is being edited by another user.
1522: */
1523: public AssignmentContentEdit editAssignmentContent(
1524: String contentReference) throws IdUnusedException,
1525: PermissionException, InUseException {
1526: // check security (throws if not permitted)
1527: unlock(SECURE_UPDATE_ASSIGNMENT_CONTENT, contentReference);
1528:
1529: String contentId = contentId(contentReference);
1530:
1531: // check for existance
1532: if (!m_contentStorage.check(contentId)) {
1533: throw new IdUnusedException(contentId);
1534: }
1535:
1536: // ignore the cache - get the AssignmentContent with a lock from the info store
1537: AssignmentContentEdit content = m_contentStorage
1538: .edit(contentId);
1539: if (content == null)
1540: throw new InUseException(contentId);
1541:
1542: ((BaseAssignmentContentEdit) content)
1543: .setEvent(EVENT_UPDATE_ASSIGNMENT_CONTENT);
1544:
1545: return content;
1546:
1547: } // editAssignmentContent
1548:
1549: /**
1550: * Commit the changes made to an AssignmentContentEdit object, and release the lock.
1551: *
1552: * @param content
1553: * The AssignmentContentEdit object to commit.
1554: */
1555: public void commitEdit(AssignmentContentEdit content) {
1556: // check for closed edit
1557: if (!content.isActiveEdit()) {
1558: try {
1559: throw new Exception();
1560: } catch (Exception e) {
1561: M_log
1562: .warn(
1563: "commitEdit(): closed AssignmentContentEdit",
1564: e);
1565: }
1566: return;
1567: }
1568:
1569: // update the properties
1570: addLiveUpdateProperties(content.getPropertiesEdit());
1571:
1572: // complete the edit
1573: m_contentStorage.commit(content);
1574:
1575: // track it
1576: EventTrackingService.post(EventTrackingService.newEvent(
1577: ((BaseAssignmentContentEdit) content).getEvent(),
1578: content.getReference(), true));
1579:
1580: // close the edit object
1581: ((BaseAssignmentContentEdit) content).closeEdit();
1582:
1583: } // commitEdit(AssignmentContent)
1584:
1585: /**
1586: * Cancel the changes made to a AssignmentContentEdit object, and release the lock.
1587: *
1588: * @param content
1589: * The AssignmentContentEdit object to commit.
1590: */
1591: public void cancelEdit(AssignmentContentEdit content) {
1592: // check for closed edit
1593: if (!content.isActiveEdit()) {
1594: try {
1595: throw new Exception();
1596: } catch (Exception e) {
1597: M_log
1598: .warn(
1599: "cancelEdit(): closed AssignmentContentEdit",
1600: e);
1601: }
1602: return;
1603: }
1604:
1605: // release the edit lock
1606: m_contentStorage.cancel(content);
1607:
1608: // close the edit object
1609: ((BaseAssignmentContentEdit) content).closeEdit();
1610:
1611: } // cancelEdit(Content)
1612:
1613: /**
1614: * Removes an AssignmentContent
1615: *
1616: * @param content -
1617: * the AssignmentContent to remove.
1618: * @throws an
1619: * AssignmentContentNotEmptyException if this content still has related Assignments.
1620: * @throws PermissionException
1621: * if current User does not have permission to do this.
1622: */
1623: public void removeAssignmentContent(AssignmentContentEdit content)
1624: throws AssignmentContentNotEmptyException,
1625: PermissionException {
1626: if (content != null) {
1627: if (content.inUse())
1628: throw new AssignmentContentNotEmptyException();
1629: else {
1630: if (!content.isActiveEdit()) {
1631: try {
1632: throw new Exception();
1633: } catch (Exception e) {
1634: M_log
1635: .warn(
1636: "removeAssignmentContent(): closed AssignmentContentEdit",
1637: e);
1638: }
1639: return;
1640: }
1641:
1642: // CHECK SECURITY
1643: unlock(SECURE_REMOVE_ASSIGNMENT_CONTENT, content
1644: .getReference());
1645:
1646: // complete the edit
1647: m_contentStorage.remove(content);
1648:
1649: // track event
1650: EventTrackingService.post(EventTrackingService
1651: .newEvent(EVENT_REMOVE_ASSIGNMENT_CONTENT,
1652: content.getReference(), true));
1653:
1654: // close the edit object
1655: ((BaseAssignmentContentEdit) content).closeEdit();
1656:
1657: // remove any realm defined for this resource
1658: try {
1659: AuthzGroupService
1660: .removeAuthzGroup(AuthzGroupService
1661: .getAuthzGroup(content
1662: .getReference()));
1663: } catch (AuthzPermissionException e) {
1664: M_log
1665: .warn("removeAssignmentContent: removing realm for : "
1666: + content.getReference()
1667: + " : "
1668: + e);
1669: } catch (GroupNotDefinedException ignore) {
1670: }
1671: }
1672: }
1673: }
1674:
1675: /**
1676: * Adds an AssignmentSubmission to the service.
1677: *
1678: * @param context -
1679: * Describes the portlet context - generated with DefaultId.getChannel().
1680: * @return The new AssignmentSubmission.
1681: * @exception IdInvalidException
1682: * if the submission id is invalid.
1683: * @exception IdUsedException
1684: * if the submission id is already used.
1685: * @throws PermissionException
1686: * if the current User does not have permission to do this.
1687: */
1688: public AssignmentSubmissionEdit addSubmission(String context,
1689: String assignmentId) throws PermissionException {
1690: if (M_log.isDebugEnabled())
1691: M_log
1692: .debug("ASSIGNMENT : BASE SERVICE : ENTERING ADD SUBMISSION");
1693:
1694: String submissionId = null;
1695: boolean badId = false;
1696:
1697: do {
1698: badId = !Validator.checkResourceId(submissionId);
1699: submissionId = IdManager.createUuid();
1700:
1701: if (m_submissionStorage.check(submissionId))
1702: badId = true;
1703: } while (badId);
1704:
1705: String key = submissionReference(context, submissionId,
1706: assignmentId);
1707:
1708: if (M_log.isDebugEnabled())
1709: M_log
1710: .debug("ASSIGNMENT : BASE SERVICE : ADD SUBMISSION : SUB REF : "
1711: + key);
1712:
1713: unlock(SECURE_ADD_ASSIGNMENT_SUBMISSION, key);
1714:
1715: if (M_log.isDebugEnabled())
1716: M_log
1717: .debug("ASSIGNMENT : BASE SERVICE : ADD SUBMISSION : UNLOCKED");
1718:
1719: // storage
1720: AssignmentSubmissionEdit submission = m_submissionStorage.put(
1721: submissionId, context, assignmentId);
1722:
1723: if (M_log.isDebugEnabled())
1724: M_log
1725: .debug("ASSIGNMENT : BASE SERVICE : LEAVING ADD SUBMISSION : REF : "
1726: + submission.getReference());
1727:
1728: // event for tracking
1729: ((BaseAssignmentSubmissionEdit) submission)
1730: .setEvent(EVENT_ADD_ASSIGNMENT_SUBMISSION);
1731:
1732: return submission;
1733: }
1734:
1735: /**
1736: * Add a new AssignmentSubmission to the directory, from a definition in XML. Must commitEdit() to make official, or cancelEdit() when done!
1737: *
1738: * @param el
1739: * The XML DOM Element defining the submission.
1740: * @return A locked AssignmentSubmissionEdit object (reserving the id).
1741: * @exception IdInvalidException
1742: * if the submission id is invalid.
1743: * @exception IdUsedException
1744: * if the submission id is already used.
1745: * @exception PermissionException
1746: * if the current user does not have permission to add a submission.
1747: */
1748: public AssignmentSubmissionEdit mergeSubmission(Element el)
1749: throws IdInvalidException, IdUsedException,
1750: PermissionException {
1751: // construct from the XML
1752: BaseAssignmentSubmission submissionFromXml = new BaseAssignmentSubmission(
1753: el);
1754:
1755: // check for a valid submission name
1756: if (!Validator.checkResourceId(submissionFromXml.getId()))
1757: throw new IdInvalidException(submissionFromXml.getId());
1758:
1759: // check security (throws if not permitted)
1760: unlock(SECURE_ADD_ASSIGNMENT_SUBMISSION, submissionFromXml
1761: .getReference());
1762:
1763: // reserve a submission with this id from the info store - if it's in use, this will return null
1764: AssignmentSubmissionEdit submission = m_submissionStorage.put(
1765: submissionFromXml.getId(), submissionFromXml
1766: .getContext(), submissionFromXml
1767: .getAssignmentId());
1768: if (submission == null) {
1769: throw new IdUsedException(submissionFromXml.getId());
1770: }
1771:
1772: // transfer from the XML read submission object to the SubmissionEdit
1773: ((BaseAssignmentSubmissionEdit) submission)
1774: .set(submissionFromXml);
1775:
1776: ((BaseAssignmentSubmissionEdit) submission)
1777: .setEvent(EVENT_ADD_ASSIGNMENT_SUBMISSION);
1778:
1779: return submission;
1780: }
1781:
1782: /**
1783: * Get a locked AssignmentSubmission object for editing. Must commitEdit() to make official, or cancelEdit() when done!
1784: *
1785: * @param submissionrReference -
1786: * the reference for the submission.
1787: * @return An AssignmentSubmissionEdit object for editing.
1788: * @exception IdUnusedException
1789: * if not found, or if not an AssignmentSubmissionEdit object
1790: * @exception PermissionException
1791: * if the current user does not have permission to edit this submission.
1792: * @exception InUseException
1793: * if the assignment is being edited by another user.
1794: */
1795: public AssignmentSubmissionEdit editSubmission(
1796: String submissionReference) throws IdUnusedException,
1797: PermissionException, InUseException {
1798: if (!unlockCheck(SECURE_GRADE_ASSIGNMENT_SUBMISSION,
1799: submissionReference)) {
1800: // check security (throws if not permitted)
1801: unlock2(SECURE_UPDATE_ASSIGNMENT_SUBMISSION,
1802: SECURE_UPDATE_ASSIGNMENT, submissionReference);
1803: }
1804:
1805: String submissionId = submissionId(submissionReference);
1806:
1807: // check for existance
1808: if (!m_submissionStorage.check(submissionId)) {
1809: throw new IdUnusedException(submissionId);
1810: }
1811:
1812: // ignore the cache - get the AssignmentSubmission with a lock from the info store
1813: AssignmentSubmissionEdit submission = m_submissionStorage
1814: .edit(submissionId);
1815: if (submission == null)
1816: throw new InUseException(submissionId);
1817:
1818: ((BaseAssignmentSubmissionEdit) submission)
1819: .setEvent(EVENT_UPDATE_ASSIGNMENT_SUBMISSION);
1820:
1821: return submission;
1822:
1823: } // editSubmission
1824:
1825: /**
1826: * Commit the changes made to an AssignmentSubmissionEdit object, and release the lock.
1827: *
1828: * @param submission
1829: * The AssignmentSubmissionEdit object to commit.
1830: */
1831: public void commitEdit(AssignmentSubmissionEdit submission) {
1832: String submissionRef = submission.getReference();
1833:
1834: // check for closed edit
1835: if (!submission.isActiveEdit()) {
1836: try {
1837: throw new Exception();
1838: } catch (Exception e) {
1839: M_log
1840: .warn(
1841: "commitEdit(): closed AssignmentSubmissionEdit",
1842: e);
1843: }
1844: return;
1845: }
1846:
1847: // update the properties
1848: addLiveUpdateProperties(submission.getPropertiesEdit());
1849:
1850: submission.setTimeLastModified(TimeService.newTime());
1851:
1852: // complete the edit
1853: m_submissionStorage.commit(submission);
1854:
1855: // close the edit object
1856: ((BaseAssignmentSubmissionEdit) submission).closeEdit();
1857:
1858: try {
1859: AssignmentSubmission s = getSubmission(submissionRef);
1860: Time returnedTime = s.getTimeReturned();
1861: Time submittedTime = s.getTimeSubmitted();
1862:
1863: // track it
1864: if (!s.getSubmitted()) {
1865: // saving a submission
1866: EventTrackingService.post(EventTrackingService
1867: .newEvent(EVENT_SAVE_ASSIGNMENT_SUBMISSION,
1868: submissionRef, true));
1869: } else if (submittedTime != null && returnedTime != null
1870: && returnedTime.after(submittedTime)) {
1871: // grading, releasing or returning a submission
1872: EventTrackingService.post(EventTrackingService
1873: .newEvent(EVENT_GRADE_ASSIGNMENT_SUBMISSION,
1874: submissionRef, true));
1875: } else {
1876: // submitting a submission
1877: EventTrackingService.post(EventTrackingService
1878: .newEvent(EVENT_SUBMIT_ASSIGNMENT_SUBMISSION,
1879: submissionRef, true));
1880: }
1881:
1882: } catch (IdUnusedException e) {
1883: M_log
1884: .warn(
1885: "commitEdit(), submissionId="
1886: + submissionRef, e);
1887: } catch (PermissionException e) {
1888: M_log
1889: .warn(
1890: "commitEdit(), submissionId="
1891: + submissionRef, e);
1892: }
1893:
1894: } // commitEdit(Submission)
1895:
1896: /**
1897: * Cancel the changes made to a AssignmentSubmissionEdit object, and release the lock.
1898: *
1899: * @param submission
1900: * The AssignmentSubmissionEdit object to commit.
1901: */
1902: public void cancelEdit(AssignmentSubmissionEdit submission) {
1903: // check for closed edit
1904: if (!submission.isActiveEdit()) {
1905: try {
1906: throw new Exception();
1907: } catch (Exception e) {
1908: M_log
1909: .warn(
1910: "cancelEdit(): closed AssignmentSubmissionEdit",
1911: e);
1912: }
1913: return;
1914: }
1915:
1916: // release the edit lock
1917: m_submissionStorage.cancel(submission);
1918:
1919: // close the edit object
1920: ((BaseAssignmentSubmissionEdit) submission).closeEdit();
1921:
1922: } // cancelEdit(Submission)
1923:
1924: /**
1925: * Removes an AssignmentSubmission and all references to it
1926: *
1927: * @param submission -
1928: * the AssignmentSubmission to remove.
1929: * @throws PermissionException
1930: * if current User does not have permission to do this.
1931: */
1932: public void removeSubmission(AssignmentSubmissionEdit submission)
1933: throws PermissionException {
1934: if (submission != null) {
1935: if (!submission.isActiveEdit()) {
1936: try {
1937: throw new Exception();
1938: } catch (Exception e) {
1939: M_log
1940: .warn(
1941: "removeSubmission(): closed AssignmentSubmissionEdit",
1942: e);
1943: }
1944: return;
1945: }
1946:
1947: // check security
1948: unlock(SECURE_REMOVE_ASSIGNMENT_SUBMISSION, submission
1949: .getReference());
1950:
1951: // complete the edit
1952: m_submissionStorage.remove(submission);
1953:
1954: // track event
1955: EventTrackingService.post(EventTrackingService.newEvent(
1956: EVENT_REMOVE_ASSIGNMENT_SUBMISSION, submission
1957: .getReference(), true));
1958:
1959: // close the edit object
1960: ((BaseAssignmentSubmissionEdit) submission).closeEdit();
1961:
1962: // remove any realm defined for this resource
1963: try {
1964: AuthzGroupService.removeAuthzGroup(AuthzGroupService
1965: .getAuthzGroup(submission.getReference()));
1966: } catch (AuthzPermissionException e) {
1967: M_log.warn("removeSubmission: removing realm for : "
1968: + submission.getReference() + " : " + e);
1969: } catch (GroupNotDefinedException ignore) {
1970: }
1971: }
1972: }// removeSubmission
1973:
1974: /**
1975: * Access all AssignmentSubmission objects - known to us (not from external providers).
1976: *
1977: * @return A list of AssignmentSubmission objects.
1978: */
1979: protected List getSubmissions(String context) {
1980: List submissions = new Vector();
1981:
1982: if ((m_caching) && (m_submissionCache != null)
1983: && (!m_submissionCache.disabled())) {
1984: // if the cache is complete, use it
1985: if (m_submissionCache.isComplete()) {
1986: submissions = m_submissionCache.getAll();
1987: // TODO: filter by context
1988: }
1989:
1990: // otherwise get all the submissions from storage
1991: else {
1992: // Note: while we are getting from storage, storage might change. These can be processed
1993: // after we get the storage entries, and put them in the cache, and mark the cache complete.
1994: // -ggolden
1995: synchronized (m_submissionCache) {
1996: // if we were waiting and it's now complete...
1997: if (m_submissionCache.isComplete()) {
1998: submissions = m_submissionCache.getAll();
1999: return submissions;
2000: }
2001:
2002: // save up any events to the cache until we get past this load
2003: m_submissionCache.holdEvents();
2004:
2005: submissions = m_submissionStorage.getAll(context);
2006:
2007: // update the cache, and mark it complete
2008: for (int i = 0; i < submissions.size(); i++) {
2009: AssignmentSubmission submission = (AssignmentSubmission) submissions
2010: .get(i);
2011: m_submissionCache.put(
2012: submission.getReference(), submission);
2013: }
2014:
2015: m_submissionCache.setComplete();
2016: // TODO: not really! just for context
2017:
2018: // now we are complete, process any cached events
2019: m_submissionCache.processEvents();
2020: }
2021: }
2022: }
2023:
2024: else {
2025: // // if we have done this already in this thread, use that
2026: // submissions = (List) CurrentService.getInThread(context+".assignment.submissions");
2027: // if (submissions == null)
2028: // {
2029: submissions = m_submissionStorage.getAll(context);
2030: //
2031: // // "cache" the submissions in the current service in case they are needed again in this thread...
2032: // if (submissions != null)
2033: // {
2034: // CurrentService.setInThread(context+".assignment.submissions", submissions);
2035: // }
2036: // }
2037: }
2038:
2039: return submissions;
2040:
2041: } // getAssignmentSubmissions
2042:
2043: /**
2044: * Access list of all AssignmentContents created by the User.
2045: *
2046: * @param owner -
2047: * The User who's AssignmentContents are requested.
2048: * @return Iterator over all AssignmentContents owned by this User.
2049: */
2050: public Iterator getAssignmentContents(User owner) {
2051: Vector retVal = new Vector();
2052: AssignmentContent aContent = null;
2053: List allContents = getAssignmentContents(owner.getId());
2054:
2055: for (int x = 0; x < allContents.size(); x++) {
2056: try {
2057: aContent = (AssignmentContent) allContents.get(x);
2058: if (aContent.getCreator().equals(owner.getId()))
2059: ;
2060: retVal.add(aContent);
2061: } catch (Exception e) {
2062: }
2063: }
2064:
2065: if (retVal.isEmpty())
2066: return new EmptyIterator();
2067: else
2068: return retVal.iterator();
2069:
2070: }// getAssignmentContents(User)
2071:
2072: /**
2073: * Access all the Assignments which have the specified AssignmentContent.
2074: *
2075: * @param content -
2076: * The particular AssignmentContent.
2077: * @return Iterator over all the Assignments with the specified AssignmentContent.
2078: */
2079: public Iterator getAssignments(AssignmentContent content) {
2080: Vector retVal = new Vector();
2081: String contentReference = null;
2082: String tempContentReference = null;
2083:
2084: if (content != null) {
2085: contentReference = content.getReference();
2086: List allAssignments = getAssignments(content.getContext());
2087: Assignment tempAssignment = null;
2088:
2089: for (int y = 0; y < allAssignments.size(); y++) {
2090: tempAssignment = (Assignment) allAssignments.get(y);
2091: tempContentReference = tempAssignment
2092: .getContentReference();
2093: if (tempContentReference != null) {
2094: if (tempContentReference.equals(contentReference)) {
2095: retVal.add(tempAssignment);
2096: }
2097: }
2098: }
2099: }
2100:
2101: if (retVal.isEmpty())
2102: return new EmptyIterator();
2103: else
2104: return retVal.iterator();
2105: }
2106:
2107: /**
2108: * Access all the Assignemnts associated with a group.
2109: *
2110: * @param context -
2111: * Describes the portlet context - generated with DefaultId.getChannel().
2112: * @return Iterator over all the Assignments associated with a group.
2113: */
2114: public Iterator getAssignmentsForContext(String context) {
2115: if (M_log.isDebugEnabled())
2116: M_log
2117: .debug("ASSIGNMENT : BASE SERVICE : GET ASSIGNMENTS FOR CONTEXT : CONTEXT : "
2118: + context);
2119: Assignment tempAssignment = null;
2120: Vector retVal = new Vector();
2121: List allAssignments = null;
2122:
2123: if (context != null) {
2124: allAssignments = getAssignments(context);
2125: for (int x = 0; x < allAssignments.size(); x++) {
2126: tempAssignment = (Assignment) allAssignments.get(x);
2127: // M_log.info("ASSIGNMENT : BASE SERVICE : GET ASSIGNMENTS FOR CONTEXT : GOT AN ASSIGNMENT : " + tempAssignment.getTitle());
2128: // M_log.info("ASSIGNMENT : BASE SERVICE : GET ASSIGNMENTS FOR CONTEXT : ASSIGNMENT'S CONTEXT : " + tempAssignment.getContext());
2129:
2130: if ((context.equals(tempAssignment.getContext()))
2131: || (context
2132: .equals(getGroupNameFromContext(tempAssignment
2133: .getContext())))) {
2134: retVal.add(tempAssignment);
2135: // M_log.info("ASSIGNMENT : BASE SERVICE : GET ASSIGNMENTS FOR CONTEXT : FOUND A MATCH");
2136: }
2137: }
2138: }
2139:
2140: if (retVal.isEmpty())
2141: return new EmptyIterator();
2142: else
2143: return retVal.iterator();
2144:
2145: }
2146:
2147: /**
2148: * @inheritDoc
2149: */
2150: public List getListAssignmentsForContext(String context) {
2151: if (M_log.isDebugEnabled())
2152: M_log
2153: .debug("ASSIGNMENT : BASE SERVICE : GET ASSIGNMENTS FOR CONTEXT : CONTEXT : "
2154: + context);
2155: Assignment tempAssignment = null;
2156: Vector retVal = new Vector();
2157: List allAssignments = new Vector();
2158:
2159: if (context != null) {
2160: allAssignments = getAssignments(context);
2161: for (int x = 0; x < allAssignments.size(); x++) {
2162: tempAssignment = (Assignment) allAssignments.get(x);
2163: // M_log.info("ASSIGNMENT : BASE SERVICE : GET ASSIGNMENTS FOR CONTEXT : GOT AN ASSIGNMENT : " + tempAssignment.getTitle());
2164: // M_log.info("ASSIGNMENT : BASE SERVICE : GET ASSIGNMENTS FOR CONTEXT : ASSIGNMENT'S CONTEXT : " + tempAssignment.getContext());
2165:
2166: if ((context.equals(tempAssignment.getContext()))
2167: || (context
2168: .equals(getGroupNameFromContext(tempAssignment
2169: .getContext())))) {
2170: String deleted = tempAssignment
2171: .getProperties()
2172: .getProperty(
2173: ResourceProperties.PROP_ASSIGNMENT_DELETED);
2174: if (deleted == null || deleted.equals("")) {
2175: // not deleted, show it
2176: if (tempAssignment.getDraft()) {
2177: // for draft assignment, only admin users or the creator can see it
2178: if (SecurityService.isSuperUser()
2179: || tempAssignment
2180: .getCreator()
2181: .equals(
2182: UserDirectoryService
2183: .getCurrentUser()
2184: .getId())) {
2185: retVal.add(tempAssignment);
2186: }
2187: } else {
2188: retVal.add(tempAssignment);
2189: }
2190: }
2191: }
2192: }
2193: }
2194:
2195: return retVal;
2196:
2197: }
2198:
2199: /**
2200: * Access a User's AssignmentSubmission to a particular Assignment.
2201: *
2202: * @param assignmentReference
2203: * The reference of the assignment.
2204: * @param person -
2205: * The User who's Submission you would like.
2206: * @return AssignmentSubmission The user's submission for that Assignment.
2207: * @throws IdUnusedException
2208: * if there is no object with this id.
2209: * @throws PermissionException
2210: * if the current user is not allowed to access this.
2211: */
2212: public AssignmentSubmission getSubmission(
2213: String assignmentReference, User person)
2214: throws IdUnusedException, PermissionException {
2215: // M_log.info("ASSIGNMENT : BASE SERVICE : ENTERING GET SUBMISSION(assignmentRef, User)");
2216: // M_log.info("ASSIGNMENT : BASE SERVICE : GET SUBMISSION(assignmentRef, User) : REF : " + assignmentReference);
2217: AssignmentSubmission retVal = null;
2218: AssignmentSubmission sub = null;
2219: List submitters = null;
2220: String aUserId = null;
2221:
2222: String assignmentId = assignmentId(assignmentReference);
2223:
2224: if (!m_assignmentStorage.check(assignmentId))
2225: throw new IdUnusedException(assignmentId);
2226:
2227: if ((assignmentReference != null) && (person != null)) {
2228: Assignment assign = m_assignmentStorage.get(assignmentId);
2229:
2230: // Match User and Assignment
2231: if (assign != null) {
2232: if (M_log.isDebugEnabled())
2233: M_log
2234: .debug("getSubmission : Got assignment with id : "
2235: + assign.getId());
2236:
2237: try {
2238: List submissions = getSubmissions(assign.getId());
2239: for (int z = 0; z < submissions.size(); z++) {
2240: sub = (AssignmentSubmission) submissions.get(z);
2241: if (M_log.isDebugEnabled())
2242: M_log
2243: .debug("getSubmission : submission id found : "
2244: + sub.getId());
2245: if (sub != null) {
2246: // M_log.info("ASSIGNMENT : BASE SERVICE : GET SUBMISSION(assignmentRef, User) : submission parent assignment id : " + sub.getAssignmentId());
2247: if (sub.getAssignmentId().equals(
2248: assignmentId)) {
2249: // M_log.info("ASSIGNMENT : BASE SERVICE : GET SUBMISSION(assignmentRef, User) : SUB'S PARENT ASSIGNMENT ID MATCHES ASSIGNMENT ID");
2250: submitters = sub.getSubmitterIds();
2251: for (int a = 0; a < submitters.size(); a++) {
2252: aUserId = (String) submitters
2253: .get(a);
2254: if (M_log.isDebugEnabled())
2255: M_log
2256: .debug("getSubmission : comparing aUser id : "
2257: + aUserId
2258: + " and chosen user id : "
2259: + person
2260: .getId());
2261: if (aUserId.equals(person.getId())) {
2262: if (M_log.isDebugEnabled())
2263: M_log
2264: .debug("getSubmission : found a match : return value is "
2265: + sub
2266: .getId());
2267: retVal = sub;
2268: }
2269: }
2270: }
2271: }
2272: }
2273: } catch (Exception e) {
2274: M_log.warn("getSubmission : EXCEPTION : " + e);
2275: }
2276: }
2277: }
2278:
2279: if (retVal != null) {
2280: unlock2(SECURE_ACCESS_ASSIGNMENT_SUBMISSION,
2281: SECURE_ACCESS_ASSIGNMENT, retVal.getReference());
2282:
2283: // track event
2284: // EventTrackingService.post(EventTrackingService.newEvent(EVENT_ACCESS_ASSIGNMENT_SUBMISSION, retVal.getReference(), false));
2285: }
2286:
2287: return retVal;
2288: }
2289:
2290: /**
2291: * Get the submissions for an assignment.
2292: *
2293: * @param assignment -
2294: * the Assignment who's submissions you would like.
2295: * @return Iterator over all the submissions for an Assignment.
2296: */
2297: public Iterator getSubmissions(Assignment assignment) {
2298: List retVal = new Vector();
2299:
2300: if (assignment != null) {
2301: retVal = getSubmissions(assignment.getId());
2302: }
2303:
2304: if (retVal.isEmpty())
2305: return new EmptyIterator();
2306: else
2307: return retVal.iterator();
2308: }
2309:
2310: /**
2311: * Access the AssignmentSubmission with the specified id.
2312: *
2313: * @param submissionReference -
2314: * The reference of the AssignmentSubmission.
2315: * @return The AssignmentSubmission corresponding to the id, or null if it does not exist.
2316: * @throws IdUnusedException
2317: * if there is no object with this id.
2318: * @throws PermissionException
2319: * if the current user is not allowed to access this.
2320: */
2321: public AssignmentSubmission getSubmission(String submissionReference)
2322: throws IdUnusedException, PermissionException {
2323: if (M_log.isDebugEnabled())
2324: M_log
2325: .debug("ASSIGNMENT : BASE SERVICE : GET SUBMISSION : REF : "
2326: + submissionReference);
2327:
2328: // check permission
2329: unlock2(SECURE_ACCESS_ASSIGNMENT_SUBMISSION,
2330: SECURE_ACCESS_ASSIGNMENT, submissionReference);
2331:
2332: AssignmentSubmission submission = null;
2333:
2334: String submissionId = submissionId(submissionReference);
2335:
2336: if ((m_caching) && (m_submissionCache != null)
2337: && (!m_submissionCache.disabled())) {
2338: // if we have it in the cache, use it
2339: if (m_submissionCache.containsKey(submissionReference))
2340: submission = (AssignmentSubmission) m_submissionCache
2341: .get(submissionReference);
2342: else {
2343: submission = m_submissionStorage.get(submissionId);
2344:
2345: // cache the result
2346: m_submissionCache.put(submissionReference, submission);
2347: }
2348: }
2349:
2350: else {
2351: // // if we have done this already in this thread, use that
2352: // submission = (AssignmentSubmission) CurrentService.getInThread(submissionId+".assignment.submission");
2353: // if (submission == null)
2354: // {
2355: submission = m_submissionStorage.get(submissionId);
2356: //
2357: // // "cache" the submission in the current service in case they are needed again in this thread...
2358: // if (submission != null)
2359: // {
2360: // CurrentService.setInThread(submissionId+".assignment.submission", submission);
2361: // }
2362: // }
2363: }
2364:
2365: if (submission == null)
2366: throw new IdUnusedException(submissionId);
2367:
2368: // track event
2369: // EventTrackingService.post(EventTrackingService.newEvent(EVENT_ACCESS_ASSIGNMENT_SUBMISSION, submission.getReference(), false));
2370:
2371: return submission;
2372:
2373: }// getAssignmentSubmission
2374:
2375: /**
2376: * Return the reference root for use in resource references and urls.
2377: *
2378: * @return The reference root for use in resource references and urls.
2379: */
2380: protected String getReferenceRoot() {
2381: return REFERENCE_ROOT;
2382: }
2383:
2384: /**
2385: * Update the live properties for an object when modified.
2386: */
2387: protected void addLiveUpdateProperties(ResourcePropertiesEdit props) {
2388: props.addProperty(ResourceProperties.PROP_MODIFIED_BY,
2389: SessionManager.getCurrentSessionUserId());
2390:
2391: props.addProperty(ResourceProperties.PROP_MODIFIED_DATE,
2392: TimeService.newTime().toString());
2393:
2394: } // addLiveUpdateProperties
2395:
2396: /**
2397: * Create the live properties for the object.
2398: */
2399: protected void addLiveProperties(ResourcePropertiesEdit props) {
2400: String current = SessionManager.getCurrentSessionUserId();
2401: props.addProperty(ResourceProperties.PROP_CREATOR, current);
2402: props.addProperty(ResourceProperties.PROP_MODIFIED_BY, current);
2403:
2404: String now = TimeService.newTime().toString();
2405: props.addProperty(ResourceProperties.PROP_CREATION_DATE, now);
2406: props.addProperty(ResourceProperties.PROP_MODIFIED_DATE, now);
2407:
2408: } // addLiveProperties
2409:
2410: /**
2411: * check permissions for addAssignment().
2412: *
2413: * @param context -
2414: * Describes the portlet context - generated with DefaultId.getChannel()
2415: * @return true if the user is allowed to addAssignment(...), false if not.
2416: */
2417: public boolean allowAddGroupAssignment(String context) {
2418: // base the check for SECURE_ADD on the site, any of the site's groups, and the channel
2419: // if the user can SECURE_ADD anywhere in that mix, they can add an assignment
2420: // this stack is not the normal azg set for channels, so use a special refernce to get this behavior
2421: String resourceString = getAccessPoint(true) + Entity.SEPARATOR
2422: + REF_TYPE_ASSIGNMENT_GROUPS + Entity.SEPARATOR + "a"
2423: + Entity.SEPARATOR + context + Entity.SEPARATOR;
2424:
2425: if (M_log.isDebugEnabled()) {
2426: M_log
2427: .debug("Entering allow add Assignment with resource string : "
2428: + resourceString);
2429: M_log
2430: .debug(" context string : "
2431: + context);
2432: }
2433:
2434: // check security on the channel (throws if not permitted)
2435: return unlockCheck(SECURE_ADD_ASSIGNMENT, resourceString);
2436:
2437: } // allowAddGroupAssignment
2438:
2439: /**
2440: * Check permissions for adding an Assignment.
2441: *
2442: * @param context -
2443: * Describes the portlet context - generated with DefaultId.getChannel().
2444: * @return True if the current User is allowed to add an Assignment, false if not.
2445: */
2446: public boolean allowAddAssignment(String context) {
2447: String resourceString = getAccessPoint(true) + Entity.SEPARATOR
2448: + "a" + Entity.SEPARATOR + context + Entity.SEPARATOR;
2449: // base the check for SECURE_ADD_ASSIGNMENT on the site and any of the site's groups
2450: // if the user can SECURE_ADD_ASSIGNMENT anywhere in that mix, they can add an assignment
2451: // this stack is not the normal azg set for site, so use a special refernce to get this behavior
2452:
2453: if (M_log.isDebugEnabled()) {
2454: M_log
2455: .debug("Entering allow add Assignment with resource string : "
2456: + resourceString);
2457: }
2458:
2459: // checking allow at the site level
2460: if (unlockCheck(SECURE_ADD_ASSIGNMENT, resourceString))
2461: return true;
2462:
2463: // if not, see if the user has any groups to which adds are allowed
2464: return (!getGroupsAllowAddAssignment(context).isEmpty());
2465: }
2466:
2467: /**
2468: * @inheritDoc
2469: */
2470: public boolean allowAddSiteAssignment(String context) {
2471: // check for assignments that will be site-wide:
2472: String resourceString = getAccessPoint(true) + Entity.SEPARATOR
2473: + "a" + Entity.SEPARATOR + context + Entity.SEPARATOR;
2474:
2475: if (M_log.isDebugEnabled()) {
2476: M_log
2477: .debug("Entering allow add Assignment with resource string : "
2478: + resourceString);
2479: }
2480:
2481: // check security on the channel (throws if not permitted)
2482: return unlockCheck(SECURE_ADD_ASSIGNMENT, resourceString);
2483: }
2484:
2485: /**
2486: * @inheritDoc
2487: */
2488: public Collection getGroupsAllowAddAssignment(String context) {
2489: return getGroupsAllowFunction(SECURE_ADD_ASSIGNMENT, context);
2490: }
2491:
2492: /**
2493: * @inherit
2494: */
2495: public boolean allowGetAssignment(String context) {
2496: String resourceString = getAccessPoint(true) + Entity.SEPARATOR
2497: + "a" + Entity.SEPARATOR + context + Entity.SEPARATOR;
2498:
2499: if (M_log.isDebugEnabled()) {
2500: M_log
2501: .debug("Entering allow get Assignment with resource string : "
2502: + resourceString);
2503: }
2504:
2505: return unlockCheck(SECURE_ACCESS_ASSIGNMENT, resourceString);
2506: }
2507:
2508: /**
2509: * @inheritDoc
2510: */
2511: public Collection getGroupsAllowGetAssignment(String context) {
2512: return getGroupsAllowFunction(SECURE_ACCESS_ASSIGNMENT, context);
2513: }
2514:
2515: /**
2516: * Check permissions for updateing an Assignment.
2517: *
2518: * @param assignmentReference -
2519: * The Assignment's reference.
2520: * @return True if the current User is allowed to update the Assignment, false if not.
2521: */
2522: public boolean allowUpdateAssignment(String assignmentReference) {
2523: if (M_log.isDebugEnabled())
2524: M_log
2525: .debug("Entering allow update Assignment with resource string : "
2526: + assignmentReference);
2527:
2528: return unlockCheck(SECURE_UPDATE_ASSIGNMENT,
2529: assignmentReference);
2530: }
2531:
2532: /**
2533: * Check permissions for removing an Assignment.
2534: *
2535: * @return True if the current User is allowed to remove the Assignment, false if not.
2536: */
2537: public boolean allowRemoveAssignment(String assignmentReference) {
2538: if (M_log.isDebugEnabled())
2539: M_log.debug("Entering allow remove Assignment "
2540: + assignmentReference);
2541:
2542: // check security (throws if not permitted)
2543: return unlockCheck(SECURE_REMOVE_ASSIGNMENT,
2544: assignmentReference);
2545: }
2546:
2547: /**
2548: * @inheritDoc
2549: */
2550: public Collection getGroupsAllowRemoveAssignment(String context) {
2551: return getGroupsAllowFunction(SECURE_REMOVE_ASSIGNMENT, context);
2552: }
2553:
2554: /**
2555: * Get the groups of this channel's contex-site that the end user has permission to "function" in.
2556: *
2557: * @param function
2558: * The function to check
2559: */
2560: protected Collection getGroupsAllowFunction(String function,
2561: String context) {
2562: Collection rv = new Vector();
2563:
2564: try {
2565: // get the site groups
2566: Site site = SiteService.getSite(context);
2567: Collection groups = site.getGroups();
2568:
2569: // if the user has SECURE_ALL_GROUPS in the context (site), or a super user, select all site groups
2570: if (SecurityService.isSuperUser()
2571: || AuthzGroupService.isAllowed(SessionManager
2572: .getCurrentSessionUserId(),
2573: SECURE_ALL_GROUPS, SiteService
2574: .siteReference(context))
2575: && unlockCheck(function, SiteService
2576: .siteReference(context))) {
2577: return groups;
2578: }
2579:
2580: // otherwise, check the groups for function
2581:
2582: // get a list of the group refs, which are authzGroup ids
2583: Collection groupRefs = new Vector();
2584: for (Iterator i = groups.iterator(); i.hasNext();) {
2585: Group group = (Group) i.next();
2586: groupRefs.add(group.getReference());
2587: }
2588:
2589: // ask the authzGroup service to filter them down based on function
2590: groupRefs = AuthzGroupService.getAuthzGroupsIsAllowed(
2591: SessionManager.getCurrentSessionUserId(), function,
2592: groupRefs);
2593:
2594: // pick the Group objects from the site's groups to return, those that are in the groupRefs list
2595: for (Iterator i = groups.iterator(); i.hasNext();) {
2596: Group group = (Group) i.next();
2597: if (groupRefs.contains(group.getReference())) {
2598: rv.add(group);
2599: }
2600: }
2601: } catch (IdUnusedException e) {
2602: }
2603:
2604: return rv;
2605:
2606: }
2607:
2608: /** ***********************************************check permissions for AssignmentContent object ******************************************* */
2609: /**
2610: * Check permissions for get AssignmentContent
2611: *
2612: * @param contentReference -
2613: * The AssignmentContent reference.
2614: * @return True if the current User is allowed to access the AssignmentContent, false if not.
2615: */
2616: public boolean allowGetAssignmentContent(String context) {
2617: String resourceString = getAccessPoint(true) + Entity.SEPARATOR
2618: + "c" + Entity.SEPARATOR + context + Entity.SEPARATOR;
2619:
2620: if (M_log.isDebugEnabled()) {
2621: M_log
2622: .debug("Entering allow get AssignmentContent with resource string : "
2623: + resourceString);
2624: }
2625:
2626: // check security (throws if not permitted)
2627: return unlockCheck(SECURE_ACCESS_ASSIGNMENT_CONTENT,
2628: resourceString);
2629: }
2630:
2631: /**
2632: * Check permissions for updating AssignmentContent
2633: *
2634: * @param contentReference -
2635: * The AssignmentContent reference.
2636: * @return True if the current User is allowed to update the AssignmentContent, false if not.
2637: */
2638: public boolean allowUpdateAssignmentContent(String contentReference) {
2639: if (M_log.isDebugEnabled())
2640: M_log
2641: .debug("Entering allow update AssignmentContent with resource string : "
2642: + contentReference);
2643:
2644: // check security (throws if not permitted)
2645: return unlockCheck(SECURE_UPDATE_ASSIGNMENT_CONTENT,
2646: contentReference);
2647: }
2648:
2649: /**
2650: * Check permissions for adding an AssignmentContent.
2651: *
2652: * @param context -
2653: * Describes the portlet context - generated with DefaultId.getChannel().
2654: * @return True if the current User is allowed to add an AssignmentContent, false if not.
2655: */
2656: public boolean allowAddAssignmentContent(String context) {
2657: String resourceString = getAccessPoint(true) + Entity.SEPARATOR
2658: + "c" + Entity.SEPARATOR + context + Entity.SEPARATOR;
2659: if (M_log.isDebugEnabled())
2660: M_log
2661: .debug("Entering allow add AssignmentContent with resource string : "
2662: + resourceString);
2663:
2664: // check security (throws if not permitted)
2665: return unlockCheck(SECURE_ADD_ASSIGNMENT_CONTENT,
2666: resourceString);
2667: }
2668:
2669: /**
2670: * Check permissions for remove the AssignmentContent
2671: *
2672: * @param contentReference -
2673: * The AssignmentContent reference.
2674: * @return True if the current User is allowed to remove the AssignmentContent, false if not.
2675: */
2676: public boolean allowRemoveAssignmentContent(String contentReference) {
2677: if (M_log.isDebugEnabled())
2678: M_log
2679: .debug("Entering allow remove assignment content with resource string : "
2680: + contentReference);
2681:
2682: // check security (throws if not permitted)
2683: return unlockCheck(SECURE_REMOVE_ASSIGNMENT_CONTENT,
2684: contentReference);
2685: }
2686:
2687: /**
2688: * Check permissions for add AssignmentSubmission
2689: *
2690: * @param context -
2691: * Describes the portlet context - generated with DefaultId.getChannel().
2692: * @return True if the current User is allowed to add an AssignmentSubmission, false if not.
2693: */
2694: public boolean allowAddSubmission(String context) {
2695: // check security (throws if not permitted)
2696: String resourceString = getAccessPoint(true) + Entity.SEPARATOR
2697: + "s" + Entity.SEPARATOR + context + Entity.SEPARATOR;
2698:
2699: if (M_log.isDebugEnabled())
2700: M_log
2701: .debug("Entering allow add Submission with resource string : "
2702: + resourceString);
2703:
2704: return unlockCheck(SECURE_ADD_ASSIGNMENT_SUBMISSION,
2705: resourceString);
2706: }
2707:
2708: /**
2709: * Get the List of Users who can addSubmission() for this assignment.
2710: *
2711: * @param assignmentReference -
2712: * a reference to an assignment
2713: * @return the List (User) of users who can addSubmission() for this assignment.
2714: */
2715: public List allowAddSubmissionUsers(String assignmentReference) {
2716: List rv = new Vector();
2717:
2718: rv = SecurityService.unlockUsers(
2719: SECURE_ADD_ASSIGNMENT_SUBMISSION, assignmentReference);
2720:
2721: // get the list of users who have SECURE_ALL_GROUPS
2722: List allGroupUsers = new Vector();
2723: try {
2724: String contextRef = SiteService
2725: .siteReference(getAssignment(assignmentReference)
2726: .getContext());
2727: allGroupUsers = SecurityService.unlockUsers(
2728: SECURE_ALL_GROUPS, contextRef);
2729: // remove duplicates
2730: allGroupUsers.removeAll(rv);
2731: } catch (Exception e) {
2732: M_log.warn(this + e.getMessage() + assignmentReference);
2733: }
2734:
2735: // combine two lists together
2736: rv.addAll(allGroupUsers);
2737:
2738: return rv;
2739:
2740: } // allowAddSubmissionUsers
2741:
2742: /**
2743: * Get the List of Users who can add assignment
2744: *
2745: * @param assignmentReference -
2746: * a reference to an assignment
2747: * @return the List (User) of users who can addSubmission() for this assignment.
2748: */
2749: public List allowAddAssignmentUsers(String context) {
2750: String resourceString = getAccessPoint(true) + Entity.SEPARATOR
2751: + "a" + Entity.SEPARATOR + context + Entity.SEPARATOR;
2752: if (M_log.isDebugEnabled()) {
2753: M_log
2754: .debug("Entering allowAddAssignmentUsers with resource string : "
2755: + resourceString);
2756: M_log
2757: .debug(" context string : "
2758: + context);
2759: }
2760: return SecurityService.unlockUsers(SECURE_ADD_ASSIGNMENT,
2761: resourceString);
2762:
2763: } // allowAddAssignmentUsers
2764:
2765: /**
2766: * Check permissions for accessing a Submission.
2767: *
2768: * @param submissionReference -
2769: * The Submission's reference.
2770: * @return True if the current User is allowed to get the AssignmentSubmission, false if not.
2771: */
2772: public boolean allowGetSubmission(String submissionReference) {
2773: if (M_log.isDebugEnabled())
2774: M_log
2775: .debug("Entering allow get Submission with resource string : "
2776: + submissionReference);
2777:
2778: return unlockCheck2(SECURE_ACCESS_ASSIGNMENT_SUBMISSION,
2779: SECURE_ACCESS_ASSIGNMENT, submissionReference);
2780: }
2781:
2782: /**
2783: * Check permissions for updating Submission.
2784: *
2785: * @param submissionReference -
2786: * The Submission's reference.
2787: * @return True if the current User is allowed to update the AssignmentSubmission, false if not.
2788: */
2789: public boolean allowUpdateSubmission(String submissionReference) {
2790: if (M_log.isDebugEnabled())
2791: M_log
2792: .debug("Entering allow update Submission with resource string : "
2793: + submissionReference);
2794:
2795: return unlockCheck2(SECURE_UPDATE_ASSIGNMENT_SUBMISSION,
2796: SECURE_UPDATE_ASSIGNMENT, submissionReference);
2797: }
2798:
2799: /**
2800: * Check permissions for remove Submission
2801: *
2802: * @param submissionReference -
2803: * The Submission's reference.
2804: * @return True if the current User is allowed to remove the AssignmentSubmission, false if not.
2805: */
2806: public boolean allowRemoveSubmission(String submissionReference) {
2807: if (M_log.isDebugEnabled())
2808: M_log
2809: .debug("Entering allow remove Submission with resource string : "
2810: + submissionReference);
2811:
2812: // check security (throws if not permitted)
2813: return unlockCheck(SECURE_REMOVE_ASSIGNMENT_SUBMISSION,
2814: submissionReference);
2815: }
2816:
2817: public boolean allowGradeSubmission(String assignmentReference) {
2818: if (M_log.isDebugEnabled()) {
2819: M_log
2820: .debug("Entering allow grade Assignment with resource string : "
2821: + assignmentReference);
2822: }
2823: return unlockCheck(SECURE_GRADE_ASSIGNMENT_SUBMISSION,
2824: assignmentReference);
2825: }
2826:
2827: /**
2828: * Access the grades spreadsheet for the reference, either for an assignment or all assignments in a context.
2829: *
2830: * @param ref
2831: * The reference, either to a specific assignment, or just to an assignment context.
2832: * @return The grades spreadsheet bytes.
2833: * @throws IdUnusedException
2834: * if there is no object with this id.
2835: * @throws PermissionException
2836: * if the current user is not allowed to access this.
2837: */
2838: public byte[] getGradesSpreadsheet(String ref)
2839: throws IdUnusedException, PermissionException {
2840: String typeGradesString = new String(REF_TYPE_GRADES
2841: + Entity.SEPARATOR);
2842: String context = ref.substring(ref.indexOf(typeGradesString)
2843: + typeGradesString.length());
2844:
2845: // get site title for display purpose
2846: String siteTitle = "";
2847: try {
2848: Site s = SiteService.getSite(context);
2849: siteTitle = s.getTitle();
2850: } catch (Exception e) {
2851: // ignore exception
2852: }
2853:
2854: // does current user allowed to grade any assignment?
2855: boolean allowGradeAny = false;
2856: List assignmentsList = getListAssignmentsForContext(context);
2857: for (int iAssignment = 0; !allowGradeAny
2858: && iAssignment < assignmentsList.size(); iAssignment++) {
2859: if (allowGradeSubmission(((Assignment) assignmentsList
2860: .get(iAssignment)).getReference())) {
2861: allowGradeAny = true;
2862: }
2863: }
2864:
2865: if (!allowGradeAny) {
2866: // not permitted to download the spreadsheet
2867: return null;
2868: } else {
2869: short rowNum = 0;
2870: HSSFWorkbook wb = new HSSFWorkbook();
2871: HSSFSheet sheet = wb.createSheet(siteTitle);
2872:
2873: // Create a row and put some cells in it. Rows are 0 based.
2874: HSSFRow row = sheet.createRow(rowNum++);
2875:
2876: row.createCell((short) 0).setCellValue(
2877: rb.getString("download.spreadsheet.title"));
2878:
2879: // empty line
2880: row = sheet.createRow(rowNum++);
2881: row.createCell((short) 0).setCellValue("");
2882:
2883: // site title
2884: row = sheet.createRow(rowNum++);
2885: row.createCell((short) 0).setCellValue(
2886: rb.getString("download.spreadsheet.site")
2887: + siteTitle);
2888:
2889: // download time
2890: row = sheet.createRow(rowNum++);
2891: row.createCell((short) 0)
2892: .setCellValue(
2893: rb.getString("download.spreadsheet.date")
2894: + TimeService.newTime()
2895: .toStringLocalFull());
2896:
2897: // empty line
2898: row = sheet.createRow(rowNum++);
2899: row.createCell((short) 0).setCellValue("");
2900:
2901: // the bold font
2902: HSSFFont font = wb.createFont();
2903: font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
2904:
2905: // the cell style with bold font
2906: HSSFCellStyle style = wb.createCellStyle();
2907: style.setFont(font);
2908:
2909: // this is the header row number
2910: short headerRowNumber = rowNum;
2911: // set up the header cells
2912: row = sheet.createRow(rowNum++);
2913: short cellNum = 0;
2914:
2915: // user enterprise id column
2916: HSSFCell cell = row.createCell(cellNum++);
2917: cell.setCellStyle(style);
2918: cell.setCellValue(rb
2919: .getString("download.spreadsheet.column.name"));
2920:
2921: // user name column
2922: cell = row.createCell(cellNum++);
2923: cell.setCellStyle(style);
2924: cell.setCellValue(rb
2925: .getString("download.spreadsheet.column.userid"));
2926:
2927: // starting from this row, going to input user data
2928: Iterator assignments = new SortedIterator(assignmentsList
2929: .iterator(), new AssignmentComparator("duedate",
2930: "true"));
2931:
2932: // allow add assignment members
2933: List allowAddAssignmentUsers = allowAddAssignmentUsers(context);
2934: // site members excluding those who can add assignments
2935: List members = new Vector();
2936: // hashtable which stores the Excel row number for particular user
2937: Hashtable user_row = new Hashtable();
2938:
2939: try {
2940: AuthzGroup group = AuthzGroupService
2941: .getAuthzGroup(SiteService
2942: .siteReference(context));
2943: Set grants = group.getUsers();
2944: for (Iterator iUserIds = new SortedIterator(grants
2945: .iterator(), new AssignmentComparator(
2946: "sortname", "true")); iUserIds.hasNext();) {
2947: String userId = (String) iUserIds.next();
2948: try {
2949: User u = UserDirectoryService.getUser(userId);
2950: // only return student
2951: if (!allowAddAssignmentUsers.contains(u)) {
2952: members.add(u);
2953: // create the column for user first
2954: row = sheet.createRow(rowNum);
2955: // update user_row Hashtable
2956: user_row
2957: .put(u.getId(), new Integer(rowNum));
2958: // increase row
2959: rowNum++;
2960: // put user displayid and sortname in the first two cells
2961: cellNum = 0;
2962: row.createCell(cellNum++).setCellValue(
2963: u.getSortName());
2964: row.createCell(cellNum).setCellValue(
2965: u.getDisplayId());
2966: }
2967: } catch (Exception e) {
2968: M_log.warn(this + e.getMessage() + " userId = "
2969: + userId);
2970: }
2971: }
2972:
2973: int index = 0;
2974: // the grade data portion starts from the third column, since the first two are used for user's display id and sort name
2975: while (assignments.hasNext()) {
2976: Assignment a = (Assignment) assignments.next();
2977:
2978: int assignmentType = a.getContent()
2979: .getTypeOfGrade();
2980:
2981: // for column header, check allow grade permission based on each assignment
2982: if (!a.getDraft()) {
2983: // put in assignment title as the column header
2984: rowNum = headerRowNumber;
2985: row = sheet.getRow(rowNum++);
2986: cellNum = (short) (index + 2);
2987: cell = row.createCell(cellNum); // since the first two column is taken by student id and name
2988: cell.setCellStyle(style);
2989: cell.setCellValue(a.getTitle());
2990:
2991: for (int loopNum = 0; loopNum < members.size(); loopNum++) {
2992: // prepopulate the column with the "no submission" string
2993: row = sheet.getRow(rowNum++);
2994: cell = row.createCell(cellNum);
2995: cell.setCellType(1);
2996: cell.setCellValue(rb
2997: .getString("listsub.nosub"));
2998: }
2999:
3000: // begin to populate the column for this assignment, iterating through student list
3001: for (Iterator sIterator = getSubmissions(a); sIterator
3002: .hasNext();) {
3003: AssignmentSubmission submission = (AssignmentSubmission) sIterator
3004: .next();
3005:
3006: String userId = (String) submission
3007: .getSubmitterIds().get(0);
3008:
3009: if (user_row.containsKey(userId)) {
3010: // find right row
3011: row = sheet.getRow(((Integer) user_row
3012: .get(userId)).intValue());
3013:
3014: if (submission.getGraded()
3015: && submission
3016: .getGradeReleased()
3017: && submission.getGrade() != null) {
3018: // graded and released
3019: if (assignmentType == 3) {
3020: try {
3021: // numeric cell type?
3022: String grade = submission
3023: .getGradeDisplay();
3024: Float.parseFloat(grade);
3025:
3026: // remove the String-based cell first
3027: cell = row.getCell(cellNum);
3028: row.removeCell(cell);
3029: // add number based cell
3030: cell = row
3031: .createCell(cellNum);
3032: cell.setCellType(0);
3033: cell.setCellValue(Float
3034: .parseFloat(grade));
3035:
3036: style = wb
3037: .createCellStyle();
3038: style.setDataFormat(wb
3039: .createDataFormat()
3040: .getFormat(
3041: "#,##0.0"));
3042: cell.setCellStyle(style);
3043: } catch (Exception e) {
3044: // if the grade is not numeric, let's make it as String type
3045: row.removeCell(cell);
3046: cell = row
3047: .createCell(cellNum);
3048: cell.setCellType(1);
3049: cell
3050: .setCellValue(submission
3051: .getGrade());
3052: }
3053: } else {
3054: // String cell type
3055: cell = row.getCell(cellNum);
3056: cell.setCellValue(submission
3057: .getGrade());
3058: }
3059: } else {
3060: // no grade available yet
3061: cell = row.getCell(cellNum);
3062: cell.setCellValue("");
3063: }
3064: } // if
3065: }
3066: }
3067:
3068: index++;
3069:
3070: }
3071: } catch (Exception e) {
3072: M_log.warn(e.getMessage() + " context=" + context);
3073: }
3074:
3075: // output
3076: Blob b = new Blob();
3077: try {
3078: wb.write(b.outputStream());
3079: } catch (IOException e) {
3080: M_log.debug(this
3081: + "Can not output the grade spread sheet. ");
3082: }
3083:
3084: return b.getBytes();
3085: }
3086:
3087: } // getGradesSpreadsheet
3088:
3089: /**
3090: * Access the submissions zip for the assignment reference.
3091: *
3092: * @param ref
3093: * The assignment reference.
3094: * @return The submissions zip bytes.
3095: * @throws IdUnusedException
3096: * if there is no object with this id.
3097: * @throws PermissionException
3098: * if the current user is not allowed to access this.
3099: */
3100: public byte[] getSubmissionsZip(String ref)
3101: throws IdUnusedException, PermissionException {
3102: if (M_log.isDebugEnabled())
3103: M_log.debug(this + ": getSubmissionsZip reference=" + ref);
3104:
3105: byte[] rv = null;
3106:
3107: try {
3108: Assignment a = getAssignment(assignmentReferenceFromSubmissionsZipReference(ref));
3109:
3110: Blob b = new Blob();
3111: StringBuffer exceptionMessage = new StringBuffer();
3112:
3113: if (allowGradeSubmission(a.getReference())) {
3114: try {
3115: ZipOutputStream out = new ZipOutputStream(b
3116: .outputStream());
3117:
3118: // create the folder structor - named after the assignment's title
3119: String root = Validator
3120: .escapeZipEntry(a.getTitle())
3121: + Entity.SEPARATOR;
3122:
3123: Iterator submissions = getSubmissions(a);
3124: String submittedText = "";
3125: if (!submissions.hasNext()) {
3126: exceptionMessage
3127: .append("There is no submission yet. ");
3128: }
3129:
3130: // Create the ZIP file
3131: String submittersName = "";
3132: int count = 1;
3133: while (submissions.hasNext()) {
3134: count = 1;
3135: submittersName = root;
3136: AssignmentSubmission s = (AssignmentSubmission) submissions
3137: .next();
3138:
3139: if (s.getSubmitted()) {
3140: User[] submitters = s.getSubmitters();
3141: String submittersString = "";
3142: for (int i = 0; i < submitters.length; i++) {
3143: if (i > 0) {
3144: submittersString = submittersString
3145: .concat("; ");
3146: }
3147: submittersString = submittersString
3148: .concat(submitters[i]
3149: .getLastName()
3150: + ","
3151: + submitters[i]
3152: .getFirstName());
3153: }
3154:
3155: if (StringUtil.trimToNull(submittersString) != null) {
3156: submittersName = submittersName
3157: .concat(StringUtil
3158: .trimToNull(submittersString));
3159: submittedText = s.getSubmittedText();
3160:
3161: boolean added = false;
3162: while (!added) {
3163: try {
3164: submittersName = submittersName
3165: .concat("/");
3166: // create the folder structure - named after the submitter's name
3167: AssignmentContent ac = a
3168: .getContent();
3169: if (ac.getTypeOfSubmission() != Assignment.ATTACHMENT_ONLY_ASSIGNMENT_SUBMISSION) {
3170: // create the text file only when a text submission is allowed
3171: String entryName = submittersName
3172: + submittersString
3173: + "_submissionText.html";
3174: ZipEntry textEntry = new ZipEntry(
3175: entryName);
3176: out.putNextEntry(textEntry);
3177: out
3178: .write(FormattedText
3179: .encodeUnicode(
3180: submittedText)
3181: .getBytes());
3182: out.closeEntry();
3183: }
3184:
3185: // create the attachment file(s)
3186: List attachments = s
3187: .getSubmittedAttachments();
3188: int attachedUrlCount = 0;
3189: for (int j = 0; j < attachments
3190: .size(); j++) {
3191: Reference r = (Reference) attachments
3192: .get(j);
3193: try {
3194: ContentResource resource = ContentHostingService
3195: .getResource(r
3196: .getId());
3197:
3198: String contentType = resource
3199: .getContentType();
3200:
3201: ResourceProperties props = r
3202: .getProperties();
3203: String displayName = props
3204: .getPropertyFormatted(props
3205: .getNamePropDisplayName());
3206:
3207: // for URL content type, encode a redirect to the body URL
3208: if (contentType
3209: .equalsIgnoreCase(ResourceProperties.TYPE_URL)) {
3210: displayName = "attached_URL_"
3211: + attachedUrlCount;
3212: attachedUrlCount++;
3213: }
3214:
3215: // buffered stream input
3216: InputStream content = resource
3217: .streamContent();
3218: byte data[] = new byte[1024 * 10];
3219: BufferedInputStream bContent = new BufferedInputStream(
3220: content,
3221: data.length);
3222:
3223: ZipEntry attachmentEntry = new ZipEntry(
3224: submittersName
3225: + displayName);
3226: out
3227: .putNextEntry(attachmentEntry);
3228: int bCount = -1;
3229: while ((bCount = bContent
3230: .read(
3231: data,
3232: 0,
3233: data.length)) != -1) {
3234: out.write(data, 0,
3235: bCount);
3236: }
3237: out.closeEntry();
3238: content.close();
3239: } catch (PermissionException e) {
3240: M_log
3241: .debug(this
3242: + ": getSubmissionsZip--PermissionException submittersName="
3243: + submittersName
3244: + " attachment reference="
3245: + r);
3246: } catch (IdUnusedException e) {
3247: M_log
3248: .debug(this
3249: + ": getSubmissionsZip--IdUnusedException submittersName="
3250: + submittersName
3251: + " attachment reference="
3252: + r);
3253: } catch (TypeException e) {
3254: M_log
3255: .debug(this
3256: + ": getSubmissionsZip--TypeException: submittersName="
3257: + submittersName
3258: + " attachment reference="
3259: + r);
3260: } catch (IOException e) {
3261: M_log
3262: .debug(this
3263: + ": getSubmissionsZip--IOException: Problem in creating the attachment file: submittersName="
3264: + submittersName
3265: + " attachment reference="
3266: + r);
3267: } catch (ServerOverloadException e) {
3268: M_log
3269: .debug(this
3270: + ": getSubmissionsZip--ServerOverloadException: submittersName="
3271: + submittersName
3272: + " attachment reference="
3273: + r);
3274: }
3275: } // for
3276:
3277: added = true;
3278: } catch (IOException e) {
3279: exceptionMessage
3280: .append("Can not establish the IO to create zip file for user "
3281: + submittersName);
3282: M_log
3283: .debug(this
3284: + ": getSubmissionsZip--IOException unable to create the zip file for user"
3285: + submittersName);
3286: submittersName = submittersName
3287: .substring(
3288: 0,
3289: submittersName
3290: .length() - 1)
3291: + "_" + count++;
3292: }
3293: } // while
3294: } // if
3295: } // submitted
3296:
3297: } // while -- there is submission
3298:
3299: // Complete the ZIP file
3300: out.close();
3301: } catch (IOException e) {
3302: exceptionMessage
3303: .append("Can not establish the IO to create zip file. ");
3304: M_log
3305: .debug(this
3306: + ": getSubmissionsZip--IOException unable to create the zip file for assignment "
3307: + a.getTitle());
3308: }
3309:
3310: // return zip file content
3311: rv = b.getBytes();
3312: }
3313: } catch (IdUnusedException e) {
3314: if (M_log.isDebugEnabled())
3315: M_log
3316: .debug(this
3317: + ": getSubmissionsZip--IdUnusedException Unable to get assignment "
3318: + ref);
3319: throw new IdUnusedException(ref);
3320: } catch (PermissionException e) {
3321: M_log
3322: .debug(this
3323: + ": getSubmissionsZip--PermissionException Not permitted to get assignment "
3324: + ref);
3325: throw new PermissionException(SessionManager
3326: .getCurrentSessionUserId(),
3327: SECURE_ACCESS_ASSIGNMENT, ref);
3328: }
3329:
3330: return rv;
3331:
3332: } // getSubmissionsZip
3333:
3334: /**
3335: * Get the string to form an assignment grade spreadsheet
3336: *
3337: * @param context
3338: * The assignment context String
3339: * @param assignmentId
3340: * The id for the assignment object; when null, indicates all assignment in that context
3341: */
3342: public String gradesSpreadsheetReference(String context,
3343: String assignmentId) {
3344: // based on all assignment in that context
3345: String s = REFERENCE_ROOT + Entity.SEPARATOR + REF_TYPE_GRADES
3346: + Entity.SEPARATOR + context;
3347: if (assignmentId != null) {
3348: // based on the specified assignment only
3349: s = s.concat(Entity.SEPARATOR + assignmentId);
3350: }
3351:
3352: return s;
3353:
3354: } // gradesSpreadsheetReference
3355:
3356: /**
3357: * Get the string to form an assignment submissions zip file
3358: *
3359: * @param context
3360: * The assignment context String
3361: * @param assignmentReference
3362: * The reference for the assignment object;
3363: */
3364: public String submissionsZipReference(String context,
3365: String assignmentReference) {
3366: // based on the specified assignment
3367: return REFERENCE_ROOT + Entity.SEPARATOR + REF_TYPE_SUBMISSIONS
3368: + Entity.SEPARATOR + context + Entity.SEPARATOR
3369: + assignmentReference;
3370:
3371: } // submissionsZipReference
3372:
3373: /**
3374: * Decode the submissionsZipReference string to get the assignment reference String
3375: *
3376: * @param sReference
3377: * The submissionZipReference String
3378: * @return The assignment reference String
3379: */
3380: private String assignmentReferenceFromSubmissionsZipReference(
3381: String sReference) {
3382: // remove the String part relating to submissions zip reference
3383: return sReference.substring(sReference
3384: .lastIndexOf(Entity.SEPARATOR + "assignment"));
3385:
3386: } // assignmentReferenceFromSubmissionsZipReference
3387:
3388: /**********************************************************************************************************************************************************************************************************************************************************
3389: * ResourceService implementation
3390: *********************************************************************************************************************************************************************************************************************************************************/
3391:
3392: /**
3393: * {@inheritDoc}
3394: */
3395: public String getLabel() {
3396: return "assignment";
3397: }
3398:
3399: /**
3400: * {@inheritDoc}
3401: */
3402: public boolean willArchiveMerge() {
3403: return true;
3404: }
3405:
3406: /**
3407: * {@inheritDoc}
3408: */
3409: public HttpAccess getHttpAccess() {
3410: return new HttpAccess() {
3411: public void handleAccess(HttpServletRequest req,
3412: HttpServletResponse res, Reference ref,
3413: Collection copyrightAcceptedRefs)
3414: throws EntityPermissionException,
3415: EntityNotDefinedException,
3416: EntityAccessOverloadException,
3417: EntityCopyrightException {
3418: UsageSession session = UsageSessionService.getSession();
3419: if (session.getUserId() == null) {
3420: // fail the request, user not logged in yet.
3421: } else {
3422: try {
3423: if (REF_TYPE_SUBMISSIONS.equals(ref
3424: .getSubType())) {
3425: // get the submissions zip blob
3426: byte[] zip = getSubmissionsZip(ref
3427: .getReference());
3428:
3429: if (zip != null) {
3430: res.setContentType("application/zip");
3431: res
3432: .setHeader(
3433: "Content-Disposition",
3434: "attachment; filename = bulk_download.zip");
3435:
3436: OutputStream out = null;
3437: try {
3438: out = res.getOutputStream();
3439: out.write(zip);
3440: out.flush();
3441: out.close();
3442: } catch (Throwable ignore) {
3443: } finally {
3444: if (out != null) {
3445: try {
3446: out.close();
3447: } catch (Throwable ignore) {
3448: }
3449: }
3450: }
3451: }
3452: }
3453:
3454: else if (REF_TYPE_GRADES.equals(ref
3455: .getSubType())) {
3456: // get the grades spreadsheet blob
3457: byte[] spreadsheet = getGradesSpreadsheet(ref
3458: .getReference());
3459:
3460: if (spreadsheet != null) {
3461: res
3462: .setContentType("application/vnd.ms-excel");
3463: res
3464: .setHeader(
3465: "Content-Disposition",
3466: "attachment; filename = export_grades_file.xls");
3467:
3468: OutputStream out = null;
3469: try {
3470: out = res.getOutputStream();
3471: out.write(spreadsheet);
3472: out.flush();
3473: out.close();
3474: } catch (Throwable ignore) {
3475: } finally {
3476: if (out != null) {
3477: try {
3478: out.close();
3479: } catch (Throwable ignore) {
3480: }
3481: }
3482: }
3483: }
3484: } else {
3485: throw new IdUnusedException(ref
3486: .getReference());
3487: }
3488: } catch (Throwable t) {
3489: throw new EntityNotDefinedException(ref
3490: .getReference());
3491: }
3492: }
3493: }
3494: };
3495: }
3496:
3497: /**
3498: * {@inheritDoc}
3499: */
3500: public boolean parseEntityReference(String reference, Reference ref) {
3501: if (reference.startsWith(REFERENCE_ROOT)) {
3502: String id = null;
3503: String subType = null;
3504: String container = null;
3505: String context = null;
3506:
3507: String[] parts = StringUtil.split(reference,
3508: Entity.SEPARATOR);
3509: // we will get null, assignment, [a|c|s|grades|submissions], context, [auid], id
3510:
3511: if (parts.length > 2) {
3512: subType = parts[2];
3513:
3514: if (parts.length > 3) {
3515: // context is the container
3516: context = parts[3];
3517:
3518: // submissions have the assignment unique id as a container
3519: if ("s".equals(subType)) {
3520: if (parts.length > 5) {
3521: container = parts[4];
3522: id = parts[5];
3523: }
3524: }
3525:
3526: // others don't
3527: else {
3528: if (parts.length > 4) {
3529: id = parts[4];
3530: }
3531: }
3532: }
3533: }
3534:
3535: ref.set(APPLICATION_ID, subType, id, container, context);
3536:
3537: return true;
3538: }
3539:
3540: return false;
3541: }
3542:
3543: /**
3544: * {@inheritDoc}
3545: */
3546: public Entity getEntity(Reference ref) {
3547: return null;
3548: }
3549:
3550: /**
3551: * {@inheritDoc}
3552: */
3553: public Collection getEntityAuthzGroups(Reference ref, String userId) {
3554: Collection rv = new Vector();
3555:
3556: // for AssignmentService assignments:
3557: // if access set to SITE, use the assignment and site authzGroups.
3558: // if access set to GROUPED, use the assignment, and the groups, but not the site authzGroups.
3559: // if the user has SECURE_ALL_GROUPS in the context, ignore GROUPED access and treat as if SITE
3560:
3561: try {
3562: // for assignment
3563: if (REF_TYPE_ASSIGNMENT.equals(ref.getSubType())) {
3564: // assignment
3565: rv.add(ref.getReference());
3566:
3567: boolean grouped = false;
3568: Collection groups = null;
3569:
3570: // check SECURE_ALL_GROUPS - if not, check if the assignment has groups or not
3571: // TODO: the last param needs to be a ContextService.getRef(ref.getContext())... or a ref.getContextAuthzGroup() -ggolden
3572: if ((userId == null)
3573: || ((!SecurityService.isSuperUser(userId)) && (!AuthzGroupService
3574: .isAllowed(userId, SECURE_ALL_GROUPS,
3575: SiteService.siteReference(ref
3576: .getContext()))))) {
3577: // get the channel to get the message to get group information
3578: // TODO: check for efficiency, cache and thread local caching usage -ggolden
3579: if (ref.getId() != null) {
3580: Assignment a = findAssignment(ref
3581: .getReference());
3582: if (a != null) {
3583: grouped = Assignment.AssignmentAccess.GROUPED == a
3584: .getAccess();
3585: groups = a.getGroups();
3586: }
3587: }
3588: }
3589:
3590: if (grouped) {
3591: // groups
3592: rv.addAll(groups);
3593: }
3594:
3595: // not grouped
3596: else {
3597: // site
3598: ref.addSiteContextAuthzGroup(rv);
3599: }
3600: } else {
3601: rv.add(ref.getReference());
3602:
3603: // for content and submission, use site security setting
3604: ref.addSiteContextAuthzGroup(rv);
3605: }
3606: } catch (Throwable e) {
3607: M_log.warn("getEntityAuthzGroups(): " + e);
3608: }
3609:
3610: return rv;
3611: }
3612:
3613: /**
3614: * {@inheritDoc}
3615: */
3616: public String getEntityUrl(Reference ref) {
3617: return null;
3618: }
3619:
3620: /**
3621: * {@inheritDoc}
3622: */
3623: public String archive(String siteId, Document doc, Stack stack,
3624: String archivePath, List attachments) {
3625:
3626: // M_log.info("archive: stubbed");
3627: // prepare the buffer for the results log
3628: StringBuffer results = new StringBuffer();
3629:
3630: // String assignRef = assignmentReference(siteId, SiteService.MAIN_CONTAINER);
3631: results.append("archiving " + getLabel() + " context "
3632: + Entity.SEPARATOR + siteId + Entity.SEPARATOR
3633: + SiteService.MAIN_CONTAINER + ".\n");
3634:
3635: // start with an element with our very own (service) name
3636: Element element = doc.createElement(AssignmentService.class
3637: .getName());
3638: ((Element) stack.peek()).appendChild(element);
3639: stack.push(element);
3640:
3641: Iterator assignmentsIterator = getAssignmentsForContext(siteId);
3642:
3643: while (assignmentsIterator.hasNext()) {
3644: Assignment assignment = (Assignment) assignmentsIterator
3645: .next();
3646:
3647: // archive this assignment
3648: Element el = assignment.toXml(doc, stack);
3649: element.appendChild(el);
3650:
3651: // in order to make the assignment.xml have a better structure
3652: // the content id attribute removed from the assignment node
3653: // the content will be a child of assignment node
3654: el.removeAttribute("assignmentcontent");
3655:
3656: // then archive the related content
3657: AssignmentContent content = (AssignmentContent) assignment
3658: .getContent();
3659: if (content != null) {
3660: Element contentEl = content.toXml(doc, stack);
3661:
3662: // assignment node has already kept the context info
3663: contentEl.removeAttribute("context");
3664:
3665: // collect attachments
3666: List atts = content.getAttachments();
3667:
3668: for (int i = 0; i < atts.size(); i++) {
3669: Reference ref = (Reference) atts.get(i);
3670: // if it's in the attachment area, and not already in the list
3671: if ((ref.getReference()
3672: .startsWith("/content/attachment/"))
3673: && (!attachments.contains(ref))) {
3674: attachments.add(ref);
3675: }
3676:
3677: // in order to make assignment.xml has the consistent format with the other xml files
3678: // move the attachments to be the children of the content, instead of the attributes
3679: String attributeString = "attachment" + i;
3680: String attRelUrl = contentEl
3681: .getAttribute(attributeString);
3682: contentEl.removeAttribute(attributeString);
3683: Element attNode = doc.createElement("attachment");
3684: attNode.setAttribute("relative-url", attRelUrl);
3685: contentEl.appendChild(attNode);
3686:
3687: } // for
3688:
3689: // make the content a childnode of the assignment node
3690: el.appendChild(contentEl);
3691:
3692: Iterator submissionsIterator = getSubmissions(assignment);
3693: while (submissionsIterator.hasNext()) {
3694: AssignmentSubmission submission = (AssignmentSubmission) submissionsIterator
3695: .next();
3696:
3697: // archive this assignment
3698: Element submissionEl = submission.toXml(doc, stack);
3699: el.appendChild(submissionEl);
3700:
3701: }
3702: } // if
3703: } // while
3704:
3705: stack.pop();
3706:
3707: return results.toString();
3708:
3709: } // archive
3710:
3711: /**
3712: * Replace the WT user id with the new qualified id
3713: *
3714: * @param el
3715: * The XML element holding the perproties
3716: * @param useIdTrans
3717: * The HashMap to track old WT id to new CTools id
3718: */
3719: protected void WTUserIdTrans(Element el, Map userIdTrans) {
3720: NodeList children4 = el.getChildNodes();
3721: int length4 = children4.getLength();
3722: for (int i4 = 0; i4 < length4; i4++) {
3723: Node child4 = children4.item(i4);
3724: if (child4.getNodeType() == Node.ELEMENT_NODE) {
3725: Element element4 = (Element) child4;
3726: if (element4.getTagName().equals("property")) {
3727: String creatorId = "";
3728: String modifierId = "";
3729: if (element4.hasAttribute("CHEF:creator")) {
3730: if ("BASE64".equalsIgnoreCase(element4
3731: .getAttribute("enc"))) {
3732: creatorId = Xml.decodeAttribute(element4,
3733: "CHEF:creator");
3734: } else {
3735: creatorId = element4
3736: .getAttribute("CHEF:creator");
3737: }
3738: String newCreatorId = (String) userIdTrans
3739: .get(creatorId);
3740: if (newCreatorId != null) {
3741: Xml.encodeAttribute(element4,
3742: "CHEF:creator", newCreatorId);
3743: element4.setAttribute("enc", "BASE64");
3744: }
3745: } else if (element4.hasAttribute("CHEF:modifiedby")) {
3746: if ("BASE64".equalsIgnoreCase(element4
3747: .getAttribute("enc"))) {
3748: modifierId = Xml.decodeAttribute(element4,
3749: "CHEF:modifiedby");
3750: } else {
3751: modifierId = element4
3752: .getAttribute("CHEF:modifiedby");
3753: }
3754: String newModifierId = (String) userIdTrans
3755: .get(modifierId);
3756: if (newModifierId != null) {
3757: Xml.encodeAttribute(element4,
3758: "CHEF:creator", newModifierId);
3759: element4.setAttribute("enc", "BASE64");
3760: }
3761: }
3762: }
3763: }
3764: }
3765:
3766: } // WTUserIdTrans
3767:
3768: /**
3769: * {@inheritDoc}
3770: */
3771: public String merge(String siteId, Element root,
3772: String archivePath, String fromSiteId, Map attachmentNames,
3773: Map userIdTrans, Set userListAllowImport) {
3774: // prepare the buffer for the results log
3775: StringBuffer results = new StringBuffer();
3776:
3777: int count = 0;
3778:
3779: try {
3780: // pass the DOM to get new assignment ids, and adjust attachments
3781: NodeList children2 = root.getChildNodes();
3782:
3783: int length2 = children2.getLength();
3784: for (int i2 = 0; i2 < length2; i2++) {
3785: Node child2 = children2.item(i2);
3786: if (child2.getNodeType() == Node.ELEMENT_NODE) {
3787: Element element2 = (Element) child2;
3788:
3789: if (element2.getTagName().equals("assignment")) {
3790: // a flag showing if continuing merging the assignment
3791: boolean goAhead = true;
3792: AssignmentContentEdit contentEdit = null;
3793:
3794: // element2 now - assignment node
3795: // adjust the id of this assignment
3796: // String newId = IdManager.createUuid();
3797: element2.setAttribute("id", IdManager
3798: .createUuid());
3799: element2.setAttribute("context", siteId);
3800:
3801: // cloneNode(false) - no children cloned
3802: Element el2clone = (Element) element2
3803: .cloneNode(false);
3804:
3805: // traverse this assignment node first to check if the person who last modified, has the right role.
3806: // if no right role, mark the flag goAhead to be false.
3807: NodeList children3 = element2.getChildNodes();
3808: int length3 = children3.getLength();
3809: for (int i3 = 0; i3 < length3; i3++) {
3810: Node child3 = children3.item(i3);
3811: if (child3.getNodeType() == Node.ELEMENT_NODE) {
3812: Element element3 = (Element) child3;
3813:
3814: // add the properties childnode to the clone of assignment node
3815: if (element3.getTagName().equals(
3816: "properties")) {
3817: NodeList children6 = element3
3818: .getChildNodes();
3819: int length6 = children6.getLength();
3820: for (int i6 = 0; i6 < length6; i6++) {
3821: Node child6 = children6
3822: .item(i6);
3823: if (child6.getNodeType() == Node.ELEMENT_NODE) {
3824: Element element6 = (Element) child6;
3825:
3826: if (element6.getTagName()
3827: .equals("property")) {
3828: if (element6
3829: .getAttribute(
3830: "name")
3831: .equalsIgnoreCase(
3832: "CHEF:modifiedby")) {
3833: if ("BASE64"
3834: .equalsIgnoreCase(element6
3835: .getAttribute("enc"))) {
3836: String creatorId = Xml
3837: .decodeAttribute(
3838: element6,
3839: "value");
3840: if (!userListAllowImport
3841: .contains(creatorId))
3842: goAhead = false;
3843: } else {
3844: String creatorId = element6
3845: .getAttribute("value");
3846: if (!userListAllowImport
3847: .contains(creatorId))
3848: goAhead = false;
3849: }
3850: }
3851: }
3852: }
3853: }
3854: }
3855: }
3856: } // for
3857:
3858: // then, go ahead to merge the content and assignment
3859: if (goAhead) {
3860: for (int i3 = 0; i3 < length3; i3++) {
3861: Node child3 = children3.item(i3);
3862: if (child3.getNodeType() == Node.ELEMENT_NODE) {
3863: Element element3 = (Element) child3;
3864:
3865: // add the properties childnode to the clone of assignment node
3866: if (element3.getTagName().equals(
3867: "properties")) {
3868: // add the properties childnode to the clone of assignment node
3869: el2clone.appendChild(element3
3870: .cloneNode(true));
3871: } else if (element3.getTagName()
3872: .equals("content")) {
3873: // element3 now- content node
3874: // adjust the id of this content
3875: String newContentId = IdManager
3876: .createUuid();
3877: element3.setAttribute("id",
3878: newContentId);
3879: element3.setAttribute(
3880: "context", siteId);
3881:
3882: // clone the content node without the children of <properties>
3883: Element el3clone = (Element) element3
3884: .cloneNode(false);
3885:
3886: // update the assignmentcontent id in assignment node
3887: String assignContentId = "/assignment/c/"
3888: + siteId
3889: + "/"
3890: + newContentId;
3891: el2clone.setAttribute(
3892: "assignmentcontent",
3893: assignContentId);
3894:
3895: // for content node, process the attachment or properties kids
3896: NodeList children5 = element3
3897: .getChildNodes();
3898: int length5 = children5
3899: .getLength();
3900: int attCount = 0;
3901: for (int i5 = 0; i5 < length5; i5++) {
3902: Node child5 = children5
3903: .item(i5);
3904: if (child5.getNodeType() == Node.ELEMENT_NODE) {
3905: Element element5 = (Element) child5;
3906:
3907: // for the node of "properties"
3908: if (element5
3909: .getTagName()
3910: .equals(
3911: "properties")) {
3912: // for the file from WT, preform userId translation when needed
3913: if (!userIdTrans
3914: .isEmpty()) {
3915: WTUserIdTrans(
3916: element3,
3917: userIdTrans);
3918: }
3919: } // for the node of properties
3920: el3clone
3921: .appendChild(element5
3922: .cloneNode(true));
3923:
3924: // for "attachment" children
3925: if (element5
3926: .getTagName()
3927: .equals(
3928: "attachment")) {
3929: // map the attachment area folder name
3930: // filter out the invalid characters in the attachment id
3931: // map the attachment area folder name
3932: String oldUrl = element5
3933: .getAttribute("relative-url");
3934: String newUrl = "";
3935: if (oldUrl
3936: .startsWith("/content/attachment/")) {
3937: newUrl = (String) attachmentNames
3938: .get(oldUrl);
3939: if (newUrl != null) {
3940: if (newUrl
3941: .startsWith("/attachment/"))
3942: newUrl = "/content"
3943: .concat(newUrl);
3944:
3945: element5
3946: .setAttribute(
3947: "relative-url",
3948: Validator
3949: .escapeQuestionMark(newUrl));
3950: }
3951: }
3952:
3953: // map any references to this site to the new site id
3954: else if (oldUrl
3955: .startsWith("/content/group/"
3956: + fromSiteId
3957: + "/")) {
3958: newUrl = "/content/group/"
3959: + siteId
3960: + oldUrl
3961: .substring(15 + fromSiteId
3962: .length());
3963: element5
3964: .setAttribute(
3965: "relative-url",
3966: Validator
3967: .escapeQuestionMark(newUrl));
3968: }
3969: // put the attachment back to the attribute field of content
3970: // to satisfy the input need of mergeAssignmentContent
3971: String attachmentString = "attachment"
3972: + attCount;
3973: el3clone
3974: .setAttribute(
3975: attachmentString,
3976: newUrl);
3977: attCount++;
3978:
3979: } // if
3980: } // if
3981: } // for
3982:
3983: // create a newassignment content
3984: contentEdit = mergeAssignmentContent(el3clone);
3985: commitEdit(contentEdit);
3986: }
3987: }
3988: } // for
3989:
3990: el2clone.setAttribute("draft", "true");
3991:
3992: // merge in this assignment
3993: AssignmentEdit edit = mergeAssignment(el2clone);
3994: edit.setContent(contentEdit);
3995: commitEdit(edit);
3996:
3997: count++;
3998: } // if goAhead
3999: } // if
4000: } // if
4001: } // for
4002: } catch (Exception any) {
4003: M_log.warn("merge(): exception: ", any);
4004: }
4005:
4006: results.append("merging assignment " + siteId + " (" + count
4007: + ") assignments.\n");
4008: return results.toString();
4009:
4010: } // merge
4011:
4012: /**
4013: * {@inheritDoc}
4014: */
4015: public String[] myToolIds() {
4016: String[] toolIds = { "sakai.assignment",
4017: "sakai.assignment.grades" };
4018: return toolIds;
4019: }
4020:
4021: /**
4022: * {@inheritDoc}
4023: */
4024: public void transferCopyEntities(String fromContext,
4025: String toContext, List resourceIds) {
4026: // import Assignment objects
4027: Iterator oAssignments = getAssignmentsForContext(fromContext);
4028: while (oAssignments.hasNext()) {
4029: Assignment oAssignment = (Assignment) oAssignments.next();
4030: String oAssignmentId = oAssignment.getId();
4031:
4032: boolean toBeImported = true;
4033: if (resourceIds != null && resourceIds.size() > 0) {
4034: // if there is a list for import assignments, only import those assignments and relative submissions
4035: toBeImported = false;
4036: for (int m = 0; m < resourceIds.size() && !toBeImported; m++) {
4037: if (((String) resourceIds.get(m))
4038: .equals(oAssignmentId)) {
4039: toBeImported = true;
4040: }
4041: }
4042: }
4043:
4044: if (toBeImported) {
4045: AssignmentEdit nAssignment = null;
4046: AssignmentContentEdit nContent = null;
4047:
4048: if (!m_assignmentStorage.check(oAssignmentId)) {
4049:
4050: } else {
4051: try {
4052: // add new Assignment content
4053: String oContentReference = oAssignment
4054: .getContentReference();
4055: String oContentId = contentId(oContentReference);
4056: if (!m_contentStorage.check(oContentId))
4057: throw new IdUnusedException(oContentId);
4058: else {
4059: AssignmentContent oContent = getAssignmentContent(oContentReference);
4060: nContent = addAssignmentContent(toContext);
4061: // attributes
4062:
4063: nContent.setAllowAttachments(oContent
4064: .getAllowAttachments());
4065: nContent.setContext(toContext);
4066: nContent.setGroupProject(oContent
4067: .getGroupProject());
4068: nContent.setHonorPledge(oContent
4069: .getHonorPledge());
4070: nContent.setIndividuallyGraded(oContent
4071: .individuallyGraded());
4072: nContent.setInstructions(oContent
4073: .getInstructions());
4074: nContent.setMaxGradePoint(oContent
4075: .getMaxGradePoint());
4076: nContent.setReleaseGrades(oContent
4077: .releaseGrades());
4078: nContent.setTimeLastModified(oContent
4079: .getTimeLastModified());
4080: nContent.setTitle(oContent.getTitle());
4081: nContent.setTypeOfGrade(oContent
4082: .getTypeOfGrade());
4083: nContent.setTypeOfSubmission(oContent
4084: .getTypeOfSubmission());
4085: // properties
4086: ResourcePropertiesEdit p = nContent
4087: .getPropertiesEdit();
4088: p.clear();
4089: p.addAll(oContent.getProperties());
4090: // update live properties
4091: addLiveProperties(p);
4092: // attachment
4093: List oAttachments = oContent
4094: .getAttachments();
4095: List nAttachments = m_entityManager
4096: .newReferenceList();
4097: for (int n = 0; n < oAttachments.size(); n++) {
4098: Reference oAttachmentRef = (Reference) oAttachments
4099: .get(n);
4100: String oAttachmentId = ((Reference) oAttachments
4101: .get(n)).getId();
4102: if (oAttachmentId.indexOf(fromContext) != -1) {
4103: // replace old site id with new site id in attachments
4104: String nAttachmentId = oAttachmentId
4105: .replaceAll(fromContext,
4106: toContext);
4107: try {
4108: ContentResource attachment = ContentHostingService
4109: .getResource(nAttachmentId);
4110: nAttachments
4111: .add(m_entityManager
4112: .newReference(attachment
4113: .getReference()));
4114: } catch (IdUnusedException e) {
4115: try {
4116: ContentResource oAttachment = ContentHostingService
4117: .getResource(oAttachmentId);
4118: try {
4119: if (ContentHostingService
4120: .isAttachmentResource(nAttachmentId)) {
4121: // add the new resource into attachment collection area
4122: ContentResource attachment = ContentHostingService
4123: .addAttachmentResource(
4124: oAttachment
4125: .getProperties()
4126: .getProperty(
4127: ResourceProperties.PROP_DISPLAY_NAME),
4128: ToolManager
4129: .getCurrentPlacement()
4130: .getContext(),
4131: ToolManager
4132: .getTool(
4133: "sakai.assignment.grades")
4134: .getTitle(),
4135: oAttachment
4136: .getContentType(),
4137: oAttachment
4138: .getContent(),
4139: oAttachment
4140: .getProperties());
4141: // add to attachment list
4142: nAttachments
4143: .add(m_entityManager
4144: .newReference(attachment
4145: .getReference()));
4146: } else {
4147: // add the new resource into resource area
4148: ContentResource attachment = ContentHostingService
4149: .addResource(
4150: oAttachment
4151: .getProperties()
4152: .getProperty(
4153: ResourceProperties.PROP_DISPLAY_NAME),
4154: ToolManager
4155: .getCurrentPlacement()
4156: .getContext(),
4157: 1,
4158: oAttachment
4159: .getContentType(),
4160: oAttachment
4161: .getContent(),
4162: oAttachment
4163: .getProperties(),
4164: NotificationService.NOTI_NONE);
4165: // add to attachment list
4166: nAttachments
4167: .add(m_entityManager
4168: .newReference(attachment
4169: .getReference()));
4170: }
4171: } catch (Exception eeAny) {
4172: // if the new resource cannot be added
4173: M_log
4174: .warn(this
4175: + " cannot add new attachment with id="
4176: + nAttachmentId);
4177: }
4178: } catch (Exception eAny) {
4179: // if cannot find the original attachment, do nothing.
4180: M_log
4181: .warn(this
4182: + " cannot find the original attachment with id="
4183: + oAttachmentId);
4184: }
4185: } catch (Exception any) {
4186: M_log.warn(this
4187: + any.getMessage());
4188: }
4189: } else {
4190: nAttachments.add(oAttachmentRef);
4191: }
4192: }
4193: nContent.replaceAttachments(nAttachments);
4194: // complete the edit
4195: m_contentStorage.commit(nContent);
4196: ((BaseAssignmentContentEdit) nContent)
4197: .closeEdit();
4198: }
4199: } catch (Exception e) {
4200: if (M_log.isWarnEnabled())
4201: M_log.warn(this + e.toString());
4202: }
4203:
4204: if (nContent != null) {
4205: try {
4206: // add new assignment
4207: nAssignment = addAssignment(toContext);
4208: // attribute
4209: nAssignment.setCloseTime(oAssignment
4210: .getCloseTime());
4211: nAssignment.setContentReference(nContent
4212: .getReference());
4213: nAssignment.setContext(toContext);
4214: nAssignment.setDraft(true);
4215: nAssignment.setDropDeadTime(oAssignment
4216: .getDropDeadTime());
4217: nAssignment.setDueTime(oAssignment
4218: .getDueTime());
4219: nAssignment.setOpenTime(oAssignment
4220: .getOpenTime());
4221: nAssignment.setSection(oAssignment
4222: .getSection());
4223: nAssignment
4224: .setTitle(oAssignment.getTitle());
4225: // properties
4226: ResourcePropertiesEdit p = nAssignment
4227: .getPropertiesEdit();
4228: p.clear();
4229: p.addAll(oAssignment.getProperties());
4230: // update live properties
4231: addLiveProperties(p);
4232: // complete the edit
4233: m_assignmentStorage.commit(nAssignment);
4234: ((BaseAssignmentEdit) nAssignment)
4235: .closeEdit();
4236: } catch (Exception ee) {
4237: }
4238: }
4239: } // if-else
4240: } // if
4241: } // for
4242: } // importResources
4243:
4244: /**
4245: * {@inheritDoc}
4246: */
4247: public String getEntityDescription(Reference ref) {
4248: return null;
4249: }
4250:
4251: /**
4252: * {@inheritDoc}
4253: */
4254: public ResourceProperties getEntityResourceProperties(Reference ref) {
4255: return null;
4256: }
4257:
4258: /**********************************************************************************************************************************************************************************************************************************************************
4259: * Assignment Implementation
4260: *********************************************************************************************************************************************************************************************************************************************************/
4261:
4262: public class BaseAssignment implements Assignment {
4263: protected ResourcePropertiesEdit m_properties;
4264:
4265: protected String m_id;
4266:
4267: protected String m_assignmentContent;
4268:
4269: protected String m_title;
4270:
4271: protected String m_context;
4272:
4273: protected String m_section;
4274:
4275: protected Time m_openTime;
4276:
4277: protected Time m_dueTime;
4278:
4279: protected Time m_closeTime;
4280:
4281: protected Time m_dropDeadTime;
4282:
4283: protected List m_authors;
4284:
4285: protected boolean m_draft;
4286:
4287: /** The Collection of groups (authorization group id strings). */
4288: protected Collection m_groups = new Vector();
4289:
4290: /** The assignment access. */
4291: protected AssignmentAccess m_access = AssignmentAccess.SITE;
4292:
4293: /**
4294: * Copy constructor
4295: */
4296: public BaseAssignment(Assignment assignment) {
4297: setAll(assignment);
4298: }// copy constructor
4299:
4300: /**
4301: * Constructor used in addAssignment
4302: */
4303: public BaseAssignment(String id, String context) {
4304: m_properties = new BaseResourcePropertiesEdit();
4305: addLiveProperties(m_properties);
4306: m_id = id;
4307: m_assignmentContent = "";
4308: m_title = "";
4309: m_context = context;
4310: m_section = "";
4311: m_authors = new Vector();
4312: m_draft = true;
4313: m_groups = new Vector();
4314: }
4315:
4316: /**
4317: * Reads the Assignment's attribute values from xml.
4318: *
4319: * @param s -
4320: * Data structure holding the xml info.
4321: */
4322: public BaseAssignment(Element el) {
4323: if (M_log.isDebugEnabled())
4324: M_log
4325: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : ENTERING STORAGE CONSTRUCTOR");
4326:
4327: m_properties = new BaseResourcePropertiesEdit();
4328:
4329: int numAttributes = 0;
4330: String intString = null;
4331: String attributeString = null;
4332: String tempString = null;
4333:
4334: m_id = el.getAttribute("id");
4335: if (M_log.isDebugEnabled())
4336: M_log
4337: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : STORAGE CONSTRUCTOR : ASSIGNMENT ID : "
4338: + m_id);
4339: m_title = el.getAttribute("title");
4340: m_section = el.getAttribute("section");
4341: m_draft = getBool(el.getAttribute("draft"));
4342: if (M_log.isDebugEnabled())
4343: M_log
4344: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : STORAGE CONSTRUCTOR : READ THROUGH REG ATTS");
4345:
4346: m_assignmentContent = el.getAttribute("assignmentcontent");
4347: if (M_log.isDebugEnabled())
4348: M_log
4349: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : STORAGE CONSTRUCTOR : CONTENT ID : "
4350: + m_assignmentContent);
4351:
4352: m_openTime = getTimeObject(el.getAttribute("opendate"));
4353: m_dueTime = getTimeObject(el.getAttribute("duedate"));
4354: m_dropDeadTime = getTimeObject(el
4355: .getAttribute("dropdeaddate"));
4356: m_closeTime = getTimeObject(el.getAttribute("closedate"));
4357: m_context = el.getAttribute("context");
4358:
4359: // READ THE AUTHORS
4360: m_authors = new Vector();
4361: intString = el.getAttribute("numberofauthors");
4362: if (M_log.isDebugEnabled())
4363: M_log
4364: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : STORAGE CONSTRUCTOR : number of authors : "
4365: + intString);
4366: try {
4367: numAttributes = Integer.parseInt(intString);
4368:
4369: for (int x = 0; x < numAttributes; x++) {
4370: if (M_log.isDebugEnabled())
4371: M_log
4372: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : STORAGE CONSTRUCTOR : reading author # "
4373: + x);
4374: attributeString = "author" + x;
4375: tempString = el.getAttribute(attributeString);
4376:
4377: if (tempString != null) {
4378: if (M_log.isDebugEnabled())
4379: M_log
4380: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : STORAGE CONSTRUCTOR : adding author # "
4381: + x
4382: + " id : "
4383: + tempString);
4384: m_authors.add(tempString);
4385: }
4386: }
4387: } catch (Exception e) {
4388: M_log
4389: .warn("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : STORAGE CONSTRUCTOR : Exception reading authors : "
4390: + e);
4391: }
4392:
4393: // READ THE PROPERTIES AND INSTRUCTIONS
4394: NodeList children = el.getChildNodes();
4395: final int length = children.getLength();
4396: for (int i = 0; i < length; i++) {
4397: Node child = children.item(i);
4398: if (child.getNodeType() != Node.ELEMENT_NODE)
4399: continue;
4400: Element element = (Element) child;
4401:
4402: // look for properties
4403: if (element.getTagName().equals("properties")) {
4404: // re-create properties
4405: m_properties = new BaseResourcePropertiesEdit(
4406: element);
4407: }
4408:
4409: // look for an group
4410: else if (element.getTagName().equals("group")) {
4411: m_groups.add(element.getAttribute("authzGroup"));
4412: }
4413: }
4414:
4415: // extract access
4416: AssignmentAccess access = AssignmentAccess.fromString(el
4417: .getAttribute("access"));
4418: if (access != null) {
4419: m_access = access;
4420: }
4421:
4422: if (M_log.isDebugEnabled())
4423: M_log
4424: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : LEAVING STORAGE CONSTRUCTOR");
4425:
4426: }// storage constructor
4427:
4428: /**
4429: * Takes the Assignment's attribute values and puts them into the xml document.
4430: *
4431: * @param s -
4432: * Data structure holding the object to be stored.
4433: * @param doc -
4434: * The xml document.
4435: */
4436: public Element toXml(Document doc, Stack stack) {
4437: if (M_log.isDebugEnabled())
4438: M_log
4439: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : ENTERING TOXML");
4440:
4441: Element assignment = doc.createElement("assignment");
4442:
4443: if (stack.isEmpty()) {
4444: doc.appendChild(assignment);
4445: } else {
4446: ((Element) stack.peek()).appendChild(assignment);
4447: }
4448: stack.push(assignment);
4449:
4450: // SET ASSIGNMENT ATTRIBUTES
4451: String numItemsString = null;
4452: String attributeString = null;
4453: String itemString = null;
4454: assignment.setAttribute("id", m_id);
4455: assignment.setAttribute("title", m_title);
4456: assignment.setAttribute("section", m_section);
4457: assignment.setAttribute("context", m_context);
4458: assignment.setAttribute("assignmentcontent",
4459: m_assignmentContent);
4460: assignment.setAttribute("draft", getBoolString(m_draft));
4461: assignment.setAttribute("opendate",
4462: getTimeString(m_openTime));
4463: assignment
4464: .setAttribute("duedate", getTimeString(m_dueTime));
4465: assignment.setAttribute("dropdeaddate",
4466: getTimeString(m_dropDeadTime));
4467: assignment.setAttribute("closedate",
4468: getTimeString(m_closeTime));
4469:
4470: if (M_log.isDebugEnabled())
4471: M_log
4472: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : TOXML : saved regular properties");
4473:
4474: // SAVE THE AUTHORS
4475: numItemsString = "" + m_authors.size();
4476: if (M_log.isDebugEnabled())
4477: M_log
4478: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : TOXML : saving "
4479: + numItemsString + " authors");
4480:
4481: assignment.setAttribute("numberofauthors", numItemsString);
4482: for (int x = 0; x < m_authors.size(); x++) {
4483: attributeString = "author" + x;
4484: itemString = (String) m_authors.get(x);
4485: if (itemString != null) {
4486: assignment
4487: .setAttribute(attributeString, itemString);
4488: if (M_log.isDebugEnabled())
4489: M_log
4490: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : TOXML : saving author : "
4491: + itemString);
4492: }
4493: }
4494:
4495: // add groups
4496: if ((m_groups != null) && (m_groups.size() > 0)) {
4497: for (Iterator i = m_groups.iterator(); i.hasNext();) {
4498: String group = (String) i.next();
4499: Element sect = doc.createElement("group");
4500: assignment.appendChild(sect);
4501: sect.setAttribute("authzGroup", group);
4502: }
4503: }
4504:
4505: // add access
4506: assignment.setAttribute("access", m_access.toString());
4507:
4508: // SAVE THE PROPERTIES
4509: m_properties.toXml(doc, stack);
4510: M_log
4511: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : TOXML : SAVED PROPERTIES");
4512: stack.pop();
4513:
4514: if (M_log.isDebugEnabled())
4515: M_log
4516: .debug("ASSIGNMENT : BASE ASSIGNMENT : LEAVING TOXML");
4517:
4518: return assignment;
4519:
4520: }// toXml
4521:
4522: protected void setAll(Assignment assignment) {
4523: if (assignment != null) {
4524: m_id = assignment.getId();
4525: m_assignmentContent = assignment.getContentReference();
4526: m_authors = assignment.getAuthors();
4527: m_title = assignment.getTitle();
4528: m_context = assignment.getContext();
4529: m_section = assignment.getSection();
4530: m_openTime = assignment.getOpenTime();
4531: m_dueTime = assignment.getDueTime();
4532: m_closeTime = assignment.getCloseTime();
4533: m_dropDeadTime = assignment.getDropDeadTime();
4534: m_draft = assignment.getDraft();
4535: m_properties = new BaseResourcePropertiesEdit();
4536: m_properties.addAll(assignment.getProperties());
4537: m_groups = assignment.getGroups();
4538: m_access = assignment.getAccess();
4539: }
4540: }
4541:
4542: public String getId() {
4543: return m_id;
4544: }
4545:
4546: /**
4547: * Access the URL which can be used to access the resource.
4548: *
4549: * @return The URL which can be used to access the resource.
4550: */
4551: public String getUrl() {
4552: return getAccessPoint(false) + Entity.SEPARATOR + "a"
4553: + Entity.SEPARATOR + m_context + Entity.SEPARATOR
4554: + m_id;
4555:
4556: } // getUrl
4557:
4558: /**
4559: * Access the internal reference which can be used to access the resource from within the system.
4560: *
4561: * @return The the internal reference which can be used to access the resource from within the system.
4562: */
4563: public String getReference() {
4564: return assignmentReference(m_context, m_id);
4565:
4566: } // getReference
4567:
4568: /**
4569: * @inheritDoc
4570: */
4571: public String getReference(String rootProperty) {
4572: return getReference();
4573: }
4574:
4575: /**
4576: * @inheritDoc
4577: */
4578: public String getUrl(String rootProperty) {
4579: return getUrl();
4580: }
4581:
4582: /**
4583: * Access the resource's properties.
4584: *
4585: * @return The resource's properties.
4586: */
4587: public ResourceProperties getProperties() {
4588: return m_properties;
4589: }
4590:
4591: /**
4592: * Access the list of authors.
4593: *
4594: * @return FlexStringArray of user ids.
4595: */
4596: public List getAuthors() {
4597: return m_authors;
4598: }
4599:
4600: /**
4601: * Add an author to the author list.
4602: *
4603: * @param author -
4604: * The User to add to the author list.
4605: */
4606: public void addAuthor(User author) {
4607: if (author != null)
4608: m_authors.add(author.getId());
4609: }
4610:
4611: /**
4612: * Remove an author from the author list.
4613: *
4614: * @param author -
4615: * the User to remove from the author list.
4616: */
4617: public void removeAuthor(User author) {
4618: if (author != null)
4619: m_authors.remove(author.getId());
4620: }
4621:
4622: /**
4623: * Access the creator of this object.
4624: *
4625: * @return String The creator's user id.
4626: */
4627: public String getCreator() {
4628: return m_properties
4629: .getProperty(ResourceProperties.PROP_CREATOR);
4630: }
4631:
4632: /**
4633: * Access the person of last modificaiton
4634: *
4635: * @return the User's Id
4636: */
4637: public String getAuthorLastModified() {
4638: return m_properties
4639: .getProperty(ResourceProperties.PROP_MODIFIED_BY);
4640: }
4641:
4642: /**
4643: * Access the title.
4644: *
4645: * @return The Assignment's title.
4646: */
4647: public String getTitle() {
4648: return m_title;
4649: }
4650:
4651: /**
4652: * Access the time that this object was created.
4653: *
4654: * @return The Time object representing the time of creation.
4655: */
4656: public Time getTimeCreated() {
4657: try {
4658: return m_properties
4659: .getTimeProperty(ResourceProperties.PROP_CREATION_DATE);
4660: } catch (EntityPropertyNotDefinedException e) {
4661:
4662: } catch (EntityPropertyTypeException e) {
4663: }
4664: return null;
4665: }
4666:
4667: /**
4668: * Access the time of last modificaiton.
4669: *
4670: * @return The Time of last modification.
4671: */
4672: public Time getTimeLastModified() {
4673: try {
4674: return m_properties
4675: .getTimeProperty(ResourceProperties.PROP_MODIFIED_DATE);
4676: } catch (EntityPropertyNotDefinedException e) {
4677:
4678: } catch (EntityPropertyTypeException e) {
4679: }
4680: return null;
4681: }
4682:
4683: /**
4684: * Access the AssignmentContent of this Assignment.
4685: *
4686: * @return The Assignment's AssignmentContent.
4687: */
4688: public AssignmentContent getContent() {
4689: AssignmentContent retVal = null;
4690: if (m_assignmentContent != null) {
4691: try {
4692: retVal = getAssignmentContent(m_assignmentContent);
4693: } catch (Exception e) {
4694: }
4695: }
4696:
4697: return retVal;
4698: }
4699:
4700: /**
4701: * Access the reference of the AssignmentContent of this Assignment.
4702: *
4703: * @return The Assignment's reference.
4704: */
4705: public String getContentReference() {
4706: return m_assignmentContent;
4707: }
4708:
4709: /**
4710: * Access the id of the Assignment's group.
4711: *
4712: * @return The id of the group for which this Assignment is designed.
4713: */
4714: public String getContext() {
4715: return m_context;
4716: }
4717:
4718: /**
4719: * Access the section info
4720: *
4721: * @return The section String
4722: */
4723: public String getSection() {
4724: return m_section;
4725: }
4726:
4727: /**
4728: * Access the first time at which the assignment can be viewed; may be null.
4729: *
4730: * @return The Time at which the assignment is due, or null if unspecified.
4731: */
4732: public Time getOpenTime() {
4733: return m_openTime;
4734: }
4735:
4736: /**
4737: * Access the time at which the assignment is due; may be null.
4738: *
4739: * @return The Time at which the Assignment is due, or null if unspecified.
4740: */
4741: public Time getDueTime() {
4742: return m_dueTime;
4743: }
4744:
4745: /**
4746: * Access the drop dead time after which responses to this assignment are considered late; may be null.
4747: *
4748: * @return The Time object representing the drop dead time, or null if unspecified.
4749: */
4750: public Time getDropDeadTime() {
4751: return m_dropDeadTime;
4752: }
4753:
4754: /**
4755: * Access the close time after which this assignment can no longer be viewed, and after which submissions will not be accepted. May be null.
4756: *
4757: * @return The Time after which the Assignment is closed, or null if unspecified.
4758: */
4759: public Time getCloseTime() {
4760: return m_closeTime;
4761: }
4762:
4763: /**
4764: * Get whether this is a draft or final copy.
4765: *
4766: * @return True if this is a draft, false if it is a final copy.
4767: */
4768: public boolean getDraft() {
4769: return m_draft;
4770: }
4771:
4772: /**
4773: * @inheritDoc
4774: */
4775: public Collection getGroups() {
4776: return new Vector(m_groups);
4777: }
4778:
4779: /**
4780: * @inheritDoc
4781: */
4782: public AssignmentAccess getAccess() {
4783: return m_access;
4784: }
4785:
4786: /**
4787: * Are these objects equal? If they are both Assignment objects, and they have matching id's, they are.
4788: *
4789: * @return true if they are equal, false if not.
4790: */
4791: public boolean equals(Object obj) {
4792: if (!(obj instanceof Assignment))
4793: return false;
4794: return ((Assignment) obj).getId().equals(getId());
4795:
4796: } // equals
4797:
4798: /**
4799: * Make a hash code that reflects the equals() logic as well. We want two objects, even if different instances, if they have the same id to hash the same.
4800: */
4801: public int hashCode() {
4802: return getId().hashCode();
4803:
4804: } // hashCode
4805:
4806: /**
4807: * Compare this object with the specified object for order.
4808: *
4809: * @return A negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
4810: */
4811: public int compareTo(Object obj) {
4812: if (!(obj instanceof Assignment))
4813: throw new ClassCastException();
4814:
4815: // if the object are the same, say so
4816: if (obj == this )
4817: return 0;
4818:
4819: // start the compare by comparing their sort names
4820: int compare = getTitle().compareTo(
4821: ((Assignment) obj).getTitle());
4822:
4823: // if these are the same
4824: if (compare == 0) {
4825: // sort based on (unique) id
4826: compare = getId().compareTo(((Assignment) obj).getId());
4827: }
4828:
4829: return compare;
4830:
4831: } // compareTo
4832:
4833: } // BaseAssignment
4834:
4835: /**********************************************************************************************************************************************************************************************************************************************************
4836: * AssignmentEdit implementation
4837: *********************************************************************************************************************************************************************************************************************************************************/
4838:
4839: /**
4840: * <p>
4841: * BaseAssignmentEdit is an implementation of the CHEF AssignmentEdit object.
4842: * </p>
4843: *
4844: * @author University of Michigan, CHEF Software Development Team
4845: */
4846: public class BaseAssignmentEdit extends BaseAssignment implements
4847: AssignmentEdit, SessionBindingListener {
4848: /** The event code for this edit. */
4849: protected String m_event = null;
4850:
4851: /** Active flag. */
4852: protected boolean m_active = false;
4853:
4854: /**
4855: * Construct from another Assignment object.
4856: *
4857: * @param Assignment
4858: * The Assignment object to use for values.
4859: */
4860: public BaseAssignmentEdit(Assignment assignment) {
4861: super (assignment);
4862:
4863: } // BaseAssignmentEdit
4864:
4865: /**
4866: * Construct.
4867: *
4868: * @param id
4869: * The assignment id.
4870: */
4871: public BaseAssignmentEdit(String id, String context) {
4872: super (id, context);
4873:
4874: } // BaseAssignmentEdit
4875:
4876: /**
4877: * Construct from information in XML.
4878: *
4879: * @param el
4880: * The XML DOM Element definining the Assignment.
4881: */
4882: public BaseAssignmentEdit(Element el) {
4883: super (el);
4884:
4885: } // BaseAssignmentEdit
4886:
4887: /**
4888: * Clean up.
4889: */
4890: protected void finalize() {
4891: // catch the case where an edit was made but never resolved
4892: if (m_active) {
4893: cancelEdit(this );
4894: }
4895:
4896: } // finalize
4897:
4898: /**
4899: * Set the title.
4900: *
4901: * @param title -
4902: * The Assignment's title.
4903: */
4904: public void setTitle(String title) {
4905: m_title = title;
4906: }
4907:
4908: /**
4909: * Set the reference of the AssignmentContent of this Assignment.
4910: *
4911: * @param String -
4912: * the reference of the AssignmentContent.
4913: */
4914: public void setContentReference(String contentReference) {
4915: if (contentReference != null)
4916: m_assignmentContent = contentReference;
4917: }
4918:
4919: /**
4920: * Set the AssignmentContent of this Assignment.
4921: *
4922: * @param content -
4923: * the Assignment's AssignmentContent.
4924: */
4925: public void setContent(AssignmentContent content) {
4926: if (content != null)
4927: m_assignmentContent = content.getReference();
4928: }
4929:
4930: /**
4931: * Set the context at the time of creation.
4932: *
4933: * @param context -
4934: * the context string.
4935: */
4936: public void setContext(String context) {
4937: m_context = context;
4938: }
4939:
4940: /**
4941: * Set the section info
4942: *
4943: * @param sectionId -
4944: * The section id
4945: */
4946: public void setSection(String sectionId) {
4947: m_section = sectionId;
4948: }
4949:
4950: /**
4951: * Set the first time at which the assignment can be viewed; may be null.
4952: *
4953: * @param opentime -
4954: * The Time at which the Assignment opens.
4955: */
4956: public void setOpenTime(Time opentime) {
4957: m_openTime = opentime;
4958: }
4959:
4960: /**
4961: * Set the time at which the assignment is due; may be null.
4962: *
4963: * @param dueTime -
4964: * The Time at which the Assignment is due.
4965: */
4966: public void setDueTime(Time duetime) {
4967: m_dueTime = duetime;
4968: }
4969:
4970: /**
4971: * Set the drop dead time after which responses to this assignment are considered late; may be null.
4972: *
4973: * @param dropdeadtime -
4974: * The Time object representing the drop dead time.
4975: */
4976: public void setDropDeadTime(Time dropdeadtime) {
4977: m_dropDeadTime = dropdeadtime;
4978: }
4979:
4980: /**
4981: * Set the time after which this assignment can no longer be viewed, and after which submissions will not be accepted. May be null.
4982: *
4983: * @param closetime -
4984: * The Time after which the Assignment is closed, or null if unspecified.
4985: */
4986: public void setCloseTime(Time closetime) {
4987: m_closeTime = closetime;
4988: }
4989:
4990: /**
4991: * Set whether this is a draft or final copy.
4992: *
4993: * @param draft -
4994: * true if this is a draft, false if it is a final copy.
4995: */
4996: public void setDraft(boolean draft) {
4997: m_draft = draft;
4998: }
4999:
5000: /**
5001: * Take all values from this object.
5002: *
5003: * @param user
5004: * The user object to take values from.
5005: */
5006: protected void set(Assignment assignment) {
5007: setAll(assignment);
5008:
5009: } // set
5010:
5011: /**
5012: * Access the event code for this edit.
5013: *
5014: * @return The event code for this edit.
5015: */
5016: protected String getEvent() {
5017: return m_event;
5018: }
5019:
5020: /**
5021: * Set the event code for this edit.
5022: *
5023: * @param event
5024: * The event code for this edit.
5025: */
5026: protected void setEvent(String event) {
5027: m_event = event;
5028: }
5029:
5030: /**
5031: * Access the resource's properties for modification
5032: *
5033: * @return The resource's properties.
5034: */
5035: public ResourcePropertiesEdit getPropertiesEdit() {
5036: return m_properties;
5037:
5038: } // getPropertiesEdit
5039:
5040: /**
5041: * Enable editing.
5042: */
5043: protected void activate() {
5044: m_active = true;
5045:
5046: } // activate
5047:
5048: /**
5049: * Check to see if the edit is still active, or has already been closed.
5050: *
5051: * @return true if the edit is active, false if it's been closed.
5052: */
5053: public boolean isActiveEdit() {
5054: return m_active;
5055:
5056: } // isActiveEdit
5057:
5058: /**
5059: * Close the edit object - it cannot be used after this.
5060: */
5061: protected void closeEdit() {
5062: m_active = false;
5063:
5064: } // closeEdit
5065:
5066: /******************************************************************************************************************************************************************************************************************************************************
5067: * Group awareness implementation
5068: *****************************************************************************************************************************************************************************************************************************************************/
5069: /**
5070: * @inheritDoc
5071: */
5072: public void setAccess(AssignmentAccess access) {
5073: m_access = access;
5074: }
5075:
5076: /**
5077: * @inheritDoc
5078: */
5079: public void setGroupAccess(Collection groups)
5080: throws PermissionException {
5081: // convenience (and what else are we going to do?)
5082: if ((groups == null) || (groups.size() == 0)) {
5083: clearGroupAccess();
5084: return;
5085: }
5086:
5087: // is there any change? If we are already grouped, and the group list is the same, ignore the call
5088: if ((m_access == AssignmentAccess.GROUPED)
5089: && (EntityCollections.isEqualEntityRefsToEntities(
5090: m_groups, groups)))
5091: return;
5092:
5093: // there should not be a case where there's no context
5094: if (m_context == null) {
5095: M_log
5096: .warn("setGroupAccess() called with null context: "
5097: + getReference());
5098: throw new PermissionException(SessionManager
5099: .getCurrentSessionUserId(), "access:site",
5100: getReference());
5101: }
5102:
5103: // isolate any groups that would be removed or added
5104: Collection addedGroups = new Vector();
5105: Collection removedGroups = new Vector();
5106: EntityCollections
5107: .computeAddedRemovedEntityRefsFromNewEntitiesOldRefs(
5108: addedGroups, removedGroups, groups,
5109: m_groups);
5110:
5111: // verify that the user has permission to remove
5112: if (removedGroups.size() > 0) {
5113: // the Group objects the user has remove permission
5114: Collection allowedGroups = getGroupsAllowRemoveAssignment(m_context);
5115:
5116: for (Iterator i = removedGroups.iterator(); i.hasNext();) {
5117: String ref = (String) i.next();
5118:
5119: // is ref a group the user can remove from?
5120: if (!EntityCollections
5121: .entityCollectionContainsRefString(
5122: allowedGroups, ref)) {
5123: throw new PermissionException(SessionManager
5124: .getCurrentSessionUserId(),
5125: "access:group:remove", ref);
5126: }
5127: }
5128: }
5129:
5130: // verify that the user has permission to add in those contexts
5131: if (addedGroups.size() > 0) {
5132: // the Group objects the user has add permission
5133: Collection allowedGroups = getGroupsAllowAddAssignment(m_context);
5134:
5135: for (Iterator i = addedGroups.iterator(); i.hasNext();) {
5136: String ref = (String) i.next();
5137:
5138: // is ref a group the user can remove from?
5139: if (!EntityCollections
5140: .entityCollectionContainsRefString(
5141: allowedGroups, ref)) {
5142: throw new PermissionException(SessionManager
5143: .getCurrentSessionUserId(),
5144: "access:group:add", ref);
5145: }
5146: }
5147: }
5148:
5149: // we are clear to perform this
5150: m_access = AssignmentAccess.GROUPED;
5151: EntityCollections.setEntityRefsFromEntities(m_groups,
5152: groups);
5153: }
5154:
5155: /**
5156: * @inheritDoc
5157: */
5158: public void clearGroupAccess() throws PermissionException {
5159: // is there any change? If we are already site, ignore the call
5160: if (m_access == AssignmentAccess.SITE) {
5161: m_groups.clear();
5162: return;
5163: }
5164:
5165: if (m_context == null) {
5166: // there should not be a case where there's no context
5167: M_log
5168: .warn("clearGroupAccess() called with null context. "
5169: + getReference());
5170: throw new PermissionException(SessionManager
5171: .getCurrentSessionUserId(), "access:site",
5172: getReference());
5173: } else {
5174: // verify that the user has permission to add in the site context
5175: if (!allowAddSiteAssignment(m_context)) {
5176: throw new PermissionException(SessionManager
5177: .getCurrentSessionUserId(), "access:site",
5178: getReference());
5179: }
5180: }
5181:
5182: // we are clear to perform this
5183: m_access = AssignmentAccess.SITE;
5184: m_groups.clear();
5185:
5186: }
5187:
5188: /******************************************************************************************************************************************************************************************************************************************************
5189: * SessionBindingListener implementation
5190: *****************************************************************************************************************************************************************************************************************************************************/
5191:
5192: public void valueBound(SessionBindingEvent event) {
5193: }
5194:
5195: public void valueUnbound(SessionBindingEvent event) {
5196: if (M_log.isDebugEnabled())
5197: M_log.debug("valueUnbound()");
5198:
5199: // catch the case where an edit was made but never resolved
5200: if (m_active) {
5201: cancelEdit(this );
5202: }
5203:
5204: } // valueUnbound
5205:
5206: } // BaseAssignmentEdit
5207:
5208: /**********************************************************************************************************************************************************************************************************************************************************
5209: * AssignmentContent Implementation
5210: *********************************************************************************************************************************************************************************************************************************************************/
5211:
5212: public class BaseAssignmentContent implements AssignmentContent {
5213: protected ResourcePropertiesEdit m_properties;
5214:
5215: protected String m_id;
5216:
5217: protected String m_context;
5218:
5219: protected List m_attachments;
5220:
5221: protected List m_authors;
5222:
5223: protected String m_title;
5224:
5225: protected String m_instructions;
5226:
5227: protected int m_honorPledge;
5228:
5229: protected int m_typeOfSubmission;
5230:
5231: protected int m_typeOfGrade;
5232:
5233: protected int m_maxGradePoint;
5234:
5235: protected boolean m_groupProject;
5236:
5237: protected boolean m_individuallyGraded;
5238:
5239: protected boolean m_releaseGrades;
5240:
5241: protected boolean m_allowAttachments;
5242:
5243: protected Time m_timeCreated;
5244:
5245: protected Time m_timeLastModified;
5246:
5247: /**
5248: * Copy constructor.
5249: */
5250: public BaseAssignmentContent(AssignmentContent content) {
5251: setAll(content);
5252: }
5253:
5254: /**
5255: * Constructor used in addAssignmentContent.
5256: */
5257: public BaseAssignmentContent(String id, String context) {
5258: m_id = id;
5259: m_context = context;
5260: m_properties = new BaseResourcePropertiesEdit();
5261: addLiveProperties(m_properties);
5262: m_authors = new Vector();
5263: m_attachments = m_entityManager.newReferenceList();
5264: m_title = "";
5265: m_instructions = "";
5266: m_honorPledge = Assignment.HONOR_PLEDGE_NOT_SET;
5267: m_typeOfSubmission = Assignment.ASSIGNMENT_SUBMISSION_TYPE_NOT_SET;
5268: m_typeOfGrade = Assignment.GRADE_TYPE_NOT_SET;
5269: m_maxGradePoint = 0;
5270: m_timeCreated = TimeService.newTime();
5271: m_timeLastModified = TimeService.newTime();
5272: }
5273:
5274: /**
5275: * Reads the AssignmentContent's attribute values from xml.
5276: *
5277: * @param s -
5278: * Data structure holding the xml info.
5279: */
5280: public BaseAssignmentContent(Element el) {
5281: int numAttributes = 0;
5282: String intString = null;
5283: String attributeString = null;
5284: String tempString = null;
5285: Reference tempReference = null;
5286: if (M_log.isDebugEnabled())
5287: M_log
5288: .debug("DB : DbCachedAssignmentContent : Entering read");
5289:
5290: m_id = el.getAttribute("id");
5291: m_context = el.getAttribute("context");
5292: m_title = el.getAttribute("title");
5293: m_groupProject = getBool(el.getAttribute("groupproject"));
5294: m_individuallyGraded = getBool(el
5295: .getAttribute("indivgraded"));
5296: m_releaseGrades = getBool(el.getAttribute("releasegrades"));
5297: m_allowAttachments = getBool(el.getAttribute("allowattach"));
5298: m_timeCreated = getTimeObject(el
5299: .getAttribute("datecreated"));
5300: m_timeLastModified = getTimeObject(el
5301: .getAttribute("lastmod"));
5302:
5303: m_instructions = FormattedText
5304: .decodeFormattedTextAttribute(el, "instructions");
5305:
5306: try {
5307: m_honorPledge = Integer.parseInt(el
5308: .getAttribute("honorpledge"));
5309: } catch (Exception e) {
5310: M_log
5311: .warn(this
5312: + " Exception parsing honor pledge int from xml file string : "
5313: + e);
5314: }
5315:
5316: try {
5317: m_typeOfSubmission = Integer.parseInt(el
5318: .getAttribute("submissiontype"));
5319: } catch (Exception e) {
5320: M_log
5321: .warn(this
5322: + " Exception parsing submission type int from xml file string : "
5323: + e);
5324: }
5325:
5326: try {
5327: m_typeOfGrade = Integer.parseInt(el
5328: .getAttribute("typeofgrade"));
5329: } catch (Exception e) {
5330: M_log
5331: .warn(this
5332: + " Exception parsing grade type int from xml file string : "
5333: + e);
5334: }
5335:
5336: try {
5337: // %%%zqian
5338: // read the scaled max grade point first; if there is none, get the old max grade value and multiple by 10
5339: String maxGradePoint = StringUtil.trimToNull(el
5340: .getAttribute("scaled_maxgradepoint"));
5341: if (maxGradePoint == null) {
5342: maxGradePoint = StringUtil.trimToNull(el
5343: .getAttribute("maxgradepoint"));
5344: if (maxGradePoint != null) {
5345: maxGradePoint = maxGradePoint + "0";
5346: }
5347: }
5348: m_maxGradePoint = Integer.parseInt(maxGradePoint);
5349: } catch (Exception e) {
5350: M_log
5351: .warn(this
5352: + " Exception parsing maxgradepoint int from xml file string : "
5353: + e);
5354: }
5355:
5356: // READ THE AUTHORS
5357: m_authors = new Vector();
5358: intString = el.getAttribute("numberofauthors");
5359: try {
5360: numAttributes = Integer.parseInt(intString);
5361:
5362: for (int x = 0; x < numAttributes; x++) {
5363: attributeString = "author" + x;
5364: tempString = el.getAttribute(attributeString);
5365: if (tempString != null)
5366: m_authors.add(tempString);
5367: }
5368: } catch (Exception e) {
5369: M_log
5370: .warn("DB : DbCachedContent : Exception reading authors : "
5371: + e);
5372: }
5373:
5374: // READ THE ATTACHMENTS
5375: m_attachments = m_entityManager.newReferenceList();
5376: if (M_log.isDebugEnabled())
5377: M_log
5378: .debug("DB : DbCachedContent : Reading attachments : ");
5379: intString = el.getAttribute("numberofattachments");
5380: if (M_log.isDebugEnabled())
5381: M_log.debug("DB : DbCachedContent : num attachments : "
5382: + intString);
5383: try {
5384: numAttributes = Integer.parseInt(intString);
5385:
5386: for (int x = 0; x < numAttributes; x++) {
5387: attributeString = "attachment" + x;
5388: tempString = el.getAttribute(attributeString);
5389: if (tempString != null) {
5390: tempReference = m_entityManager
5391: .newReference(tempString);
5392: m_attachments.add(tempReference);
5393: if (M_log.isDebugEnabled())
5394: M_log.debug("DB : DbCachedContent : "
5395: + attributeString + " : "
5396: + tempString);
5397: }
5398: }
5399: } catch (Exception e) {
5400: M_log
5401: .warn("DB : DbCachedContent : Exception reading attachments : "
5402: + e);
5403: }
5404:
5405: // READ THE PROPERTIES
5406: NodeList children = el.getChildNodes();
5407: final int length = children.getLength();
5408: for (int i = 0; i < length; i++) {
5409: Node child = children.item(i);
5410: if (child.getNodeType() != Node.ELEMENT_NODE)
5411: continue;
5412: Element element = (Element) child;
5413:
5414: // look for properties
5415: if (element.getTagName().equals("properties")) {
5416: // re-create properties
5417: m_properties = new BaseResourcePropertiesEdit(
5418: element);
5419: }
5420: // old style of encoding
5421: else if (element.getTagName().equals(
5422: "instructions-html")
5423: || element.getTagName().equals(
5424: "instructions-formatted")
5425: || element.getTagName().equals("instructions")) {
5426: if ((element.getChildNodes() != null)
5427: && (element.getChildNodes().item(0) != null)) {
5428: m_instructions = element.getChildNodes()
5429: .item(0).getNodeValue();
5430: if (element.getTagName().equals("instructions"))
5431: m_instructions = FormattedText
5432: .convertPlaintextToFormattedText(m_instructions);
5433: if (element.getTagName().equals(
5434: "instructions-formatted"))
5435: m_instructions = FormattedText
5436: .convertOldFormattedText(m_instructions);
5437: if (M_log.isDebugEnabled())
5438: M_log
5439: .debug("XML : DbCachedAssignmentContent : instructions : "
5440: + m_instructions);
5441: }
5442: if (m_instructions == null) {
5443: m_instructions = "";
5444: }
5445: }
5446: }
5447:
5448: if (M_log.isDebugEnabled())
5449: M_log
5450: .debug("ASSIGNMENT : BASE SERVICE : BASE CONTENT : LEAVING STORAGE CONSTRUTOR");
5451:
5452: }// storage constructor
5453:
5454: /**
5455: * Takes the AssignmentContent's attribute values and puts them into the xml document.
5456: *
5457: * @param s -
5458: * Data structure holding the object to be stored.
5459: * @param doc -
5460: * The xml document.
5461: */
5462: public Element toXml(Document doc, Stack stack) {
5463: if (M_log.isDebugEnabled())
5464: M_log
5465: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : ENTERING TOXML");
5466:
5467: Element content = doc.createElement("content");
5468:
5469: if (stack.isEmpty()) {
5470: doc.appendChild(content);
5471: } else {
5472: ((Element) stack.peek()).appendChild(content);
5473: }
5474: stack.push(content);
5475:
5476: String numItemsString = null;
5477: String attributeString = null;
5478: String itemString = null;
5479: Reference tempReference = null;
5480:
5481: content.setAttribute("id", m_id);
5482: content.setAttribute("context", m_context);
5483: content.setAttribute("title", m_title);
5484: content.setAttribute("groupproject",
5485: getBoolString(m_groupProject));
5486: content.setAttribute("indivgraded",
5487: getBoolString(m_individuallyGraded));
5488: content.setAttribute("releasegrades",
5489: getBoolString(m_releaseGrades));
5490: content.setAttribute("allowattach",
5491: getBoolString(m_allowAttachments));
5492: content.setAttribute("honorpledge", String
5493: .valueOf(m_honorPledge));
5494: content.setAttribute("submissiontype", String
5495: .valueOf(m_typeOfSubmission));
5496: content.setAttribute("typeofgrade", String
5497: .valueOf(m_typeOfGrade));
5498: content.setAttribute("scaled_maxgradepoint", String
5499: .valueOf(m_maxGradePoint));
5500: content.setAttribute("datecreated",
5501: getTimeString(m_timeCreated));
5502: content.setAttribute("lastmod",
5503: getTimeString(m_timeLastModified));
5504:
5505: if (M_log.isDebugEnabled())
5506: M_log
5507: .debug("ASSIGNMENT : BASE SERVICE : BASE CONTENT : TOXML : SAVED REGULAR PROPERTIES");
5508:
5509: // SAVE THE AUTHORS
5510: numItemsString = "" + m_authors.size();
5511: content.setAttribute("numberofauthors", numItemsString);
5512: for (int x = 0; x < m_authors.size(); x++) {
5513: attributeString = "author" + x;
5514: itemString = (String) m_authors.get(x);
5515: if (itemString != null)
5516: content.setAttribute(attributeString, itemString);
5517: }
5518:
5519: if (M_log.isDebugEnabled())
5520: M_log
5521: .debug("ASSIGNMENT : BASE SERVICE : BASE CONTENT : TOXML : SAVED AUTHORS");
5522:
5523: // SAVE THE ATTACHMENTS
5524: numItemsString = "" + m_attachments.size();
5525: content.setAttribute("numberofattachments", numItemsString);
5526: for (int x = 0; x < m_attachments.size(); x++) {
5527: attributeString = "attachment" + x;
5528: tempReference = (Reference) m_attachments.get(x);
5529: itemString = tempReference.getReference();
5530: if (itemString != null)
5531: content.setAttribute(attributeString, itemString);
5532: }
5533:
5534: // SAVE THE PROPERTIES
5535: m_properties.toXml(doc, stack);
5536:
5537: if (M_log.isDebugEnabled())
5538: M_log
5539: .debug("ASSIGNMENT : BASE SERVICE : BASE CONTENT : TOXML : SAVED REGULAR PROPERTIES");
5540:
5541: stack.pop();
5542:
5543: // SAVE THE INSTRUCTIONS
5544: FormattedText.encodeFormattedTextAttribute(content,
5545: "instructions", m_instructions);
5546:
5547: return content;
5548:
5549: }// toXml
5550:
5551: protected void setAll(AssignmentContent content) {
5552: if (content != null) {
5553: m_id = content.getId();
5554: m_context = content.getContext();
5555: m_authors = content.getAuthors();
5556: m_attachments = content.getAttachments();
5557: m_title = content.getTitle();
5558: m_instructions = content.getInstructions();
5559: m_honorPledge = content.getHonorPledge();
5560: m_typeOfSubmission = content.getTypeOfSubmission();
5561: m_typeOfGrade = content.getTypeOfGrade();
5562: m_maxGradePoint = content.getMaxGradePoint();
5563: m_groupProject = content.getGroupProject();
5564: m_individuallyGraded = content.individuallyGraded();
5565: m_releaseGrades = content.releaseGrades();
5566: m_allowAttachments = content.getAllowAttachments();
5567: m_timeCreated = content.getTimeCreated();
5568: m_timeLastModified = content.getTimeLastModified();
5569: m_properties = new BaseResourcePropertiesEdit();
5570: m_properties.addAll(content.getProperties());
5571: }
5572: }
5573:
5574: public String getId() {
5575: return m_id;
5576: }
5577:
5578: /**
5579: * Access the URL which can be used to access the resource.
5580: *
5581: * @return The URL which can be used to access the resource.
5582: */
5583: public String getUrl() {
5584: return getAccessPoint(false) + Entity.SEPARATOR + "c"
5585: + Entity.SEPARATOR + m_context + Entity.SEPARATOR
5586: + m_id;
5587:
5588: } // getUrl
5589:
5590: /**
5591: * Access the internal reference which can be used to access the resource from within the system.
5592: *
5593: * @return The the internal reference which can be used to access the resource from within the system.
5594: */
5595: public String getReference() {
5596: return contentReference(m_context, m_id);
5597:
5598: } // getReference
5599:
5600: /**
5601: * @inheritDoc
5602: */
5603: public String getReference(String rootProperty) {
5604: return getReference();
5605: }
5606:
5607: /**
5608: * @inheritDoc
5609: */
5610: public String getUrl(String rootProperty) {
5611: return getUrl();
5612: }
5613:
5614: /**
5615: * Access the resource's properties.
5616: *
5617: * @return The resource's properties.
5618: */
5619: public ResourceProperties getProperties() {
5620: return m_properties;
5621: }
5622:
5623: /******************************************************************************************************************************************************************************************************************************************************
5624: * AttachmentContainer Implementation
5625: *****************************************************************************************************************************************************************************************************************************************************/
5626:
5627: /**
5628: * Access the attachments.
5629: *
5630: * @return The set of attachments (a ReferenceVector containing Reference objects) (may be empty).
5631: */
5632: public List getAttachments() {
5633: return m_attachments;
5634: }
5635:
5636: /******************************************************************************************************************************************************************************************************************************************************
5637: * AssignmentContent Implementation
5638: *****************************************************************************************************************************************************************************************************************************************************/
5639:
5640: /**
5641: * Access the AssignmentContent's context at the time of creation.
5642: *
5643: * @return String - the context string.
5644: */
5645: public String getContext() {
5646: return m_context;
5647: }
5648:
5649: /**
5650: * Access the list of authors.
5651: *
5652: * @return FlexStringArray of user ids.
5653: */
5654: public List getAuthors() {
5655: return m_authors;
5656: }
5657:
5658: /**
5659: * Access the creator of this object.
5660: *
5661: * @return The User object representing the creator.
5662: */
5663: public String getCreator() {
5664: return m_properties
5665: .getProperty(ResourceProperties.PROP_CREATOR);
5666: }
5667:
5668: /**
5669: * Access the person of last modificaiton
5670: *
5671: * @return the User
5672: */
5673: public String getAuthorLastModified() {
5674: return m_properties
5675: .getProperty(ResourceProperties.PROP_MODIFIED_BY);
5676: }
5677:
5678: /**
5679: * Access the title.
5680: *
5681: * @return The Assignment's title.
5682: */
5683: public String getTitle() {
5684: return m_title;
5685: }
5686:
5687: /**
5688: * Access the instructions.
5689: *
5690: * @return The Assignment Content's instructions.
5691: */
5692: public String getInstructions() {
5693: return m_instructions;
5694: }
5695:
5696: /**
5697: * Get the type of valid submission.
5698: *
5699: * @return int - Type of Submission.
5700: */
5701: public int getTypeOfSubmission() {
5702: return m_typeOfSubmission;
5703: }
5704:
5705: /**
5706: * Access a string describing the type of grade.
5707: *
5708: * @param gradeType -
5709: * The integer representing the type of grade.
5710: * @return Description of the type of grade.
5711: */
5712: public String getTypeOfGradeString(int type) {
5713: String retVal = null;
5714:
5715: switch (type) {
5716: case 1:
5717: retVal = Assignment.UNGRADED_GRADE_TYPE_STRING;
5718: break;
5719:
5720: case 2:
5721: retVal = Assignment.LETTER_GRADE_TYPE_STRING;
5722: break;
5723:
5724: case 3:
5725: retVal = Assignment.SCORE_GRADE_TYPE_STRING;
5726: break;
5727:
5728: case 4:
5729: retVal = Assignment.PASS_FAIL_GRADE_TYPE_STRING;
5730: break;
5731:
5732: case 5:
5733: retVal = Assignment.CHECK_GRADE_TYPE_STRING;
5734: break;
5735:
5736: default:
5737: retVal = "Unknown Grade Type";
5738: break;
5739: }
5740:
5741: return retVal;
5742: }
5743:
5744: /**
5745: * Get the grade type.
5746: *
5747: * @return gradeType - The type of grade.
5748: */
5749: public int getTypeOfGrade() {
5750: return m_typeOfGrade;
5751: }
5752:
5753: /**
5754: * Get the maximum grade for grade type = SCORE_GRADE_TYPE(3)
5755: *
5756: * @return The maximum grade score.
5757: */
5758: public int getMaxGradePoint() {
5759: return m_maxGradePoint;
5760: }
5761:
5762: /**
5763: * Get the maximum grade for grade type = SCORE_GRADE_TYPE(3) Formated to show one decimal place
5764: *
5765: * @return The maximum grade score.
5766: */
5767: public String getMaxGradePointDisplay() {
5768: // formated to show one decimal place, for example, 1000 to 100.0
5769: String one_decimal_maxGradePoint = m_maxGradePoint / 10
5770: + "." + (m_maxGradePoint % 10);
5771: return one_decimal_maxGradePoint;
5772: }
5773:
5774: /**
5775: * Get whether this project can be a group project.
5776: *
5777: * @return True if this can be a group project, false otherwise.
5778: */
5779: public boolean getGroupProject() {
5780: return m_groupProject;
5781: }
5782:
5783: /**
5784: * Get whether group projects should be individually graded.
5785: *
5786: * @return individGraded - true if projects are individually graded, false if grades are given to the group.
5787: */
5788: public boolean individuallyGraded() {
5789: return m_individuallyGraded;
5790: }
5791:
5792: /**
5793: * Gets whether grades can be released once submissions are graded.
5794: *
5795: * @return true if grades can be released once submission are graded, false if they must be released manually.
5796: */
5797: public boolean releaseGrades() {
5798: return m_releaseGrades;
5799: }
5800:
5801: /**
5802: * Get the Honor Pledge type; values are NONE and ENGINEERING_HONOR_PLEDGE.
5803: *
5804: * @return the Honor Pledge value.
5805: */
5806: public int getHonorPledge() {
5807: return m_honorPledge;
5808: }
5809:
5810: /**
5811: * Does this Assignment allow attachments?
5812: *
5813: * @return true if the Assignment allows attachments, false otherwise?
5814: */
5815: public boolean getAllowAttachments() {
5816: return m_allowAttachments;
5817: }
5818:
5819: /**
5820: * Access the time that this object was created.
5821: *
5822: * @return The Time object representing the time of creation.
5823: */
5824: public Time getTimeCreated() {
5825: return m_timeCreated;
5826: }
5827:
5828: /**
5829: * Access the time of last modificaiton.
5830: *
5831: * @return The Time of last modification.
5832: */
5833: public Time getTimeLastModified() {
5834: return m_timeLastModified;
5835: }
5836:
5837: /**
5838: * Is this AssignmentContent selected for use by an Assignment ?
5839: */
5840: public boolean inUse() {
5841: boolean retVal = false;
5842: Assignment assignment = null;
5843: List allAssignments = getAssignments(m_context);
5844: for (int x = 0; x < allAssignments.size(); x++) {
5845: assignment = (Assignment) allAssignments.get(x);
5846: if (assignment.getContentReference().equals(
5847: getReference()))
5848: return true;
5849: }
5850:
5851: return retVal;
5852: }
5853:
5854: /**
5855: * Are these objects equal? If they are both AssignmentContent objects, and they have matching id's, they are.
5856: *
5857: * @return true if they are equal, false if not.
5858: */
5859: public boolean equals(Object obj) {
5860: if (!(obj instanceof AssignmentContent))
5861: return false;
5862: return ((AssignmentContent) obj).getId().equals(getId());
5863:
5864: } // equals
5865:
5866: /**
5867: * Make a hash code that reflects the equals() logic as well. We want two objects, even if different instances, if they have the same id to hash the same.
5868: */
5869: public int hashCode() {
5870: return getId().hashCode();
5871:
5872: } // hashCode
5873:
5874: /**
5875: * Compare this object with the specified object for order.
5876: *
5877: * @return A negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
5878: */
5879: public int compareTo(Object obj) {
5880: if (!(obj instanceof AssignmentContent))
5881: throw new ClassCastException();
5882:
5883: // if the object are the same, say so
5884: if (obj == this )
5885: return 0;
5886:
5887: // start the compare by comparing their sort names
5888: int compare = getTitle().compareTo(
5889: ((AssignmentContent) obj).getTitle());
5890:
5891: // if these are the same
5892: if (compare == 0) {
5893: // sort based on (unique) id
5894: compare = getId().compareTo(
5895: ((AssignmentContent) obj).getId());
5896: }
5897:
5898: return compare;
5899:
5900: } // compareTo
5901:
5902: }// BaseAssignmentContent
5903:
5904: /**********************************************************************************************************************************************************************************************************************************************************
5905: * AssignmentContentEdit implementation
5906: *********************************************************************************************************************************************************************************************************************************************************/
5907:
5908: /**
5909: * <p>
5910: * BaseAssignmentContentEdit is an implementation of the CHEF AssignmentContentEdit object.
5911: * </p>
5912: *
5913: * @author University of Michigan, CHEF Software Development Team
5914: */
5915: public class BaseAssignmentContentEdit extends
5916: BaseAssignmentContent implements AttachmentContainer,
5917: AssignmentContentEdit, SessionBindingListener {
5918: /** The event code for this edit. */
5919: protected String m_event = null;
5920:
5921: /** Active flag. */
5922: protected boolean m_active = false;
5923:
5924: /**
5925: * Construct from another AssignmentContent object.
5926: *
5927: * @param AssignmentContent
5928: * The AssignmentContent object to use for values.
5929: */
5930: public BaseAssignmentContentEdit(
5931: AssignmentContent assignmentContent) {
5932: super (assignmentContent);
5933:
5934: } // BaseAssignmentContentEdit
5935:
5936: /**
5937: * Construct.
5938: *
5939: * @param id
5940: * The AssignmentContent id.
5941: */
5942: public BaseAssignmentContentEdit(String id, String context) {
5943: super (id, context);
5944:
5945: } // BaseAssignmentContentEdit
5946:
5947: /**
5948: * Construct from information in XML.
5949: *
5950: * @param el
5951: * The XML DOM Element definining the AssignmentContent.
5952: */
5953: public BaseAssignmentContentEdit(Element el) {
5954: super (el);
5955:
5956: } // BaseAssignmentContentEdit
5957:
5958: /**
5959: * Clean up.
5960: */
5961: protected void finalize() {
5962: // catch the case where an edit was made but never resolved
5963: if (m_active) {
5964: cancelEdit(this );
5965: }
5966:
5967: } // finalize
5968:
5969: /******************************************************************************************************************************************************************************************************************************************************
5970: * AttachmentContainer Implementation
5971: *****************************************************************************************************************************************************************************************************************************************************/
5972:
5973: /**
5974: * Add an attachment.
5975: *
5976: * @param ref -
5977: * The attachment Reference.
5978: */
5979: public void addAttachment(Reference ref) {
5980: if (ref != null)
5981: m_attachments.add(ref);
5982: }
5983:
5984: /**
5985: * Remove an attachment.
5986: *
5987: * @param ref -
5988: * The attachment Reference to remove (the one removed will equal this, they need not be ==).
5989: */
5990: public void removeAttachment(Reference ref) {
5991: if (ref != null)
5992: m_attachments.remove(ref);
5993: }
5994:
5995: /**
5996: * Replace the attachment set.
5997: *
5998: * @param attachments -
5999: * A ReferenceVector that will become the new set of attachments.
6000: */
6001: public void replaceAttachments(List attachments) {
6002: m_attachments = attachments;
6003: }
6004:
6005: /**
6006: * Clear all attachments.
6007: */
6008: public void clearAttachments() {
6009: m_attachments.clear();
6010: }
6011:
6012: /******************************************************************************************************************************************************************************************************************************************************
6013: * AssignmentContentEdit Implementation
6014: *****************************************************************************************************************************************************************************************************************************************************/
6015:
6016: /**
6017: * Set the title.
6018: *
6019: * @param title -
6020: * The Assignment's title.
6021: */
6022: public void setTitle(String title) {
6023: m_title = title;
6024: }
6025:
6026: /**
6027: * Set the instructions.
6028: *
6029: * @param instructions -
6030: * The Assignment's instructions.
6031: */
6032: public void setInstructions(String instructions) {
6033: m_instructions = instructions;
6034: }
6035:
6036: /**
6037: * Set the context at the time of creation.
6038: *
6039: * @param context -
6040: * the context string.
6041: */
6042: public void setContext(String context) {
6043: m_context = context;
6044: }
6045:
6046: /**
6047: * Set the type of valid submission.
6048: *
6049: * @param int -
6050: * Type of Submission.
6051: */
6052: public void setTypeOfSubmission(int type) {
6053: m_typeOfSubmission = type;
6054: }
6055:
6056: /**
6057: * Set the grade type.
6058: *
6059: * @param gradeType -
6060: * The type of grade.
6061: */
6062: public void setTypeOfGrade(int gradeType) {
6063: m_typeOfGrade = gradeType;
6064: }
6065:
6066: /**
6067: * Set the maximum grade for grade type = SCORE_GRADE_TYPE(3)
6068: *
6069: * @param maxPoints -
6070: * The maximum grade score.
6071: */
6072: public void setMaxGradePoint(int maxPoints) {
6073: m_maxGradePoint = maxPoints;
6074: }
6075:
6076: /**
6077: * Set whether this project can be a group project.
6078: *
6079: * @param groupProject -
6080: * True if this can be a group project, false otherwise.
6081: */
6082: public void setGroupProject(boolean groupProject) {
6083: m_groupProject = groupProject;
6084: }
6085:
6086: /**
6087: * Set whether group projects should be individually graded.
6088: *
6089: * @param individGraded -
6090: * true if projects are individually graded, false if grades are given to the group.
6091: */
6092: public void setIndividuallyGraded(boolean individGraded) {
6093: m_individuallyGraded = individGraded;
6094: }
6095:
6096: /**
6097: * Sets whether grades can be released once submissions are graded.
6098: *
6099: * @param release -
6100: * true if grades can be released once submission are graded, false if they must be released manually.
6101: */
6102: public void setReleaseGrades(boolean release) {
6103: m_releaseGrades = release;
6104: }
6105:
6106: /**
6107: * Set the Honor Pledge type; values are NONE and ENGINEERING_HONOR_PLEDGE.
6108: *
6109: * @param pledgeType -
6110: * the Honor Pledge value.
6111: */
6112: public void setHonorPledge(int pledgeType) {
6113: m_honorPledge = pledgeType;
6114: }
6115:
6116: /**
6117: * Does this Assignment allow attachments?
6118: *
6119: * @param allow -
6120: * true if the Assignment allows attachments, false otherwise?
6121: */
6122: public void setAllowAttachments(boolean allow) {
6123: m_allowAttachments = allow;
6124: }
6125:
6126: /**
6127: * Add an author to the author list.
6128: *
6129: * @param author -
6130: * The User to add to the author list.
6131: */
6132: public void addAuthor(User author) {
6133: if (author != null)
6134: m_authors.add(author.getId());
6135: }
6136:
6137: /**
6138: * Remove an author from the author list.
6139: *
6140: * @param author -
6141: * the User to remove from the author list.
6142: */
6143: public void removeAuthor(User author) {
6144: if (author != null)
6145: m_authors.remove(author.getId());
6146: }
6147:
6148: /**
6149: * Set the time last modified.
6150: *
6151: * @param lastmod -
6152: * The Time at which the Content was last modified.
6153: */
6154: public void setTimeLastModified(Time lastmod) {
6155: if (lastmod != null)
6156: m_timeLastModified = lastmod;
6157: }
6158:
6159: /**
6160: * Take all values from this object.
6161: *
6162: * @param AssignmentContent
6163: * The AssignmentContent object to take values from.
6164: */
6165: protected void set(AssignmentContent assignmentContent) {
6166: setAll(assignmentContent);
6167:
6168: } // set
6169:
6170: /**
6171: * Access the event code for this edit.
6172: *
6173: * @return The event code for this edit.
6174: */
6175: protected String getEvent() {
6176: return m_event;
6177: }
6178:
6179: /**
6180: * Set the event code for this edit.
6181: *
6182: * @param event
6183: * The event code for this edit.
6184: */
6185: protected void setEvent(String event) {
6186: m_event = event;
6187: }
6188:
6189: /**
6190: * Access the resource's properties for modification
6191: *
6192: * @return The resource's properties.
6193: */
6194: public ResourcePropertiesEdit getPropertiesEdit() {
6195: return m_properties;
6196:
6197: } // getPropertiesEdit
6198:
6199: /**
6200: * Enable editing.
6201: */
6202: protected void activate() {
6203: m_active = true;
6204:
6205: } // activate
6206:
6207: /**
6208: * Check to see if the edit is still active, or has already been closed.
6209: *
6210: * @return true if the edit is active, false if it's been closed.
6211: */
6212: public boolean isActiveEdit() {
6213: return m_active;
6214:
6215: } // isActiveEdit
6216:
6217: /**
6218: * Close the edit object - it cannot be used after this.
6219: */
6220: protected void closeEdit() {
6221: m_active = false;
6222:
6223: } // closeEdit
6224:
6225: /******************************************************************************************************************************************************************************************************************************************************
6226: * SessionBindingListener implementation
6227: *****************************************************************************************************************************************************************************************************************************************************/
6228:
6229: public void valueBound(SessionBindingEvent event) {
6230: }
6231:
6232: public void valueUnbound(SessionBindingEvent event) {
6233: if (M_log.isDebugEnabled())
6234: M_log.debug("valueUnbound()");
6235:
6236: // catch the case where an edit was made but never resolved
6237: if (m_active) {
6238: cancelEdit(this );
6239: }
6240:
6241: } // valueUnbound
6242:
6243: } // BaseAssignmentContentEdit
6244:
6245: /**********************************************************************************************************************************************************************************************************************************************************
6246: * AssignmentSubmission implementation
6247: *********************************************************************************************************************************************************************************************************************************************************/
6248:
6249: public class BaseAssignmentSubmission implements
6250: AssignmentSubmission {
6251: protected final String STATUS_DRAFT = "Drafted";
6252:
6253: protected final String STATUS_SUBMITTED = "Submitted";
6254:
6255: protected final String STATUS_RETURNED = "Returned";
6256:
6257: protected final String STATUS_GRADED = "Graded";
6258:
6259: protected ResourcePropertiesEdit m_properties;
6260:
6261: protected String m_id;
6262:
6263: protected String m_assignment;
6264:
6265: protected String m_context;
6266:
6267: protected List m_submitters;
6268:
6269: protected Time m_timeSubmitted;
6270:
6271: protected Time m_timeReturned;
6272:
6273: protected Time m_timeLastModified;
6274:
6275: protected List m_submittedAttachments;
6276:
6277: protected List m_feedbackAttachments;
6278:
6279: protected String m_submittedText;
6280:
6281: protected String m_feedbackComment;
6282:
6283: protected String m_feedbackText;
6284:
6285: protected String m_grade;
6286:
6287: protected boolean m_submitted;
6288:
6289: protected boolean m_returned;
6290:
6291: protected boolean m_graded;
6292:
6293: protected boolean m_gradeReleased;
6294:
6295: protected boolean m_honorPledgeFlag;
6296:
6297: /**
6298: * Copy constructor.
6299: */
6300: public BaseAssignmentSubmission(AssignmentSubmission submission) {
6301: setAll(submission);
6302: }
6303:
6304: /**
6305: * Constructor used by addSubmission.
6306: */
6307: public BaseAssignmentSubmission(String id, String context,
6308: String assignId) {
6309: m_id = id;
6310: m_context = context;
6311: m_assignment = assignId;
6312: m_properties = new BaseResourcePropertiesEdit();
6313: addLiveProperties(m_properties);
6314: m_submitters = new Vector();
6315: m_feedbackAttachments = m_entityManager.newReferenceList();
6316: m_submittedAttachments = m_entityManager.newReferenceList();
6317: m_submitted = false;
6318: m_returned = false;
6319: m_graded = false;
6320: m_gradeReleased = false;
6321: m_submittedText = "";
6322: m_feedbackComment = "";
6323: m_feedbackText = "";
6324: m_grade = "";
6325: m_timeLastModified = TimeService.newTime();
6326:
6327: String currentUser = SessionManager
6328: .getCurrentSessionUserId();
6329: if (currentUser == null)
6330: currentUser = "";
6331: m_submitters.add(currentUser);
6332: }
6333:
6334: /**
6335: * Reads the AssignmentSubmission's attribute values from xml.
6336: *
6337: * @param s -
6338: * Data structure holding the xml info.
6339: */
6340: public BaseAssignmentSubmission(Element el) {
6341: int numAttributes = 0;
6342: String intString = null;
6343: String attributeString = null;
6344: String tempString = null;
6345: Reference tempReference = null;
6346:
6347: if (M_log.isDebugEnabled())
6348: M_log
6349: .debug("ASSIGNMENT : BASE SERVICE : BASE SUB : ENTERING STORAGE CONSTRUCTOR");
6350:
6351: m_id = el.getAttribute("id");
6352: // M_log.info("ASSIGNMENT : BASE SERVICE : BASE SUBMISSION : CONSTRUCTOR : m_id : " + m_id);
6353: m_context = el.getAttribute("context");
6354: // M_log.info("ASSIGNMENT : BASE SERVICE : BASE SUBMISSION : CONSTRUCTOR : m_context : " + m_context);
6355:
6356: // %%%zqian
6357: // read the scaled grade point first; if there is none, get the old grade value
6358: String grade = StringUtil.trimToNull(el
6359: .getAttribute("scaled_grade"));
6360: if (grade == null) {
6361: grade = StringUtil.trimToNull(el.getAttribute("grade"));
6362: if (grade != null) {
6363: try {
6364: Integer.parseInt(grade);
6365: // for the grades in points, multiple those by 10
6366: grade = grade + "0";
6367: } catch (Exception e) {
6368: }
6369: }
6370: }
6371: m_grade = grade;
6372:
6373: // M_log.info("ASSIGNMENT : BASE SERVICE : BASE SUBMISSION : CONSTRUCTOR : m_grade : " + m_grade);
6374: m_assignment = el.getAttribute("assignment");
6375: // M_log.info("ASSIGNMENT : BASE SERVICE : BASE SUBMISSION : CONSTRUCTOR : m_assignment : " + m_assignment);
6376:
6377: m_timeSubmitted = getTimeObject(el
6378: .getAttribute("datesubmitted"));
6379: m_timeReturned = getTimeObject(el
6380: .getAttribute("datereturned"));
6381: m_assignment = el.getAttribute("assignment");
6382: m_timeLastModified = getTimeObject(el
6383: .getAttribute("lastmod"));
6384:
6385: m_submitted = getBool(el.getAttribute("submitted"));
6386: m_returned = getBool(el.getAttribute("returned"));
6387: m_graded = getBool(el.getAttribute("graded"));
6388: m_gradeReleased = getBool(el.getAttribute("gradereleased"));
6389: m_honorPledgeFlag = getBool(el.getAttribute("pledgeflag"));
6390:
6391: m_submittedText = FormattedText
6392: .decodeFormattedTextAttribute(el, "submittedtext");
6393: m_feedbackComment = FormattedText
6394: .decodeFormattedTextAttribute(el, "feedbackcomment");
6395: m_feedbackText = FormattedText
6396: .decodeFormattedTextAttribute(el, "feedbacktext");
6397:
6398: // READ THE SUBMITTERS
6399: m_submitters = new Vector();
6400: if (M_log.isDebugEnabled())
6401: M_log
6402: .debug("ASSIGNMENT : BASE SERVICE : BASE SUB : CONSTRUCTOR : Reading submitters : ");
6403: intString = el.getAttribute("numberofsubmitters");
6404: try {
6405: numAttributes = Integer.parseInt(intString);
6406:
6407: for (int x = 0; x < numAttributes; x++) {
6408: attributeString = "submitter" + x;
6409: tempString = el.getAttribute(attributeString);
6410: if (tempString != null)
6411: m_submitters.add(tempString);
6412: }
6413: } catch (Exception e) {
6414: M_log
6415: .warn("ASSIGNMENT : BASE SERVICE : BASE SUB : CONSTRUCTOR : Exception reading submitters : "
6416: + e);
6417: }
6418:
6419: // READ THE FEEDBACK ATTACHMENTS
6420: m_feedbackAttachments = m_entityManager.newReferenceList();
6421: intString = el.getAttribute("numberoffeedbackattachments");
6422: if (M_log.isDebugEnabled())
6423: M_log
6424: .debug("ASSIGNMENT : BASE SERVICE : BASE SUB : CONSTRUCTOR : num feedback attachments : "
6425: + intString);
6426: try {
6427: numAttributes = Integer.parseInt(intString);
6428:
6429: for (int x = 0; x < numAttributes; x++) {
6430: attributeString = "feedbackattachment" + x;
6431: tempString = el.getAttribute(attributeString);
6432: if (tempString != null) {
6433: tempReference = m_entityManager
6434: .newReference(tempString);
6435: m_feedbackAttachments.add(tempReference);
6436: if (M_log.isDebugEnabled())
6437: M_log
6438: .debug("ASSIGNMENT : BASE SERVICE : BASE SUB : CONSTRUCTOR : "
6439: + attributeString
6440: + " : "
6441: + tempString);
6442: }
6443: }
6444: } catch (Exception e) {
6445: M_log
6446: .warn("ASSIGNMENT : BASE SERVICE : BASE SUB : CONSTRUCTOR : Exception reading feedback attachments : "
6447: + e);
6448: }
6449:
6450: // READ THE SUBMITTED ATTACHMENTS
6451: m_submittedAttachments = m_entityManager.newReferenceList();
6452: intString = el.getAttribute("numberofsubmittedattachments");
6453: if (M_log.isDebugEnabled())
6454: M_log
6455: .debug("ASSIGNMENT : BASE SERVICE : BASE SUB : CONSTRUCTOR : num submitted attachments : "
6456: + intString);
6457: try {
6458: numAttributes = Integer.parseInt(intString);
6459:
6460: for (int x = 0; x < numAttributes; x++) {
6461: attributeString = "submittedattachment" + x;
6462: tempString = el.getAttribute(attributeString);
6463: if (tempString != null) {
6464: tempReference = m_entityManager
6465: .newReference(tempString);
6466: m_submittedAttachments.add(tempReference);
6467: if (M_log.isDebugEnabled())
6468: M_log
6469: .debug("ASSIGNMENT : BASE SERVICE : BASE SUB : CONSTRUCTOR : "
6470: + attributeString
6471: + " : "
6472: + tempString);
6473: }
6474: }
6475: } catch (Exception e) {
6476: M_log
6477: .warn("ASSIGNMENT : BASE SERVICE : BASE SUB : CONSTRUCTOR : Exception reading submitted attachments : "
6478: + e);
6479: }
6480:
6481: // READ THE PROPERTIES, SUBMITTED TEXT, FEEDBACK COMMENT, FEEDBACK TEXT
6482: NodeList children = el.getChildNodes();
6483: final int length = children.getLength();
6484: for (int i = 0; i < length; i++) {
6485: Node child = children.item(i);
6486: if (child.getNodeType() != Node.ELEMENT_NODE)
6487: continue;
6488: Element element = (Element) child;
6489:
6490: // look for properties
6491: if (element.getTagName().equals("properties")) {
6492: // re-create properties
6493: m_properties = new BaseResourcePropertiesEdit(
6494: element);
6495: }
6496: // old style encoding
6497: else if (element.getTagName().equals("submittedtext")) {
6498: if ((element.getChildNodes() != null)
6499: && (element.getChildNodes().item(0) != null)) {
6500: m_submittedText = element.getChildNodes().item(
6501: 0).getNodeValue();
6502: if (M_log.isDebugEnabled())
6503: M_log
6504: .debug("ASSIGNMENT : BASE SERVICE : BASE SUB : CONSTRUCTOR : submittedtext : "
6505: + m_submittedText);
6506: }
6507: if (m_submittedText == null) {
6508: m_submittedText = "";
6509: }
6510: }
6511: // old style encoding
6512: else if (element.getTagName().equals("feedbackcomment")) {
6513: if ((element.getChildNodes() != null)
6514: && (element.getChildNodes().item(0) != null)) {
6515: m_feedbackComment = element.getChildNodes()
6516: .item(0).getNodeValue();
6517: if (M_log.isDebugEnabled())
6518: M_log
6519: .debug("ASSIGNMENT : BASE SERVICE : BASE SUB : CONSTRUCTOR : feedbackcomment : "
6520: + m_feedbackComment);
6521: }
6522: if (m_feedbackComment == null) {
6523: m_feedbackComment = "";
6524: }
6525: }
6526: // old style encoding
6527: else if (element.getTagName().equals("feedbacktext")) {
6528: if ((element.getChildNodes() != null)
6529: && (element.getChildNodes().item(0) != null)) {
6530: m_feedbackText = element.getChildNodes()
6531: .item(0).getNodeValue();
6532: if (M_log.isDebugEnabled())
6533: M_log
6534: .debug("ASSIGNMENT : BASE SERVICE : BASE SUB : CONSTRUCTOR : FEEDBACK TEXT : "
6535: + m_feedbackText);
6536: }
6537: if (m_feedbackText == null) {
6538: m_feedbackText = "";
6539: }
6540: }
6541: }
6542:
6543: if (M_log.isDebugEnabled())
6544: M_log
6545: .debug("ASSIGNMENT : BASE SERVICE : BASE SUB : LEAVING STORAGE CONSTRUCTOR");
6546:
6547: }// storage constructor
6548:
6549: /**
6550: * Takes the AssignmentContent's attribute values and puts them into the xml document.
6551: *
6552: * @param s -
6553: * Data structure holding the object to be stored.
6554: * @param doc -
6555: * The xml document.
6556: */
6557: public Element toXml(Document doc, Stack stack) {
6558: if (M_log.isDebugEnabled())
6559: M_log
6560: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : ENTERING TOXML");
6561:
6562: Element submission = doc.createElement("submission");
6563: if (stack.isEmpty()) {
6564: doc.appendChild(submission);
6565: } else {
6566: ((Element) stack.peek()).appendChild(submission);
6567: }
6568:
6569: stack.push(submission);
6570:
6571: String numItemsString = null;
6572: String attributeString = null;
6573: String itemString = null;
6574: Reference tempReference = null;
6575:
6576: submission.setAttribute("id", m_id);
6577: submission.setAttribute("context", m_context);
6578: submission.setAttribute("scaled_grade", m_grade);
6579: submission.setAttribute("assignment", m_assignment);
6580: submission.setAttribute("datesubmitted",
6581: getTimeString(m_timeSubmitted));
6582: submission.setAttribute("datereturned",
6583: getTimeString(m_timeReturned));
6584: submission.setAttribute("lastmod",
6585: getTimeString(m_timeLastModified));
6586: submission.setAttribute("submitted",
6587: getBoolString(m_submitted));
6588: submission.setAttribute("returned",
6589: getBoolString(m_returned));
6590: submission.setAttribute("graded", getBoolString(m_graded));
6591: submission.setAttribute("gradereleased",
6592: getBoolString(m_gradeReleased));
6593: submission.setAttribute("pledgeflag",
6594: getBoolString(m_honorPledgeFlag));
6595:
6596: if (M_log.isDebugEnabled())
6597: M_log
6598: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : SAVED REGULAR PROPERTIES");
6599:
6600: // SAVE THE SUBMITTERS
6601: numItemsString = "" + m_submitters.size();
6602: submission.setAttribute("numberofsubmitters",
6603: numItemsString);
6604: for (int x = 0; x < m_submitters.size(); x++) {
6605: attributeString = "submitter" + x;
6606: itemString = (String) m_submitters.get(x);
6607: if (itemString != null)
6608: submission
6609: .setAttribute(attributeString, itemString);
6610: }
6611:
6612: if (M_log.isDebugEnabled())
6613: M_log
6614: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : SAVED SUBMITTERS");
6615:
6616: // SAVE THE FEEDBACK ATTACHMENTS
6617: numItemsString = "" + m_feedbackAttachments.size();
6618: submission.setAttribute("numberoffeedbackattachments",
6619: numItemsString);
6620: if (M_log.isDebugEnabled())
6621: M_log
6622: .debug("DB : DbCachedStorage : DbCachedAssignmentSubmission : entering fb attach loop : size : "
6623: + numItemsString);
6624: for (int x = 0; x < m_feedbackAttachments.size(); x++) {
6625: attributeString = "feedbackattachment" + x;
6626: tempReference = (Reference) m_feedbackAttachments
6627: .get(x);
6628: itemString = tempReference.getReference();
6629: if (itemString != null)
6630: submission
6631: .setAttribute(attributeString, itemString);
6632: }
6633:
6634: if (M_log.isDebugEnabled())
6635: M_log
6636: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : SAVED FEEDBACK ATTACHMENTS");
6637:
6638: // SAVE THE SUBMITTED ATTACHMENTS
6639: numItemsString = "" + m_submittedAttachments.size();
6640: submission.setAttribute("numberofsubmittedattachments",
6641: numItemsString);
6642: for (int x = 0; x < m_submittedAttachments.size(); x++) {
6643: attributeString = "submittedattachment" + x;
6644: tempReference = (Reference) m_submittedAttachments
6645: .get(x);
6646: itemString = tempReference.getReference();
6647: if (itemString != null)
6648: submission
6649: .setAttribute(attributeString, itemString);
6650: }
6651:
6652: if (M_log.isDebugEnabled())
6653: M_log
6654: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : SAVED SUBMITTED ATTACHMENTS");
6655:
6656: // SAVE THE PROPERTIES
6657: m_properties.toXml(doc, stack);
6658: stack.pop();
6659:
6660: FormattedText.encodeFormattedTextAttribute(submission,
6661: "submittedtext", m_submittedText);
6662: FormattedText.encodeFormattedTextAttribute(submission,
6663: "feedbackcomment", m_feedbackComment);
6664: FormattedText.encodeFormattedTextAttribute(submission,
6665: "feedbacktext", m_feedbackText);
6666:
6667: if (M_log.isDebugEnabled())
6668: M_log
6669: .debug("ASSIGNMENT : BASE SERVICE : BASE ASSIGNMENT : LEAVING TOXML");
6670:
6671: return submission;
6672:
6673: }// toXml
6674:
6675: protected void setAll(AssignmentSubmission submission) {
6676: m_id = submission.getId();
6677: m_context = submission.getContext();
6678: m_assignment = submission.getAssignmentId();
6679: m_grade = submission.getGrade();
6680: m_submitters = submission.getSubmitterIds();
6681: m_submitted = submission.getSubmitted();
6682: m_timeSubmitted = submission.getTimeSubmitted();
6683: m_timeReturned = submission.getTimeReturned();
6684: m_timeLastModified = submission.getTimeLastModified();
6685: m_submittedAttachments = submission
6686: .getSubmittedAttachments();
6687: m_feedbackAttachments = submission.getFeedbackAttachments();
6688: m_submittedText = submission.getSubmittedText();
6689: m_feedbackComment = submission.getFeedbackComment();
6690: m_feedbackText = submission.getFeedbackText();
6691: m_returned = submission.getReturned();
6692: m_graded = submission.getGraded();
6693: m_gradeReleased = submission.getGradeReleased();
6694: m_honorPledgeFlag = submission.getHonorPledgeFlag();
6695: m_properties = new BaseResourcePropertiesEdit();
6696: m_properties.addAll(submission.getProperties());
6697: }
6698:
6699: /**
6700: * Access the URL which can be used to access the resource.
6701: *
6702: * @return The URL which can be used to access the resource.
6703: */
6704: public String getUrl() {
6705: return getAccessPoint(false) + Entity.SEPARATOR + "s"
6706: + Entity.SEPARATOR + m_context + Entity.SEPARATOR
6707: + m_id;
6708:
6709: } // getUrl
6710:
6711: /**
6712: * Access the internal reference which can be used to access the resource from within the system.
6713: *
6714: * @return The the internal reference which can be used to access the resource from within the system.
6715: */
6716: public String getReference() {
6717: return submissionReference(m_context, m_id, m_assignment);
6718:
6719: } // getReference
6720:
6721: /**
6722: * @inheritDoc
6723: */
6724: public String getReference(String rootProperty) {
6725: return getReference();
6726: }
6727:
6728: /**
6729: * @inheritDoc
6730: */
6731: public String getUrl(String rootProperty) {
6732: return getUrl();
6733: }
6734:
6735: /**
6736: * Access the id of the resource.
6737: *
6738: * @return The id.
6739: */
6740: public String getId() {
6741: return m_id;
6742: }
6743:
6744: /**
6745: * Access the resource's properties.
6746: *
6747: * @return The resource's properties.
6748: */
6749: public ResourceProperties getProperties() {
6750: return m_properties;
6751: }
6752:
6753: /******************************************************************************************************************************************************************************************************************************************************
6754: * AssignmentSubmission implementation
6755: *****************************************************************************************************************************************************************************************************************************************************/
6756:
6757: /**
6758: * Access the AssignmentSubmission's context at the time of creation.
6759: *
6760: * @return String - the context string.
6761: */
6762: public String getContext() {
6763: return m_context;
6764: }
6765:
6766: /**
6767: * Access the Assignment for this Submission
6768: *
6769: * @return the Assignment
6770: */
6771: public Assignment getAssignment() {
6772: Assignment retVal = null;
6773: if (m_assignment != null) {
6774: retVal = m_assignmentStorage.get(m_assignment);
6775: }
6776:
6777: return retVal;
6778: }
6779:
6780: /**
6781: * Access the Id for the Assignment for this Submission
6782: *
6783: * @return String - the Assignment Id
6784: */
6785: public String getAssignmentId() {
6786: return m_assignment;
6787: }
6788:
6789: /**
6790: * Get whether this is a final submission.
6791: *
6792: * @return True if a final submission, false if still a draft.
6793: */
6794: public boolean getSubmitted() {
6795: return m_submitted;
6796: }
6797:
6798: /**
6799: * Access the list of Users who submitted this response to the Assignment.
6800: *
6801: * @return Array of User objects.
6802: */
6803: public User[] getSubmitters() {
6804: List retVal = new Vector();
6805: for (int x = 0; x < m_submitters.size(); x++) {
6806: String userId = (String) m_submitters.get(x);
6807: try {
6808: retVal.add(UserDirectoryService.getUser(userId));
6809: } catch (Exception e) {
6810: M_log.warn(this + e.getMessage() + userId);
6811: }
6812: }
6813:
6814: // get the User[] array
6815: int size = retVal.size();
6816: User[] rv = new User[size];
6817: for (int k = 0; k < size; k++) {
6818: rv[k] = (User) retVal.get(k);
6819: }
6820:
6821: return rv;
6822: }
6823:
6824: /**
6825: * Access the list of Users who submitted this response to the Assignment.
6826: *
6827: * @return FlexStringArray of user ids.
6828: */
6829: public List getSubmitterIds() {
6830: return m_submitters;
6831: }
6832:
6833: /**
6834: * Set the time at which this response was submitted; null signifies the response is unsubmitted.
6835: *
6836: * @return Time of submission.
6837: */
6838: public Time getTimeSubmitted() {
6839: return m_timeSubmitted;
6840: }
6841:
6842: /**
6843: * Get whether the grade has been released.
6844: *
6845: * @return True if the Submissions's grade has been released, false otherwise.
6846: */
6847: public boolean getGradeReleased() {
6848: return m_gradeReleased;
6849: }
6850:
6851: /**
6852: * Access the grade recieved.
6853: *
6854: * @return The Submission's grade..
6855: */
6856: public String getGrade() {
6857: return m_grade;
6858: }
6859:
6860: /**
6861: * Access the grade recieved.
6862: *
6863: * @return The Submission's grade..
6864: */
6865: public String getGradeDisplay() {
6866: Assignment m = getAssignment();
6867: if (m.getContent().getTypeOfGrade() == Assignment.SCORE_GRADE_TYPE) {
6868: if (m_grade != null && m_grade.length() > 0) {
6869: try {
6870: Integer.parseInt(m_grade);
6871: // if point grade, display the grade with one decimal place
6872: return m_grade.substring(0,
6873: m_grade.length() - 1)
6874: + "."
6875: + m_grade
6876: .substring(m_grade.length() - 1);
6877: } catch (Exception e) {
6878: return m_grade;
6879: }
6880: } else {
6881: return StringUtil.trimToZero(m_grade);
6882: }
6883: } else {
6884: return StringUtil.trimToZero(m_grade);
6885: }
6886: }
6887:
6888: /**
6889: * Get the time of last modification;
6890: *
6891: * @return The time of last modification.
6892: */
6893: public Time getTimeLastModified() {
6894: return m_timeLastModified;
6895: }
6896:
6897: /**
6898: * Text submitted in response to the Assignment.
6899: *
6900: * @return The text of the submission.
6901: */
6902: public String getSubmittedText() {
6903: return m_submittedText;
6904: }
6905:
6906: /**
6907: * Access the list of attachments to this response to the Assignment.
6908: *
6909: * @return ReferenceVector of the list of attachments as Reference objects;
6910: */
6911: public List getSubmittedAttachments() {
6912: return m_submittedAttachments;
6913: }
6914:
6915: /**
6916: * Get the general comments by the grader
6917: *
6918: * @return The text of the grader's comments; may be null.
6919: */
6920: public String getFeedbackComment() {
6921: return m_feedbackComment;
6922: }
6923:
6924: /**
6925: * Access the text part of the instructors feedback; usually an annotated copy of the submittedText
6926: *
6927: * @return The text of the grader's feedback.
6928: */
6929: public String getFeedbackText() {
6930: return m_feedbackText;
6931: }
6932:
6933: /**
6934: * Access the list of attachments returned to the students in the process of grading this assignment; usually a modified or annotated version of the attachment submitted.
6935: *
6936: * @return ReferenceVector of the Resource objects pointing to the attachments.
6937: */
6938: public List getFeedbackAttachments() {
6939: return m_feedbackAttachments;
6940: }
6941:
6942: /**
6943: * Get whether this Submission was rejected by the grader.
6944: *
6945: * @return True if this response was rejected by the grader, false otherwise.
6946: */
6947: public boolean getReturned() {
6948: return m_returned;
6949: }
6950:
6951: /**
6952: * Get whether this Submission has been graded.
6953: *
6954: * @return True if the submission has been graded, false otherwise.
6955: */
6956: public boolean getGraded() {
6957: return m_graded;
6958: }
6959:
6960: /**
6961: * Get the time on which the graded submission was returned; null means the response is not yet graded.
6962: *
6963: * @return the time (may be null)
6964: */
6965: public Time getTimeReturned() {
6966: return m_timeReturned;
6967: }
6968:
6969: /**
6970: * Access the checked status of the honor pledge flag.
6971: *
6972: * @return True if the honor pledge is checked, false otherwise.
6973: */
6974: public boolean getHonorPledgeFlag() {
6975: return m_honorPledgeFlag;
6976: }
6977:
6978: /**
6979: * Returns the status of the submission : Not Started, submitted, returned or graded.
6980: *
6981: * @return The Submission's status.
6982: */
6983: public String getStatus() {
6984: String retVal = null;
6985:
6986: if (m_submitted) {
6987: if (m_graded && m_gradeReleased)
6988: retVal = STATUS_GRADED;
6989: else if (m_returned)
6990: retVal = STATUS_RETURNED;
6991: else
6992: retVal = STATUS_SUBMITTED;
6993: } else
6994: retVal = STATUS_DRAFT;
6995:
6996: return retVal;
6997: }
6998:
6999: /**
7000: * Are these objects equal? If they are both AssignmentSubmission objects, and they have matching id's, they are.
7001: *
7002: * @return true if they are equal, false if not.
7003: */
7004: public boolean equals(Object obj) {
7005: if (!(obj instanceof AssignmentSubmission))
7006: return false;
7007: return ((AssignmentSubmission) obj).getId().equals(getId());
7008:
7009: } // equals
7010:
7011: /**
7012: * Make a hash code that reflects the equals() logic as well. We want two objects, even if different instances, if they have the same id to hash the same.
7013: */
7014: public int hashCode() {
7015: return getId().hashCode();
7016:
7017: } // hashCode
7018:
7019: /**
7020: * Compare this object with the specified object for order.
7021: *
7022: * @return A negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
7023: */
7024: public int compareTo(Object obj) {
7025: if (!(obj instanceof AssignmentSubmission))
7026: throw new ClassCastException();
7027:
7028: // if the object are the same, say so
7029: if (obj == this )
7030: return 0;
7031:
7032: // start the compare by comparing their sort names
7033: int compare = getTimeSubmitted().toString().compareTo(
7034: ((AssignmentSubmission) obj).getTimeSubmitted()
7035: .toString());
7036:
7037: // if these are the same
7038: if (compare == 0) {
7039: // sort based on (unique) id
7040: compare = getId().compareTo(
7041: ((AssignmentSubmission) obj).getId());
7042: }
7043:
7044: return compare;
7045:
7046: } // compareTo
7047:
7048: } // AssignmentSubmission
7049:
7050: /**********************************************************************************************************************************************************************************************************************************************************
7051: * AssignmentSubmissionEdit implementation
7052: *********************************************************************************************************************************************************************************************************************************************************/
7053:
7054: /**
7055: * <p>
7056: * BaseAssignmentSubmissionEdit is an implementation of the CHEF AssignmentSubmissionEdit object.
7057: * </p>
7058: *
7059: * @author University of Michigan, CHEF Software Development Team
7060: */
7061: public class BaseAssignmentSubmissionEdit extends
7062: BaseAssignmentSubmission implements
7063: AssignmentSubmissionEdit, SessionBindingListener {
7064: /** The event code for this edit. */
7065: protected String m_event = null;
7066:
7067: /** Active flag. */
7068: protected boolean m_active = false;
7069:
7070: /**
7071: * Construct from another AssignmentSubmission object.
7072: *
7073: * @param AssignmentSubmission
7074: * The AssignmentSubmission object to use for values.
7075: */
7076: public BaseAssignmentSubmissionEdit(
7077: AssignmentSubmission assignmentSubmission) {
7078: super (assignmentSubmission);
7079:
7080: } // BaseAssignmentSubmissionEdit
7081:
7082: /**
7083: * Construct.
7084: *
7085: * @param id
7086: * The AssignmentSubmission id.
7087: */
7088: public BaseAssignmentSubmissionEdit(String id, String context,
7089: String assignmentId) {
7090: super (id, context, assignmentId);
7091:
7092: } // BaseAssignmentSubmissionEdit
7093:
7094: /**
7095: * Construct from information in XML.
7096: *
7097: * @param el
7098: * The XML DOM Element definining the AssignmentSubmission.
7099: */
7100: public BaseAssignmentSubmissionEdit(Element el) {
7101: super (el);
7102:
7103: } // BaseAssignmentSubmissionEdit
7104:
7105: /**
7106: * Clean up.
7107: */
7108: protected void finalize() {
7109: // catch the case where an edit was made but never resolved
7110: if (m_active) {
7111: cancelEdit(this );
7112: }
7113:
7114: } // finalize
7115:
7116: /**
7117: * Set the context at the time of creation.
7118: *
7119: * @param context -
7120: * the context string.
7121: */
7122: public void setContext(String context) {
7123: m_context = context;
7124: }
7125:
7126: /**
7127: * Set the Assignment for this Submission
7128: *
7129: * @param assignment -
7130: * the Assignment
7131: */
7132: public void setAssignment(Assignment assignment) {
7133: if (assignment != null) {
7134: m_assignment = assignment.getId();
7135: } else
7136: m_assignment = "";
7137: }
7138:
7139: /**
7140: * Set whether this is a final submission.
7141: *
7142: * @param submitted -
7143: * True if a final submission, false if still a draft.
7144: */
7145: public void setSubmitted(boolean submitted) {
7146: m_submitted = submitted;
7147: }
7148:
7149: /**
7150: * Add a User to the submitters list.
7151: *
7152: * @param submitter -
7153: * the User to add.
7154: */
7155: public void addSubmitter(User submitter) {
7156: if (submitter != null)
7157: m_submitters.add(submitter.getId());
7158: }
7159:
7160: /**
7161: * Remove an User from the submitter list
7162: *
7163: * @param submitter -
7164: * the User to remove.
7165: */
7166: public void removeSubmitter(User submitter) {
7167: if (submitter != null)
7168: m_submitters.remove(submitter.getId());
7169: }
7170:
7171: /**
7172: * Remove all user from the submitter list
7173: */
7174: public void clearSubmitters() {
7175: m_submitters.clear();
7176: }
7177:
7178: /**
7179: * Set the time at which this response was submitted; setting it to null signifies the response is unsubmitted.
7180: *
7181: * @param timeSubmitted -
7182: * Time of submission.
7183: */
7184: public void setTimeSubmitted(Time value) {
7185: m_timeSubmitted = value;
7186: }
7187:
7188: /**
7189: * Set whether the grade has been released.
7190: *
7191: * @param released -
7192: * True if the Submissions's grade has been released, false otherwise.
7193: */
7194: public void setGradeReleased(boolean released) {
7195: m_gradeReleased = released;
7196: }
7197:
7198: /**
7199: * Sets the grade for the Submisssion.
7200: *
7201: * @param grade -
7202: * The Submission's grade.
7203: */
7204: public void setGrade(String grade) {
7205: m_grade = grade;
7206: }
7207:
7208: /**
7209: * Text submitted in response to the Assignment.
7210: *
7211: * @param submissionText -
7212: * The text of the submission.
7213: */
7214: public void setSubmittedText(String value) {
7215: m_submittedText = value;
7216: }
7217:
7218: /**
7219: * Add an attachment to the list of submitted attachments.
7220: *
7221: * @param attachment -
7222: * The Reference object pointing to the attachment.
7223: */
7224: public void addSubmittedAttachment(Reference attachment) {
7225: if (attachment != null)
7226: m_submittedAttachments.add(attachment);
7227: }
7228:
7229: /**
7230: * Remove an attachment from the list of submitted attachments
7231: *
7232: * @param attachment -
7233: * The Reference object pointing to the attachment.
7234: */
7235: public void removeSubmittedAttachment(Reference attachment) {
7236: if (attachment != null)
7237: m_submittedAttachments.remove(attachment);
7238: }
7239:
7240: /**
7241: * Remove all submitted attachments.
7242: */
7243: public void clearSubmittedAttachments() {
7244: m_submittedAttachments.clear();
7245: }
7246:
7247: /**
7248: * Set the general comments by the grader.
7249: *
7250: * @param comment -
7251: * the text of the grader's comments; may be null.
7252: */
7253: public void setFeedbackComment(String value) {
7254: m_feedbackComment = value;
7255: }
7256:
7257: /**
7258: * Set the text part of the instructors feedback; usually an annotated copy of the submittedText
7259: *
7260: * @param feedback -
7261: * The text of the grader's feedback.
7262: */
7263: public void setFeedbackText(String value) {
7264: m_feedbackText = value;
7265: }
7266:
7267: /**
7268: * Add an attachment to the list of feedback attachments.
7269: *
7270: * @param attachment -
7271: * The Resource object pointing to the attachment.
7272: */
7273: public void addFeedbackAttachment(Reference attachment) {
7274: if (attachment != null)
7275: m_feedbackAttachments.add(attachment);
7276: }
7277:
7278: /**
7279: * Remove an attachment from the list of feedback attachments.
7280: *
7281: * @param attachment -
7282: * The Resource pointing to the attachment to remove.
7283: */
7284: public void removeFeedbackAttachment(Reference attachment) {
7285: if (attachment != null)
7286: m_feedbackAttachments.remove(attachment);
7287: }
7288:
7289: /**
7290: * Remove all feedback attachments.
7291: */
7292: public void clearFeedbackAttachments() {
7293: m_feedbackAttachments.clear();
7294: }
7295:
7296: /**
7297: * Set whether this Submission was rejected by the grader.
7298: *
7299: * @param returned -
7300: * true if this response was rejected by the grader, false otherwise.
7301: */
7302: public void setReturned(boolean value) {
7303: m_returned = value;
7304: }
7305:
7306: /**
7307: * Set whether this Submission has been graded.
7308: *
7309: * @param graded -
7310: * true if the submission has been graded, false otherwise.
7311: */
7312: public void setGraded(boolean value) {
7313: m_graded = value;
7314: }
7315:
7316: /**
7317: * Set the time at which the graded Submission was returned; setting it to null means it is not yet graded.
7318: *
7319: * @param timeReturned -
7320: * The time at which the graded Submission was returned.
7321: */
7322: public void setTimeReturned(Time timeReturned) {
7323: m_timeReturned = timeReturned;
7324: }
7325:
7326: /**
7327: * Set the checked status of the honor pledge flag.
7328: *
7329: * @param honorPledgeFlag -
7330: * True if the honor pledge is checked, false otherwise.
7331: */
7332: public void setHonorPledgeFlag(boolean honorPledgeFlag) {
7333: m_honorPledgeFlag = honorPledgeFlag;
7334: }
7335:
7336: /**
7337: * Set the time last modified.
7338: *
7339: * @param lastmod -
7340: * The Time at which the Assignment was last modified.
7341: */
7342: public void setTimeLastModified(Time lastmod) {
7343: if (lastmod != null)
7344: m_timeLastModified = lastmod;
7345: }
7346:
7347: /**
7348: * Take all values from this object.
7349: *
7350: * @param AssignmentSubmission
7351: * The AssignmentSubmission object to take values from.
7352: */
7353: protected void set(AssignmentSubmission assignmentSubmission) {
7354: setAll(assignmentSubmission);
7355:
7356: } // set
7357:
7358: /**
7359: * Access the event code for this edit.
7360: *
7361: * @return The event code for this edit.
7362: */
7363: protected String getEvent() {
7364: return m_event;
7365: }
7366:
7367: /**
7368: * Set the event code for this edit.
7369: *
7370: * @param event
7371: * The event code for this edit.
7372: */
7373: protected void setEvent(String event) {
7374: m_event = event;
7375: }
7376:
7377: /**
7378: * Access the resource's properties for modification
7379: *
7380: * @return The resource's properties.
7381: */
7382: public ResourcePropertiesEdit getPropertiesEdit() {
7383: return m_properties;
7384:
7385: } // getPropertiesEdit
7386:
7387: /**
7388: * Enable editing.
7389: */
7390: protected void activate() {
7391: m_active = true;
7392:
7393: } // activate
7394:
7395: /**
7396: * Check to see if the edit is still active, or has already been closed.
7397: *
7398: * @return true if the edit is active, false if it's been closed.
7399: */
7400: public boolean isActiveEdit() {
7401: return m_active;
7402:
7403: } // isActiveEdit
7404:
7405: /**
7406: * Close the edit object - it cannot be used after this.
7407: */
7408: protected void closeEdit() {
7409: m_active = false;
7410:
7411: } // closeEdit
7412:
7413: /******************************************************************************************************************************************************************************************************************************************************
7414: * SessionBindingListener implementation
7415: *****************************************************************************************************************************************************************************************************************************************************/
7416:
7417: public void valueBound(SessionBindingEvent event) {
7418: }
7419:
7420: public void valueUnbound(SessionBindingEvent event) {
7421: if (M_log.isDebugEnabled())
7422: M_log.debug("valueUnbound()");
7423:
7424: // catch the case where an edit was made but never resolved
7425: if (m_active) {
7426: cancelEdit(this );
7427: }
7428:
7429: } // valueUnbound
7430:
7431: } // BaseAssignmentSubmissionEdit
7432:
7433: /**********************************************************************************************************************************************************************************************************************************************************
7434: * Assignment Storage
7435: *********************************************************************************************************************************************************************************************************************************************************/
7436:
7437: protected interface AssignmentStorage {
7438: /**
7439: * Open.
7440: */
7441: public void open();
7442:
7443: /**
7444: * Close.
7445: */
7446: public void close();
7447:
7448: /**
7449: * Check if an Assignment by this id exists.
7450: *
7451: * @param id
7452: * The assignment id.
7453: * @return true if an Assignment by this id exists, false if not.
7454: */
7455: public boolean check(String id);
7456:
7457: /**
7458: * Get the Assignment with this id, or null if not found.
7459: *
7460: * @param id
7461: * The Assignment id.
7462: * @return The Assignment with this id, or null if not found.
7463: */
7464: public Assignment get(String id);
7465:
7466: /**
7467: * Get all Assignments.
7468: *
7469: * @return The list of all Assignments.
7470: */
7471: public List getAll(String context);
7472:
7473: /**
7474: * Add a new Assignment with this id.
7475: *
7476: * @param id
7477: * The Assignment id.
7478: * @param context
7479: * The context.
7480: * @return The locked Assignment object with this id, or null if the id is in use.
7481: */
7482: public AssignmentEdit put(String id, String context);
7483:
7484: /**
7485: * Get a lock on the Assignment with this id, or null if a lock cannot be gotten.
7486: *
7487: * @param id
7488: * The Assignment id.
7489: * @return The locked Assignment with this id, or null if this records cannot be locked.
7490: */
7491: public AssignmentEdit edit(String id);
7492:
7493: /**
7494: * Commit the changes and release the lock.
7495: *
7496: * @param Assignment
7497: * The Assignment to commit.
7498: */
7499: public void commit(AssignmentEdit assignment);
7500:
7501: /**
7502: * Cancel the changes and release the lock.
7503: *
7504: * @param Assignment
7505: * The Assignment to commit.
7506: */
7507: public void cancel(AssignmentEdit assignment);
7508:
7509: /**
7510: * Remove this Assignment.
7511: *
7512: * @param Assignment
7513: * The Assignment to remove.
7514: */
7515: public void remove(AssignmentEdit assignment);
7516:
7517: } // AssignmentStorage
7518:
7519: /**********************************************************************************************************************************************************************************************************************************************************
7520: * AssignmentContent Storage
7521: *********************************************************************************************************************************************************************************************************************************************************/
7522:
7523: protected interface AssignmentContentStorage {
7524: /**
7525: * Open.
7526: */
7527: public void open();
7528:
7529: /**
7530: * Close.
7531: */
7532: public void close();
7533:
7534: /**
7535: * Check if a AssignmentContent by this id exists.
7536: *
7537: * @param id
7538: * The AssignmentContent id.
7539: * @return true if a AssignmentContent by this id exists, false if not.
7540: */
7541: public boolean check(String id);
7542:
7543: /**
7544: * Get the AssignmentContent with this id, or null if not found.
7545: *
7546: * @param id
7547: * The AssignmentContent id.
7548: * @return The AssignmentContent with this id, or null if not found.
7549: */
7550: public AssignmentContent get(String id);
7551:
7552: /**
7553: * Get all AssignmentContents.
7554: *
7555: * @return The list of all AssignmentContents.
7556: */
7557: public List getAll(String context);
7558:
7559: /**
7560: * Add a new AssignmentContent with this id.
7561: *
7562: * @param id
7563: * The AssignmentContent id.
7564: * @param context
7565: * The context.
7566: * @return The locked AssignmentContent object with this id, or null if the id is in use.
7567: */
7568: public AssignmentContentEdit put(String id, String context);
7569:
7570: /**
7571: * Get a lock on the AssignmentContent with this id, or null if a lock cannot be gotten.
7572: *
7573: * @param id
7574: * The AssignmentContent id.
7575: * @return The locked AssignmentContent with this id, or null if this records cannot be locked.
7576: */
7577: public AssignmentContentEdit edit(String id);
7578:
7579: /**
7580: * Commit the changes and release the lock.
7581: *
7582: * @param AssignmentContent
7583: * The AssignmentContent to commit.
7584: */
7585: public void commit(AssignmentContentEdit content);
7586:
7587: /**
7588: * Cancel the changes and release the lock.
7589: *
7590: * @param AssignmentContent
7591: * The AssignmentContent to commit.
7592: */
7593: public void cancel(AssignmentContentEdit content);
7594:
7595: /**
7596: * Remove this AssignmentContent.
7597: *
7598: * @param AssignmentContent
7599: * The AssignmentContent to remove.
7600: */
7601: public void remove(AssignmentContentEdit content);
7602:
7603: } // AssignmentContentStorage
7604:
7605: /**********************************************************************************************************************************************************************************************************************************************************
7606: * AssignmentSubmission Storage
7607: *********************************************************************************************************************************************************************************************************************************************************/
7608:
7609: protected interface AssignmentSubmissionStorage {
7610: /**
7611: * Open.
7612: */
7613: public void open();
7614:
7615: /**
7616: * Close.
7617: */
7618: public void close();
7619:
7620: /**
7621: * Check if a AssignmentSubmission by this id exists.
7622: *
7623: * @param id
7624: * The AssignmentSubmission id.
7625: * @return true if a AssignmentSubmission by this id exists, false if not.
7626: */
7627: public boolean check(String id);
7628:
7629: /**
7630: * Get the AssignmentSubmission with this id, or null if not found.
7631: *
7632: * @param id
7633: * The AssignmentSubmission id.
7634: * @return The AssignmentSubmission with this id, or null if not found.
7635: */
7636: public AssignmentSubmission get(String id);
7637:
7638: /**
7639: * Get all AssignmentSubmissions.
7640: *
7641: * @return The list of all AssignmentSubmissions.
7642: */
7643: public List getAll(String context);
7644:
7645: /**
7646: * Add a new AssignmentSubmission with this id.
7647: *
7648: * @param id
7649: * The AssignmentSubmission id.
7650: * @param context
7651: * The context.
7652: * @return The locked AssignmentSubmission object with this id, or null if the id is in use.
7653: */
7654: public AssignmentSubmissionEdit put(String id, String context,
7655: String assignmentId);
7656:
7657: /**
7658: * Get a lock on the AssignmentSubmission with this id, or null if a lock cannot be gotten.
7659: *
7660: * @param id
7661: * The AssignmentSubmission id.
7662: * @return The locked AssignmentSubmission with this id, or null if this records cannot be locked.
7663: */
7664: public AssignmentSubmissionEdit edit(String id);
7665:
7666: /**
7667: * Commit the changes and release the lock.
7668: *
7669: * @param AssignmentSubmission
7670: * The AssignmentSubmission to commit.
7671: */
7672: public void commit(AssignmentSubmissionEdit submission);
7673:
7674: /**
7675: * Cancel the changes and release the lock.
7676: *
7677: * @param AssignmentSubmission
7678: * The AssignmentSubmission to commit.
7679: */
7680: public void cancel(AssignmentSubmissionEdit submission);
7681:
7682: /**
7683: * Remove this AssignmentSubmission.
7684: *
7685: * @param AssignmentSubmission
7686: * The AssignmentSubmission to remove.
7687: */
7688: public void remove(AssignmentSubmissionEdit submission);
7689:
7690: } // AssignmentSubmissionStorage
7691:
7692: /**
7693: * Utility function which returns the string representation of the long value of the time object.
7694: *
7695: * @param t -
7696: * the Time object.
7697: * @return A String representation of the long value of the time object.
7698: */
7699: protected String getTimeString(Time t) {
7700: String retVal = "";
7701: if (t != null)
7702: retVal = t.toString();
7703: return retVal;
7704: }
7705:
7706: /**
7707: * Utility function which returns a string from a boolean value.
7708: *
7709: * @param b -
7710: * the boolean value.
7711: * @return - "True" if the input value is true, "false" otherwise.
7712: */
7713: protected String getBoolString(boolean b) {
7714: if (b)
7715: return "true";
7716: else
7717: return "false";
7718: }
7719:
7720: /**
7721: * Utility function which returns a boolean value from a string.
7722: *
7723: * @param s -
7724: * The input string.
7725: * @return the boolean true if the input string is "true", false otherwise.
7726: */
7727: protected boolean getBool(String s) {
7728: boolean retVal = false;
7729: if (s != null) {
7730: if (s.equalsIgnoreCase("true"))
7731: retVal = true;
7732: }
7733: return retVal;
7734: }
7735:
7736: /**
7737: * Utility function which converts a string into a chef time object.
7738: *
7739: * @param timeString -
7740: * String version of a time in long format, representing the standard ms since the epoch, Jan 1, 1970 00:00:00.
7741: * @return A chef Time object.
7742: */
7743: protected Time getTimeObject(String timeString) {
7744: Time aTime = null;
7745: timeString = StringUtil.trimToNull(timeString);
7746: if (timeString != null) {
7747: try {
7748: aTime = TimeService.newTimeGmt(timeString);
7749: } catch (Exception e) {
7750: try {
7751: long longTime = Long.parseLong(timeString);
7752: aTime = TimeService.newTime(longTime);
7753: } catch (Exception ee) {
7754: M_log
7755: .warn(this
7756: + " Exception creating time object from xml file : "
7757: + ee);
7758: }
7759: }
7760: }
7761: return aTime;
7762: }
7763:
7764: protected String getGroupNameFromContext(String context) {
7765: String retVal = "";
7766:
7767: if (context != null) {
7768: int index = context.indexOf("group-");
7769: if (index != -1) {
7770: String[] parts = StringUtil.splitFirst(context, "-");
7771: if (parts.length > 1) {
7772: retVal = parts[1];
7773: }
7774: } else {
7775: retVal = context;
7776: }
7777: }
7778:
7779: return retVal;
7780: }
7781:
7782: /**********************************************************************************************************************************************************************************************************************************************************
7783: * StorageUser implementations (no container)
7784: *********************************************************************************************************************************************************************************************************************************************************/
7785:
7786: /**********************************************************************************************************************************************************************************************************************************************************
7787: * AssignmentStorageUser implementation
7788: *********************************************************************************************************************************************************************************************************************************************************/
7789:
7790: protected class AssignmentStorageUser implements StorageUser {
7791: /**
7792: * Construct a new continer given just an id.
7793: *
7794: * @param id
7795: * The id for the new object.
7796: * @return The new container Resource.
7797: */
7798: public Entity newContainer(String ref) {
7799: return null;
7800: }
7801:
7802: /**
7803: * Construct a new container resource, from an XML element.
7804: *
7805: * @param element
7806: * The XML.
7807: * @return The new container resource.
7808: */
7809: public Entity newContainer(Element element) {
7810: return null;
7811: }
7812:
7813: /**
7814: * Construct a new container resource, as a copy of another
7815: *
7816: * @param other
7817: * The other contianer to copy.
7818: * @return The new container resource.
7819: */
7820: public Entity newContainer(Entity other) {
7821: return null;
7822: }
7823:
7824: /**
7825: * Construct a new resource given just an id.
7826: *
7827: * @param container
7828: * The Resource that is the container for the new resource (may be null).
7829: * @param id
7830: * The id for the new object.
7831: * @param others
7832: * (options) array of objects to load into the Resource's fields.
7833: * @return The new resource.
7834: */
7835: public Entity newResource(Entity container, String id,
7836: Object[] others) {
7837: return new BaseAssignment(id, (String) others[0]);
7838: }
7839:
7840: /**
7841: * Construct a new resource, from an XML element.
7842: *
7843: * @param container
7844: * The Resource that is the container for the new resource (may be null).
7845: * @param element
7846: * The XML.
7847: * @return The new resource from the XML.
7848: */
7849: public Entity newResource(Entity container, Element element) {
7850: return new BaseAssignment(element);
7851: }
7852:
7853: /**
7854: * Construct a new resource from another resource of the same type.
7855: *
7856: * @param container
7857: * The Resource that is the container for the new resource (may be null).
7858: * @param other
7859: * The other resource.
7860: * @return The new resource as a copy of the other.
7861: */
7862: public Entity newResource(Entity container, Entity other) {
7863: return new BaseAssignment((Assignment) other);
7864: }
7865:
7866: /**
7867: * Construct a new continer given just an id.
7868: *
7869: * @param id
7870: * The id for the new object.
7871: * @return The new containe Resource.
7872: */
7873: public Edit newContainerEdit(String ref) {
7874: return null;
7875: }
7876:
7877: /**
7878: * Construct a new container resource, from an XML element.
7879: *
7880: * @param element
7881: * The XML.
7882: * @return The new container resource.
7883: */
7884: public Edit newContainerEdit(Element element) {
7885: return null;
7886: }
7887:
7888: /**
7889: * Construct a new container resource, as a copy of another
7890: *
7891: * @param other
7892: * The other contianer to copy.
7893: * @return The new container resource.
7894: */
7895: public Edit newContainerEdit(Entity other) {
7896: return null;
7897: }
7898:
7899: /**
7900: * Construct a new resource given just an id.
7901: *
7902: * @param container
7903: * The Resource that is the container for the new resource (may be null).
7904: * @param id
7905: * The id for the new object.
7906: * @param others
7907: * (options) array of objects to load into the Resource's fields.
7908: * @return The new resource.
7909: */
7910: public Edit newResourceEdit(Entity container, String id,
7911: Object[] others) {
7912: BaseAssignmentEdit e = new BaseAssignmentEdit(id,
7913: (String) others[0]);
7914: e.activate();
7915: return e;
7916: }
7917:
7918: /**
7919: * Construct a new resource, from an XML element.
7920: *
7921: * @param container
7922: * The Resource that is the container for the new resource (may be null).
7923: * @param element
7924: * The XML.
7925: * @return The new resource from the XML.
7926: */
7927: public Edit newResourceEdit(Entity container, Element element) {
7928: BaseAssignmentEdit e = new BaseAssignmentEdit(element);
7929: e.activate();
7930: return e;
7931: }
7932:
7933: /**
7934: * Construct a new resource from another resource of the same type.
7935: *
7936: * @param container
7937: * The Resource that is the container for the new resource (may be null).
7938: * @param other
7939: * The other resource.
7940: * @return The new resource as a copy of the other.
7941: */
7942: public Edit newResourceEdit(Entity container, Entity other) {
7943: BaseAssignmentEdit e = new BaseAssignmentEdit(
7944: (Assignment) other);
7945: e.activate();
7946: return e;
7947: }
7948:
7949: /**
7950: * Collect the fields that need to be stored outside the XML (for the resource).
7951: *
7952: * @return An array of field values to store in the record outside the XML (for the resource).
7953: */
7954: public Object[] storageFields(Entity r) {
7955: Object rv[] = new Object[1];
7956: rv[0] = ((Assignment) r).getContext();
7957: return rv;
7958: }
7959:
7960: /**
7961: * Check if this resource is in draft mode.
7962: *
7963: * @param r
7964: * The resource.
7965: * @return true if the resource is in draft mode, false if not.
7966: */
7967: public boolean isDraft(Entity r) {
7968: return false;
7969: }
7970:
7971: /**
7972: * Access the resource owner user id.
7973: *
7974: * @param r
7975: * The resource.
7976: * @return The resource owner user id.
7977: */
7978: public String getOwnerId(Entity r) {
7979: return null;
7980: }
7981:
7982: /**
7983: * Access the resource date.
7984: *
7985: * @param r
7986: * The resource.
7987: * @return The resource date.
7988: */
7989: public Time getDate(Entity r) {
7990: return null;
7991: }
7992:
7993: }// AssignmentStorageUser
7994:
7995: /**********************************************************************************************************************************************************************************************************************************************************
7996: * AssignmentContentStorageUser implementation
7997: *********************************************************************************************************************************************************************************************************************************************************/
7998:
7999: protected class AssignmentContentStorageUser implements StorageUser {
8000: /**
8001: * Construct a new continer given just an id.
8002: *
8003: * @param id
8004: * The id for the new object.
8005: * @return The new container Resource.
8006: */
8007: public Entity newContainer(String ref) {
8008: return null;
8009: }
8010:
8011: /**
8012: * Construct a new container resource, from an XML element.
8013: *
8014: * @param element
8015: * The XML.
8016: * @return The new container resource.
8017: */
8018: public Entity newContainer(Element element) {
8019: return null;
8020: }
8021:
8022: /**
8023: * Construct a new container resource, as a copy of another
8024: *
8025: * @param other
8026: * The other contianer to copy.
8027: * @return The new container resource.
8028: */
8029: public Entity newContainer(Entity other) {
8030: return null;
8031: }
8032:
8033: /**
8034: * Construct a new resource given just an id.
8035: *
8036: * @param container
8037: * The Resource that is the container for the new resource (may be null).
8038: * @param id
8039: * The id for the new object.
8040: * @param others
8041: * (options) array of objects to load into the Resource's fields.
8042: * @return The new resource.
8043: */
8044: public Entity newResource(Entity container, String id,
8045: Object[] others) {
8046: return new BaseAssignmentContent(id, (String) others[0]);
8047: }
8048:
8049: /**
8050: * Construct a new resource, from an XML element.
8051: *
8052: * @param container
8053: * The Resource that is the container for the new resource (may be null).
8054: * @param element
8055: * The XML.
8056: * @return The new resource from the XML.
8057: */
8058: public Entity newResource(Entity container, Element element) {
8059: return new BaseAssignmentContent(element);
8060: }
8061:
8062: /**
8063: * Construct a new resource from another resource of the same type.
8064: *
8065: * @param container
8066: * The Resource that is the container for the new resource (may be null).
8067: * @param other
8068: * The other resource.
8069: * @return The new resource as a copy of the other.
8070: */
8071: public Entity newResource(Entity container, Entity other) {
8072: return new BaseAssignmentContent((AssignmentContent) other);
8073: }
8074:
8075: /**
8076: * Construct a new continer given just an id.
8077: *
8078: * @param id
8079: * The id for the new object.
8080: * @return The new containe Resource.
8081: */
8082: public Edit newContainerEdit(String ref) {
8083: return null;
8084: }
8085:
8086: /**
8087: * Construct a new container resource, from an XML element.
8088: *
8089: * @param element
8090: * The XML.
8091: * @return The new container resource.
8092: */
8093: public Edit newContainerEdit(Element element) {
8094: return null;
8095: }
8096:
8097: /**
8098: * Construct a new container resource, as a copy of another
8099: *
8100: * @param other
8101: * The other contianer to copy.
8102: * @return The new container resource.
8103: */
8104: public Edit newContainerEdit(Entity other) {
8105: return null;
8106: }
8107:
8108: /**
8109: * Construct a new rsource given just an id.
8110: *
8111: * @param container
8112: * The Resource that is the container for the new resource (may be null).
8113: * @param id
8114: * The id for the new object.
8115: * @param others
8116: * (options) array of objects to load into the Resource's fields.
8117: * @return The new resource.
8118: */
8119: public Edit newResourceEdit(Entity container, String id,
8120: Object[] others) {
8121: BaseAssignmentContentEdit e = new BaseAssignmentContentEdit(
8122: id, (String) others[0]);
8123: e.activate();
8124: return e;
8125: }
8126:
8127: /**
8128: * Construct a new resource, from an XML element.
8129: *
8130: * @param container
8131: * The Resource that is the container for the new resource (may be null).
8132: * @param element
8133: * The XML.
8134: * @return The new resource from the XML.
8135: */
8136: public Edit newResourceEdit(Entity container, Element element) {
8137: BaseAssignmentContentEdit e = new BaseAssignmentContentEdit(
8138: element);
8139: e.activate();
8140: return e;
8141: }
8142:
8143: /**
8144: * Construct a new resource from another resource of the same type.
8145: *
8146: * @param container
8147: * The Resource that is the container for the new resource (may be null).
8148: * @param other
8149: * The other resource.
8150: * @return The new resource as a copy of the other.
8151: */
8152: public Edit newResourceEdit(Entity container, Entity other) {
8153: BaseAssignmentContentEdit e = new BaseAssignmentContentEdit(
8154: (AssignmentContent) other);
8155: e.activate();
8156: return e;
8157: }
8158:
8159: /**
8160: * Collect the fields that need to be stored outside the XML (for the resource).
8161: *
8162: * @return An array of field values to store in the record outside the XML (for the resource).
8163: */
8164: public Object[] storageFields(Entity r) {
8165: Object rv[] = new Object[1];
8166: rv[0] = ((AssignmentContent) r).getCreator();
8167: return rv;
8168: }
8169:
8170: /**
8171: * Check if this resource is in draft mode.
8172: *
8173: * @param r
8174: * The resource.
8175: * @return true if the resource is in draft mode, false if not.
8176: */
8177: public boolean isDraft(Entity r) {
8178: return false;
8179: }
8180:
8181: /**
8182: * Access the resource owner user id.
8183: *
8184: * @param r
8185: * The resource.
8186: * @return The resource owner user id.
8187: */
8188: public String getOwnerId(Entity r) {
8189: return null;
8190: }
8191:
8192: /**
8193: * Access the resource date.
8194: *
8195: * @param r
8196: * The resource.
8197: * @return The resource date.
8198: */
8199: public Time getDate(Entity r) {
8200: return null;
8201: }
8202:
8203: }// ContentStorageUser
8204:
8205: /**********************************************************************************************************************************************************************************************************************************************************
8206: * SubmissionStorageUser implementation
8207: *********************************************************************************************************************************************************************************************************************************************************/
8208:
8209: protected class AssignmentSubmissionStorageUser implements
8210: StorageUser {
8211: /**
8212: * Construct a new continer given just an id.
8213: *
8214: * @param id
8215: * The id for the new object.
8216: * @return The new container Resource.
8217: */
8218: public Entity newContainer(String ref) {
8219: return null;
8220: }
8221:
8222: /**
8223: * Construct a new container resource, from an XML element.
8224: *
8225: * @param element
8226: * The XML.
8227: * @return The new container resource.
8228: */
8229: public Entity newContainer(Element element) {
8230: return null;
8231: }
8232:
8233: /**
8234: * Construct a new container resource, as a copy of another
8235: *
8236: * @param other
8237: * The other contianer to copy.
8238: * @return The new container resource.
8239: */
8240: public Entity newContainer(Entity other) {
8241: return null;
8242: }
8243:
8244: /**
8245: * Construct a new resource given just an id.
8246: *
8247: * @param container
8248: * The Resource that is the container for the new resource (may be null).
8249: * @param id
8250: * The id for the new object.
8251: * @param others
8252: * (options) array of objects to load into the Resource's fields.
8253: * @return The new resource.
8254: */
8255: public Entity newResource(Entity container, String id,
8256: Object[] others) {
8257: return new BaseAssignmentSubmission(id, (String) others[0],
8258: (String) others[1]);
8259: }
8260:
8261: /**
8262: * Construct a new resource, from an XML element.
8263: *
8264: * @param container
8265: * The Resource that is the container for the new resource (may be null).
8266: * @param element
8267: * The XML.
8268: * @return The new resource from the XML.
8269: */
8270: public Entity newResource(Entity container, Element element) {
8271: return new BaseAssignmentSubmission(element);
8272: }
8273:
8274: /**
8275: * Construct a new resource from another resource of the same type.
8276: *
8277: * @param container
8278: * The Resource that is the container for the new resource (may be null).
8279: * @param other
8280: * The other resource.
8281: * @return The new resource as a copy of the other.
8282: */
8283: public Entity newResource(Entity container, Entity other) {
8284: return new BaseAssignmentSubmission(
8285: (AssignmentSubmission) other);
8286: }
8287:
8288: /**
8289: * Construct a new continer given just an id.
8290: *
8291: * @param id
8292: * The id for the new object.
8293: * @return The new containe Resource.
8294: */
8295: public Edit newContainerEdit(String ref) {
8296: return null;
8297: }
8298:
8299: /**
8300: * Construct a new container resource, from an XML element.
8301: *
8302: * @param element
8303: * The XML.
8304: * @return The new container resource.
8305: */
8306: public Edit newContainerEdit(Element element) {
8307: return null;
8308: }
8309:
8310: /**
8311: * Construct a new container resource, as a copy of another
8312: *
8313: * @param other
8314: * The other contianer to copy.
8315: * @return The new container resource.
8316: */
8317: public Edit newContainerEdit(Entity other) {
8318: return null;
8319: }
8320:
8321: /**
8322: * Construct a new rsource given just an id.
8323: *
8324: * @param container
8325: * The Resource that is the container for the new resource (may be null).
8326: * @param id
8327: * The id for the new object.
8328: * @param others
8329: * (options) array of objects to load into the Resource's fields.
8330: * @return The new resource.
8331: */
8332: public Edit newResourceEdit(Entity container, String id,
8333: Object[] others) {
8334: BaseAssignmentSubmissionEdit e = new BaseAssignmentSubmissionEdit(
8335: id, (String) others[0], (String) others[1]);
8336: e.activate();
8337: return e;
8338: }
8339:
8340: /**
8341: * Construct a new resource, from an XML element.
8342: *
8343: * @param container
8344: * The Resource that is the container for the new resource (may be null).
8345: * @param element
8346: * The XML.
8347: * @return The new resource from the XML.
8348: */
8349: public Edit newResourceEdit(Entity container, Element element) {
8350: BaseAssignmentSubmissionEdit e = new BaseAssignmentSubmissionEdit(
8351: element);
8352: e.activate();
8353: return e;
8354: }
8355:
8356: /**
8357: * Construct a new resource from another resource of the same type.
8358: *
8359: * @param container
8360: * The Resource that is the container for the new resource (may be null).
8361: * @param other
8362: * The other resource.
8363: * @return The new resource as a copy of the other.
8364: */
8365: public Edit newResourceEdit(Entity container, Entity other) {
8366: BaseAssignmentSubmissionEdit e = new BaseAssignmentSubmissionEdit(
8367: (AssignmentSubmission) other);
8368: e.activate();
8369: return e;
8370: }
8371:
8372: /**
8373: * Collect the fields that need to be stored outside the XML (for the resource).
8374: *
8375: * @return An array of field values to store in the record outside the XML (for the resource).
8376: */
8377: public Object[] storageFields(Entity r) {
8378: Object rv[] = new Object[1];
8379: rv[0] = ((AssignmentSubmission) r).getAssignmentId();
8380: return rv;
8381: }
8382:
8383: /**
8384: * Check if this resource is in draft mode.
8385: *
8386: * @param r
8387: * The resource.
8388: * @return true if the resource is in draft mode, false if not.
8389: */
8390: public boolean isDraft(Entity r) {
8391: return false;
8392: }
8393:
8394: /**
8395: * Access the resource owner user id.
8396: *
8397: * @param r
8398: * The resource.
8399: * @return The resource owner user id.
8400: */
8401: public String getOwnerId(Entity r) {
8402: return null;
8403: }
8404:
8405: /**
8406: * Access the resource date.
8407: *
8408: * @param r
8409: * The resource.
8410: * @return The resource date.
8411: */
8412: public Time getDate(Entity r) {
8413: return null;
8414: }
8415:
8416: }// SubmissionStorageUser
8417:
8418: /**********************************************************************************************************************************************************************************************************************************************************
8419: * CacheRefresher implementations (no container)
8420: *********************************************************************************************************************************************************************************************************************************************************/
8421:
8422: /**********************************************************************************************************************************************************************************************************************************************************
8423: * AssignmentCacheRefresher implementation
8424: *********************************************************************************************************************************************************************************************************************************************************/
8425:
8426: protected class AssignmentCacheRefresher implements CacheRefresher {
8427: /**
8428: * Get a new value for this key whose value has already expired in the cache.
8429: *
8430: * @param key
8431: * The key whose value has expired and needs to be refreshed.
8432: * @param oldValue
8433: * The old expired value of the key.
8434: * @return a new value for use in the cache for this key; if null, the entry will be removed.
8435: */
8436: public Object refresh(Object key, Object oldValue, Event event) {
8437:
8438: // key is a reference, but our storage wants an id
8439: String id = assignmentId((String) key);
8440:
8441: // get whatever we have from storage for the cache for this vale
8442: Assignment assignment = m_assignmentStorage.get(id);
8443:
8444: if (M_log.isDebugEnabled())
8445: M_log.debug("refresh(): " + key + " : " + id);
8446:
8447: return assignment;
8448:
8449: } // refresh
8450:
8451: }// AssignmentCacheRefresher
8452:
8453: /**********************************************************************************************************************************************************************************************************************************************************
8454: * AssignmentContentCacheRefresher implementation
8455: *********************************************************************************************************************************************************************************************************************************************************/
8456:
8457: protected class AssignmentContentCacheRefresher implements
8458: CacheRefresher {
8459: /**
8460: * Get a new value for this key whose value has already expired in the cache.
8461: *
8462: * @param key
8463: * The key whose value has expired and needs to be refreshed.
8464: * @param oldValue
8465: * The old expired value of the key.
8466: * @return a new value for use in the cache for this key; if null, the entry will be removed.
8467: */
8468: public Object refresh(Object key, Object oldValue, Event event) {
8469:
8470: // key is a reference, but our storage wants an id
8471: String id = contentId((String) key);
8472:
8473: // get whatever we have from storage for the cache for this vale
8474: AssignmentContent content = m_contentStorage.get(id);
8475:
8476: if (M_log.isDebugEnabled())
8477: M_log.debug("refresh(): " + key + " : " + id);
8478:
8479: return content;
8480:
8481: } // refresh
8482:
8483: }// AssignmentContentCacheRefresher
8484:
8485: /**********************************************************************************************************************************************************************************************************************************************************
8486: * AssignmentSubmissionCacheRefresher implementation
8487: *********************************************************************************************************************************************************************************************************************************************************/
8488:
8489: protected class AssignmentSubmissionCacheRefresher implements
8490: CacheRefresher {
8491: /**
8492: * Get a new value for this key whose value has already expired in the cache.
8493: *
8494: * @param key
8495: * The key whose value has expired and needs to be refreshed.
8496: * @param oldValue
8497: * The old expired value of the key.
8498: * @return a new value for use in the cache for this key; if null, the entry will be removed.
8499: */
8500: public Object refresh(Object key, Object oldValue, Event event) {
8501:
8502: // key is a reference, but our storage wants an id
8503: String id = submissionId((String) key);
8504:
8505: // get whatever we have from storage for the cache for this vale
8506: AssignmentSubmission submission = m_submissionStorage
8507: .get(id);
8508:
8509: if (M_log.isDebugEnabled())
8510: M_log.debug("refresh(): " + key + " : " + id);
8511:
8512: return submission;
8513:
8514: } // refresh
8515:
8516: }// AssignmentSubmissionCacheRefresher
8517:
8518: /**
8519: * the AssignmentComparator clas
8520: */
8521: private class AssignmentComparator implements Comparator {
8522: /**
8523: * the criteria
8524: */
8525: String m_criteria = null;
8526:
8527: /**
8528: * the criteria
8529: */
8530: String m_asc = null;
8531:
8532: /**
8533: * constructor
8534: * @param criteria
8535: * The sort criteria string
8536: * @param asc
8537: * The sort order string. TRUE_STRING if ascending; "false" otherwise.
8538: */
8539: public AssignmentComparator(String criteria, String asc) {
8540: m_criteria = criteria;
8541: m_asc = asc;
8542: } // constructor
8543:
8544: /**
8545: * implementing the compare function
8546: *
8547: * @param o1
8548: * The first object
8549: * @param o2
8550: * The second object
8551: * @return The compare result. 1 is o1 < o2; -1 otherwise
8552: */
8553: public int compare(Object o1, Object o2) {
8554: int result = -1;
8555:
8556: /** *********** fo sorting assignments ****************** */
8557: if (m_criteria.equals("duedate")) {
8558: // sorted by the assignment due date
8559: Time t1 = ((Assignment) o1).getDueTime();
8560: Time t2 = ((Assignment) o2).getDueTime();
8561:
8562: if (t1 == null) {
8563: result = -1;
8564: } else if (t2 == null) {
8565: result = 1;
8566: } else if (t1.before(t2)) {
8567: result = -1;
8568: } else {
8569: result = 1;
8570: }
8571: } else if (m_criteria.equals("sortname")) {
8572: // sorted by the user's display name
8573: String s1 = null;
8574: String userId1 = (String) o1;
8575: if (userId1 != null) {
8576: try {
8577: User u1 = UserDirectoryService.getUser(userId1);
8578: s1 = u1 != null ? u1.getSortName() : null;
8579: } catch (Exception e) {
8580: if (M_log.isDebugEnabled())
8581: M_log.debug(this + e.getMessage() + " id="
8582: + userId1);
8583: }
8584: }
8585:
8586: String s2 = null;
8587: String userId2 = (String) o2;
8588: if (userId2 != null) {
8589: try {
8590: User u2 = UserDirectoryService.getUser(userId2);
8591: s2 = u2 != null ? u2.getSortName() : null;
8592: } catch (Exception e) {
8593: if (M_log.isDebugEnabled())
8594: M_log.debug(this + e.getMessage() + " id="
8595: + userId2);
8596: }
8597: }
8598:
8599: if (s1 == null) {
8600: result = -1;
8601: } else if (s2 == null) {
8602: result = 1;
8603: } else {
8604: result = s1.compareTo(s2);
8605: }
8606: }
8607:
8608: // sort ascending or descending
8609: if (m_asc.equals(Boolean.FALSE.toString())) {
8610: result = -result;
8611: }
8612: return result;
8613: }
8614: }
8615:
8616: } // BaseAssignmentService
|