Source Code Cross Referenced for BaseAssignmentService.java in  » ERP-CRM-Financial » sakai » org » sakaiproject » assignment » impl » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » ERP CRM Financial » sakai » org.sakaiproject.assignment.impl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.