Source Code Cross Referenced for ExtractionHelper.java in  » ERP-CRM-Financial » sakai » org » sakaiproject » tool » assessment » qti » helper » 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.tool.assessment.qti.helper 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**********************************************************************************
0002:         * $URL: https://source.sakaiproject.org/svn/sam/trunk/component/src/java/org/sakaiproject/tool/assessment/qti/helper/ExtractionHelper.java $
0003:         * $Id: ExtractionHelper.java 9274 2006-05-10 22:50:48Z daisyf@stanford.edu $
0004:         ***********************************************************************************
0005:         *
0006:         * Copyright (c) 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.tool.assessment.qti.helper;
0021:
0022:        import java.io.IOException;
0023:        import java.util.ArrayList;
0024:        import java.util.Calendar;
0025:        import java.util.Date;
0026:        import java.util.HashSet;
0027:        import java.util.Iterator;
0028:        import java.util.List;
0029:        import java.util.Map;
0030:        import java.util.Set;
0031:
0032:        import javax.activation.MimetypesFileTypeMap;
0033:        import javax.xml.parsers.ParserConfigurationException;
0034:
0035:        import org.apache.commons.logging.Log;
0036:        import org.apache.commons.logging.LogFactory;
0037:        import org.sakaiproject.component.cover.ServerConfigurationService;
0038:        import org.sakaiproject.content.api.ContentResource;
0039:        import org.sakaiproject.content.cover.ContentHostingService;
0040:        import org.sakaiproject.tool.assessment.data.dao.assessment.Answer;
0041:        import org.sakaiproject.tool.assessment.data.dao.assessment.AnswerFeedback;
0042:        import org.sakaiproject.tool.assessment.data.dao.assessment.AssessmentAccessControl;
0043:        import org.sakaiproject.tool.assessment.data.dao.assessment.AssessmentFeedback;
0044:        import org.sakaiproject.tool.assessment.data.dao.assessment.EvaluationModel;
0045:        import org.sakaiproject.tool.assessment.data.dao.assessment.ItemText;
0046:        import org.sakaiproject.tool.assessment.data.dao.assessment.SecuredIPAddress;
0047:        import org.sakaiproject.tool.assessment.data.ifc.assessment.AnswerFeedbackIfc;
0048:        import org.sakaiproject.tool.assessment.data.ifc.assessment.AssessmentAccessControlIfc;
0049:        import org.sakaiproject.tool.assessment.data.ifc.assessment.AssessmentAttachmentIfc;
0050:        import org.sakaiproject.tool.assessment.data.ifc.assessment.AssessmentBaseIfc;
0051:        import org.sakaiproject.tool.assessment.data.ifc.assessment.AssessmentIfc;
0052:        import org.sakaiproject.tool.assessment.data.ifc.assessment.ItemAttachmentIfc;
0053:        import org.sakaiproject.tool.assessment.data.ifc.assessment.ItemDataIfc;
0054:        import org.sakaiproject.tool.assessment.data.ifc.assessment.SectionAttachmentIfc;
0055:        import org.sakaiproject.tool.assessment.data.ifc.shared.TypeIfc;
0056:        import org.sakaiproject.tool.assessment.facade.AssessmentFacade;
0057:        import org.sakaiproject.tool.assessment.facade.ItemFacade;
0058:        import org.sakaiproject.tool.assessment.facade.QuestionPoolFacade;
0059:        import org.sakaiproject.tool.assessment.facade.SectionFacade;
0060:        import org.sakaiproject.tool.assessment.qti.asi.ASIBaseClass;
0061:        import org.sakaiproject.tool.assessment.qti.asi.Assessment;
0062:        import org.sakaiproject.tool.assessment.qti.asi.Item;
0063:        import org.sakaiproject.tool.assessment.qti.asi.Section;
0064:        import org.sakaiproject.tool.assessment.qti.constants.AuthoringConstantStrings;
0065:        import org.sakaiproject.tool.assessment.qti.constants.QTIVersion;
0066:        import org.sakaiproject.tool.assessment.qti.exception.Iso8601FormatException;
0067:        import org.sakaiproject.tool.assessment.qti.helper.item.ItemTypeExtractionStrategy;
0068:        import org.sakaiproject.tool.assessment.qti.util.Iso8601DateFormat;
0069:        import org.sakaiproject.tool.assessment.qti.util.Iso8601TimeInterval;
0070:        import org.sakaiproject.tool.assessment.qti.util.XmlMapper;
0071:        import org.sakaiproject.tool.assessment.qti.util.XmlUtil;
0072:        import org.sakaiproject.tool.assessment.services.assessment.AssessmentService;
0073:        import org.sakaiproject.tool.cover.ToolManager;
0074:        import org.sakaiproject.user.api.User;
0075:        import org.sakaiproject.user.cover.UserDirectoryService;
0076:        import org.w3c.dom.DOMException;
0077:        import org.w3c.dom.Document;
0078:        import org.w3c.dom.Node;
0079:        import org.xml.sax.SAXException;
0080:
0081:        /**
0082:         * <p>Has helper methods for data extraction (import) from QTI</p>
0083:         * <p> </p>
0084:         * <p>Copyright: Copyright (c) 2005 Sakai</p>
0085:         * @author Ed Smiley esmiley@stanford.edu
0086:         * @version $Id: ExtractionHelper.java 9274 2006-05-10 22:50:48Z daisyf@stanford.edu $
0087:         */
0088:
0089:        public class ExtractionHelper {
0090:            private static final String QTI_VERSION_1_2_PATH = "v1p2";
0091:            private static final String QTI_VERSION_2_0_PATH = "v2p0";
0092:            private static final String TRANSFORM_PATH = "xml/xsl/dataTransform/import";
0093:
0094:            private static final String ASSESSMENT_TRANSFORM = "extractAssessment.xsl";
0095:            private static final String SECTION_TRANSFORM = "extractSection.xsl";
0096:            private static final String ITEM_TRANSFORM = "extractItem.xsl";
0097:            private static Log log = LogFactory.getLog(ExtractionHelper.class);
0098:
0099:            private int qtiVersion = QTIVersion.VERSION_1_2;
0100:            private String overridePath = null; // override defaults and settings
0101:            private String FIB_BLANK_INDICATOR = " {} ";
0102:
0103:            private String unzipLocation;
0104:
0105:            // versioning title string that it will look for/use, followed by a number
0106:            private static final String VERSION_START = "  - ";
0107:
0108:            /**
0109:             * @deprecated
0110:             */
0111:            public ExtractionHelper() {
0112:                this .setQtiVersion(QTIVersion.VERSION_1_2);
0113:
0114:            }
0115:
0116:            /**
0117:             * Get ExtractionHelper for QTIVersion.VERSION_1_2
0118:             * or QTIVersion.VERSION_2_0
0119:             * @param qtiVersion
0120:             */
0121:            public ExtractionHelper(int qtiVersion) {
0122:                this .setQtiVersion(qtiVersion);
0123:            }
0124:
0125:            /**
0126:             * Path to XSL transform code.
0127:             * @return context-relative path to XSL transform code.
0128:             */
0129:            public String getTransformPath() {
0130:                // first check to see if normal computed path has been overridden
0131:                if (overridePath != null) {
0132:                    return overridePath;
0133:                }
0134:
0135:                return TRANSFORM_PATH + "/" + getQtiPath();
0136:            }
0137:
0138:            private String getQtiPath() {
0139:                return qtiVersion == QTIVersion.VERSION_1_2 ? QTI_VERSION_1_2_PATH
0140:                        : QTI_VERSION_2_0_PATH;
0141:            }
0142:
0143:            /**
0144:             * Get QTI version flag.
0145:             * Either QTIVersion.VERSION_1_2 or QTIVersion.VERSION_2_0;
0146:             * @return QTI version flag
0147:             */
0148:            public int getQtiVersion() {
0149:                return qtiVersion;
0150:            }
0151:
0152:            /**
0153:             * Set QTI version flag.
0154:             * Either QTIVersion.VERSION_1_2 or QTIVersion.VERSION_2_0;
0155:             * @param qtiVersion
0156:             */
0157:            public void setQtiVersion(int qtiVersion) {
0158:                if (!QTIVersion.isValid(qtiVersion)) {
0159:                    throw new IllegalArgumentException("NOT Legal Qti Version.");
0160:                }
0161:                this .qtiVersion = qtiVersion;
0162:            }
0163:
0164:            /**
0165:             * Get an XML document for the transform
0166:             * @param template
0167:             * @return
0168:             */
0169:            public Document getTransformDocument(String template) {
0170:                //Document document = null;
0171:
0172:                if (!isOKtransform(template)) {
0173:                    throw new IllegalArgumentException("NOT valid template.");
0174:                }
0175:                String templateContextPath = this .getTransformPath() + "/"
0176:                        + template;
0177:                return XmlUtil.readDocument(templateContextPath);
0178:            }
0179:
0180:            /**
0181:             * Get map of data to set from assessment XML
0182:             * @param assessmentXml
0183:             * @return a Map
0184:             */
0185:            public Map mapAssessment(Assessment assessmentXml) {
0186:                log.debug("inside: mapAssessment");
0187:                return map(ASSESSMENT_TRANSFORM, assessmentXml);
0188:            }
0189:
0190:            /**
0191:             * Get map of data to set from section XML
0192:             * @param sectionXml
0193:             * @return a Map
0194:             */
0195:            public Map mapSection(Section sectionXml) {
0196:                return map(SECTION_TRANSFORM, sectionXml);
0197:            }
0198:
0199:            /**
0200:             * Get map of data to set from item XML
0201:             * @param itemXml
0202:             * @return a Map
0203:             */
0204:            public Map mapItem(Item itemXml) {
0205:                return map(ITEM_TRANSFORM, itemXml);
0206:            }
0207:
0208:            /**
0209:             * Helper method
0210:             * @param transformType ASSESSMENT_TRANSFORM, SECTION_TRANSFORM, ITEM_TRANSFORM
0211:             * @param asi ASIBaseClass: Assessment, Section, or Item XML
0212:             * @return
0213:             */
0214:            private Map map(String transformType, ASIBaseClass asi) {
0215:                if (!isOKasi(asi)) {
0216:                    throw new IllegalArgumentException(
0217:                            "Incorrect ASI subclass.");
0218:                }
0219:                if (!isOKtransform(transformType)) {
0220:                    throw new IllegalArgumentException("Incorrect transform: "
0221:                            + transformType + ".");
0222:                }
0223:                Map map = null;
0224:                try {
0225:                    Document transform = getTransformDocument(transformType);
0226:                    Document xml = asi.getDocument();
0227:                    Document model = XmlUtil.transformDocument(xml, transform);
0228:                    map = XmlMapper.map(model);
0229:                } catch (IOException ex) {
0230:                    log.error(ex);
0231:                    ex.printStackTrace(System.out);
0232:                } catch (SAXException ex) {
0233:                    log.error(ex);
0234:                    ex.printStackTrace(System.out);
0235:                } catch (ParserConfigurationException ex) {
0236:                    log.error(ex);
0237:                    ex.printStackTrace(System.out);
0238:                }
0239:                return map;
0240:
0241:            }
0242:
0243:            /**
0244:             * Look up a List of Section XML from Assessment Xml
0245:             * @return a List of Section XML objects
0246:             */
0247:            public List getSectionXmlList(Assessment assessmentXml) {
0248:                List nodeList = assessmentXml.selectNodes("//section");
0249:                List sectionXmlList = new ArrayList();
0250:
0251:                // now convert our list of Nodes to a list of section xml
0252:                for (int i = 0; i < nodeList.size(); i++) {
0253:                    try {
0254:                        Node node = (Node) nodeList.get(i);
0255:                        // create a document for a section xml object
0256:                        Document sectionDoc = XmlUtil.createDocument();
0257:                        // Make a copy for inserting into the new document
0258:                        Node importNode = sectionDoc.importNode(node, true);
0259:                        // Insert the copy into sectionDoc
0260:                        sectionDoc.appendChild(importNode);
0261:                        Section sectionXml = new Section(sectionDoc, this 
0262:                                .getQtiVersion());
0263:                        // add the new section xml object to the list
0264:                        sectionXmlList.add(sectionXml);
0265:                    } catch (DOMException ex) {
0266:                        log.error(ex);
0267:                        ex.printStackTrace(System.out);
0268:                    }
0269:                }
0270:                return sectionXmlList;
0271:            }
0272:
0273:            /**
0274:             * Look up a List of Item XML from Section Xml
0275:             * @param Section sectionXml
0276:             * @return a List of Item XML objects
0277:             */
0278:            public List getItemXmlList(Section sectionXml) {
0279:                String itemElementName = qtiVersion == QTIVersion.VERSION_1_2 ? "//item"
0280:                        : "//assessmentItem";
0281:
0282:                // now convert our list of Nodes to a list of section xml
0283:                List nodeList = sectionXml.selectNodes(itemElementName);
0284:                List itemXmlList = new ArrayList();
0285:                for (int i = 0; i < nodeList.size(); i++) {
0286:                    try {
0287:                        Node node = (Node) nodeList.get(i);
0288:                        // create a document for a item xml object
0289:                        Document itemDoc = XmlUtil.createDocument();
0290:                        // Make a copy for inserting into the new document
0291:                        Node importNode = itemDoc.importNode(node, true);
0292:                        // Insert the copy into itemDoc
0293:                        itemDoc.appendChild(importNode);
0294:                        Item itemXml = new Item(itemDoc, this .getQtiVersion());
0295:                        // add the new section xml object to the list
0296:                        itemXmlList.add(itemXml);
0297:                    } catch (DOMException ex) {
0298:                        log.error(ex);
0299:                        ex.printStackTrace(System.out);
0300:                    }
0301:                }
0302:                return itemXmlList;
0303:            }
0304:
0305:            /**
0306:             * Used internally.
0307:             * @param transform
0308:             * @return true if OK
0309:             */
0310:            private boolean isOKtransform(String transform) {
0311:                return (transform == this .ASSESSMENT_TRANSFORM
0312:                        || transform == this .SECTION_TRANSFORM || transform == this .ITEM_TRANSFORM) ? true
0313:                        : false;
0314:            }
0315:
0316:            /**
0317:             * Used internally.
0318:             * @param asi
0319:             * @return true if OK
0320:             */
0321:            private boolean isOKasi(ASIBaseClass asi) {
0322:                return (asi instanceof  Assessment || asi instanceof  Section || asi instanceof  Item) ? true
0323:                        : false;
0324:            }
0325:
0326:            //  /**
0327:            //   * Create assessment from the extracted properties.
0328:            //   * @param assessmentMap the extracted properties
0329:            //   * @return an assessment, which has been persisted
0330:            //   */
0331:            //  public AssessmentFacade createAssessment(Map assessmentMap)
0332:            //  {
0333:            //    String description = (String) assessmentMap.get("description");
0334:            //    String title = (String) assessmentMap.get("title");
0335:            //    AssessmentService assessmentService = new AssessmentService();
0336:            //    AssessmentFacade assessment = assessmentService.createAssessment(
0337:            //        title, description, null, null);
0338:            //    return assessment;
0339:            //  }
0340:
0341:            /**
0342:             * Update assessment from the extracted properties.
0343:             * Note: you need to do a save when you are done.
0344:             * @param assessment the assessment, which will  be persisted
0345:             * @param assessmentMap the extracted properties
0346:             */
0347:            public void updateAssessment(AssessmentFacade assessment,
0348:                    Map assessmentMap) {
0349:                String title;
0350:                String displayName;
0351:                String description;
0352:                String comments;
0353:
0354:                String instructorNotification;
0355:                String testeeNotification;
0356:                String multipartAllowed;
0357:                String createdBy;
0358:                String createdDate;
0359:
0360:                title = (String) assessmentMap.get("title");
0361:                displayName = (String) assessmentMap.get("title");
0362:                comments = (String) assessmentMap.get("comments");
0363:
0364:                log.debug("ASSESSMENT updating metadata information");
0365:                // set meta data
0366:                List metalist = (List) assessmentMap.get("metadata");
0367:                MetaDataList metadataList = new MetaDataList(metalist);
0368:                metadataList.setDefaults(assessment);
0369:                metadataList.addTo(assessment);
0370:                createdBy = assessment.getAssessmentMetaDataByLabel("CREATOR");
0371:
0372:                log.debug("ASSESSMENT updating basic information");
0373:                // set basic properties
0374:                assessment.setCreatedBy(createdBy);
0375:                assessment.setComments(comments);
0376:                assessment.setCreatedDate(new Date());
0377:                assessment.setLastModifiedBy("Sakai Import");
0378:                assessment.setLastModifiedDate(new Date());
0379:
0380:                // additional information
0381:
0382:                // restricted IP address
0383:                log
0384:                        .debug("ASSESSMENT updating access control, evaluation model, feedback");
0385:
0386:                // access control
0387:                String duration = (String) assessmentMap.get("duration");
0388:                log.debug("duration: " + duration);
0389:
0390:                makeAccessControl(assessment, duration);
0391:                String submissionMsg = metadataList.getSubmissionMessage();
0392:                updateSubmissionMessage(assessment, submissionMsg);
0393:
0394:                // evaluation model control
0395:                makeEvaluationModel(assessment);
0396:
0397:                // assessment feedback control
0398:                makeAssessmentFeedback(assessment);
0399:
0400:            }
0401:
0402:            /**
0403:             * Put feedback settings into assessment (bi-directional)
0404:             * @param assessment
0405:             */
0406:            private void makeAssessmentFeedback(AssessmentFacade assessment) {
0407:                AssessmentFeedback feedback = (AssessmentFeedback) assessment
0408:                        .getAssessmentFeedback();
0409:                if (feedback == null) {
0410:                    feedback = new AssessmentFeedback();
0411:                    // Need to fix AssessmentFeedback so it can take AssessmentFacade later
0412:                    feedback.setAssessmentBase(assessment.getData());
0413:                }
0414:
0415:                if ("TRUE"
0416:                        .equalsIgnoreCase(assessment
0417:                                .getAssessmentMetaDataByLabel("FEEDBACK_SHOW_QUESTION"))) {
0418:                    feedback.setShowQuestionText(Boolean.TRUE);
0419:                } else {
0420:                    feedback.setShowQuestionText(Boolean.FALSE);
0421:                }
0422:
0423:                if ("TRUE"
0424:                        .equalsIgnoreCase(assessment
0425:                                .getAssessmentMetaDataByLabel("FEEDBACK_SHOW_RESPONSE"))) {
0426:                    feedback.setShowStudentResponse(Boolean.TRUE);
0427:                } else {
0428:                    feedback.setShowStudentResponse(Boolean.FALSE);
0429:                }
0430:
0431:                if ("TRUE"
0432:                        .equalsIgnoreCase(assessment
0433:                                .getAssessmentMetaDataByLabel("FEEDBACK_SHOW_CORRECT_RESPONSE"))) {
0434:                    feedback.setShowCorrectResponse(Boolean.TRUE);
0435:                } else {
0436:                    feedback.setShowCorrectResponse(Boolean.FALSE);
0437:                }
0438:
0439:                if ("TRUE"
0440:                        .equalsIgnoreCase(assessment
0441:                                .getAssessmentMetaDataByLabel("FEEDBACK_SHOW_STUDENT_SCORE"))) {
0442:                    feedback.setShowStudentScore(Boolean.TRUE);
0443:                } else {
0444:                    feedback.setShowStudentScore(Boolean.FALSE);
0445:                }
0446:
0447:                if ("TRUE"
0448:                        .equalsIgnoreCase(assessment
0449:                                .getAssessmentMetaDataByLabel("FEEDBACK_SHOW_STUDENT_QUESTIONSCORE"))) {
0450:                    feedback.setShowStudentQuestionScore(Boolean.TRUE);
0451:                } else {
0452:                    feedback.setShowStudentQuestionScore(Boolean.FALSE);
0453:                }
0454:
0455:                if ("TRUE"
0456:                        .equalsIgnoreCase(assessment
0457:                                .getAssessmentMetaDataByLabel("FEEDBACK_SHOW_ITEM_LEVEL"))) {
0458:                    feedback.setShowQuestionLevelFeedback(Boolean.TRUE);
0459:                } else {
0460:                    feedback.setShowQuestionLevelFeedback(Boolean.FALSE);
0461:                }
0462:
0463:                if ("TRUE"
0464:                        .equalsIgnoreCase(assessment
0465:                                .getAssessmentMetaDataByLabel("FEEDBACK_SHOW_SELECTION_LEVEL"))) {
0466:                    feedback.setShowSelectionLevelFeedback(Boolean.TRUE);
0467:                } else {
0468:                    feedback.setShowSelectionLevelFeedback(Boolean.FALSE);
0469:                }
0470:
0471:                if ("TRUE"
0472:                        .equalsIgnoreCase(assessment
0473:                                .getAssessmentMetaDataByLabel("FEEDBACK_SHOW_GRADER_COMMENT"))) {
0474:                    feedback.setShowGraderComments(Boolean.TRUE);
0475:                } else {
0476:                    feedback.setShowGraderComments(Boolean.FALSE);
0477:                }
0478:
0479:                if ("TRUE".equalsIgnoreCase(assessment
0480:                        .getAssessmentMetaDataByLabel("FEEDBACK_SHOW_STATS"))) {
0481:                    feedback.setShowStatistics(Boolean.TRUE);
0482:                } else {
0483:                    feedback.setShowStatistics(Boolean.FALSE);
0484:                }
0485:
0486:                if (this 
0487:                        .notNullOrEmpty(assessment
0488:                                .getAssessmentMetaDataByLabel("FEEDBACK_DELIVERY_DATE"))
0489:                        || "DATED"
0490:                                .equalsIgnoreCase(assessment
0491:                                        .getAssessmentMetaDataByLabel("FEEDBACK_DELIVERY"))) {
0492:                    feedback.setFeedbackDelivery(feedback.FEEDBACK_BY_DATE);
0493:                } else if ("IMMEDIATE".equalsIgnoreCase(assessment
0494:                        .getAssessmentMetaDataByLabel("FEEDBACK_DELIVERY"))) {
0495:                    feedback.setFeedbackDelivery(feedback.IMMEDIATE_FEEDBACK);
0496:                } else {
0497:                    feedback.setFeedbackDelivery(feedback.NO_FEEDBACK);
0498:                }
0499:
0500:                if ("QUESTION".equalsIgnoreCase(assessment
0501:                        .getAssessmentMetaDataByLabel("FEEDBACK_AUTHORING"))) {
0502:                    feedback
0503:                            .setFeedbackAuthoring(feedback.QUESTIONLEVEL_FEEDBACK);
0504:                } else if ("SECTION".equalsIgnoreCase(assessment
0505:                        .getAssessmentMetaDataByLabel("FEEDBACK_AUTHORING"))) {
0506:                    feedback
0507:                            .setFeedbackAuthoring(feedback.SECTIONLEVEL_FEEDBACK);
0508:                } else {
0509:                    feedback.setFeedbackAuthoring(feedback.BOTH_FEEDBACK);
0510:                }
0511:
0512:                assessment.setAssessmentFeedback(feedback);
0513:            }
0514:
0515:            /**
0516:             * Put evaluation settings into assessment (bi-directional)
0517:             * @param assessment
0518:             */
0519:            private void makeEvaluationModel(AssessmentFacade assessment) {
0520:                EvaluationModel evaluationModel = (EvaluationModel) assessment
0521:                        .getEvaluationModel();
0522:                if (evaluationModel == null) {
0523:                    evaluationModel = new EvaluationModel();
0524:                    // Need to fix EvaluationModel so it can take AssessmentFacade later
0525:                    evaluationModel.setAssessmentBase(assessment.getData());
0526:                }
0527:
0528:                // anonymous
0529:                if ("TRUE".equalsIgnoreCase(assessment
0530:                        .getAssessmentMetaDataByLabel("ANONYMOUS_GRADING"))) {
0531:                    evaluationModel
0532:                            .setAnonymousGrading(EvaluationModel.ANONYMOUS_GRADING);
0533:                } else {
0534:                    evaluationModel
0535:                            .setAnonymousGrading(EvaluationModel.NON_ANONYMOUS_GRADING);
0536:                }
0537:
0538:                // gradebook options, don't know how this is supposed to work, leave alone for now
0539:                if ("DEFAULT".equalsIgnoreCase(assessment
0540:                        .getAssessmentMetaDataByLabel("GRADEBOOK_OPTIONS"))) {
0541:                    evaluationModel
0542:                            .setToGradeBook(EvaluationModel.TO_DEFAULT_GRADEBOOK
0543:                                    .toString());
0544:                } else if ("SELECTED".equalsIgnoreCase(assessment
0545:                        .getAssessmentMetaDataByLabel("GRADEBOOK_OPTIONS"))) {
0546:                    evaluationModel
0547:                            .setToGradeBook(EvaluationModel.NOT_TO_GRADEBOOK
0548:                                    .toString()); // this is for backward compatibility. 
0549:                    // we've always used 2 for 'None' option. Old exported XML will have 'SELECTED' for assessemnts that are set not to send to gradebook, so we need to accomodate those.
0550:                    // TO_SELECTED_GRADEBOOK is not really used. 
0551:                }
0552:                //  SAK-7162
0553:                else if ("NONE".equalsIgnoreCase(assessment
0554:                        .getAssessmentMetaDataByLabel("GRADEBOOK_OPTIONS"))) {
0555:                    evaluationModel
0556:                            .setToGradeBook(EvaluationModel.NOT_TO_GRADEBOOK
0557:                                    .toString());
0558:                }
0559:
0560:                // highest or last
0561:                if ("HIGHEST_SCORE".equalsIgnoreCase(assessment
0562:                        .getAssessmentMetaDataByLabel("GRADE_SCORE"))) {
0563:                    evaluationModel
0564:                            .setScoringType(EvaluationModel.HIGHEST_SCORE);
0565:                }
0566:                /*
0567:                   // not implementing average for now
0568:                else if ("AVERAGE".equalsIgnoreCase(assessment.getAssessmentMetaDataByLabel(
0569:                    "GRADE_SCORE")))
0570:                {
0571:                  evaluationModel.setScoringType(EvaluationModel.AVERAGE_SCORE);
0572:                }
0573:                 */
0574:                else if ("LAST_SCORE".equalsIgnoreCase(assessment
0575:                        .getAssessmentMetaDataByLabel("GRADE_SCORE"))) {
0576:                    evaluationModel.setScoringType(EvaluationModel.LAST_SCORE);
0577:                }
0578:                assessment.setEvaluationModel(evaluationModel);
0579:            }
0580:
0581:            private void updateSubmissionMessage(AssessmentFacade assessment,
0582:                    String submissionMsg) {
0583:                AssessmentAccessControl control = (AssessmentAccessControl) assessment
0584:                        .getAssessmentAccessControl();
0585:                if (control == null) {
0586:                    control = new AssessmentAccessControl();
0587:                    // need to fix accessControl so it can take AssessmentFacade later
0588:                    control.setAssessmentBase(assessment.getData());
0589:                }
0590:                if (submissionMsg != null) {
0591:                    control
0592:                            .setSubmissionMessage(makeFCKAttachment(submissionMsg));
0593:                }
0594:
0595:            }
0596:
0597:            /**
0598:             * Put access control settings into assessment (bi-directional)
0599:             * @param assessment
0600:             * @param duration Time interval for timed assessment (Iso8601 format)
0601:             */
0602:            private void makeAccessControl(AssessmentFacade assessment,
0603:                    String duration) {
0604:                AssessmentAccessControl control = (AssessmentAccessControl) assessment
0605:                        .getAssessmentAccessControl();
0606:                if (control == null) {
0607:                    control = new AssessmentAccessControl();
0608:                    // need to fix accessControl so it can take AssessmentFacade later
0609:                    control.setAssessmentBase(assessment.getData());
0610:                }
0611:
0612:                // Control dates
0613:                Iso8601DateFormat iso = new Iso8601DateFormat();
0614:                String startDate = assessment
0615:                        .getAssessmentMetaDataByLabel("START_DATE");
0616:                String dueDate = assessment
0617:                        .getAssessmentMetaDataByLabel("END_DATE");
0618:                String retractDate = assessment
0619:                        .getAssessmentMetaDataByLabel("RETRACT_DATE");
0620:                String feedbackDate = assessment
0621:                        .getAssessmentMetaDataByLabel("FEEDBACK_DELIVERY_DATE");
0622:
0623:                try {
0624:                    control.setStartDate(iso.parse(startDate).getTime());
0625:                    assessment.getData().addAssessmentMetaData(
0626:                            "hasAvailableDate", "true");
0627:
0628:                } catch (Iso8601FormatException ex) {
0629:                    log.debug("Cannot set startDate.");
0630:                }
0631:                try {
0632:                    control.setDueDate(iso.parse(dueDate).getTime());
0633:                    //      assessment.getData().addAssessmentMetaData("hasDueDate", "true");
0634:                    assessment.getData().addAssessmentMetaData("dueDate",
0635:                            "true");
0636:                } catch (Iso8601FormatException ex) {
0637:                    log.debug("Cannot set dueDate.");
0638:                }
0639:                try {
0640:                    control.setRetractDate(iso.parse(retractDate).getTime());
0641:                    assessment.getData().addAssessmentMetaData(
0642:                            "hasRetractDate", "true");
0643:                } catch (Iso8601FormatException ex) {
0644:                    log.debug("Cannot set retractDate.");
0645:                }
0646:                try {
0647:                    control.setFeedbackDate(iso.parse(feedbackDate).getTime());
0648:                    assessment.getData().addAssessmentMetaData(
0649:                            "FEEDBACK_DELIVERY", "DATED");
0650:                } catch (Iso8601FormatException ex) {
0651:                    log.debug("Cannot set feedbackDate.");
0652:                }
0653:
0654:                // don't know what site you will have in a new environment
0655:                // but registered as a BUG in SAM-271 so turning it on.
0656:
0657:                String releasedTo = assessment
0658:                        .getAssessmentMetaDataByLabel("ASSESSMENT_RELEASED_TO");
0659:
0660:                // for backwards compatibility with version 1.5 exports.
0661:                if (releasedTo != null
0662:                        && releasedTo.indexOf("Authenticated Users") > -1) {
0663:                    log
0664:                            .debug("Fixing obsolete reference to 'Authenticated Users', setting released to 'Anonymous Users'.");
0665:                    releasedTo = AuthoringConstantStrings.ANONYMOUS;
0666:                }
0667:
0668:                // for backwards compatibility with version 1.5 exports.
0669:                if (releasedTo != null
0670:                        && releasedTo.indexOf("Authenticated Users") > -1) {
0671:                    log
0672:                            .debug("Fixing obsolete reference to 'Authenticated Users', setting released to 'Anonymous Users'.");
0673:                    releasedTo = AuthoringConstantStrings.ANONYMOUS;
0674:                }
0675:
0676:                log.debug("control.setReleaseTo(releasedTo)='" + releasedTo
0677:                        + "'.");
0678:                control.setReleaseTo(releasedTo);
0679:
0680:                // Timed Assessment
0681:                if (duration != null) {
0682:                    try {
0683:                        Iso8601TimeInterval tiso = new Iso8601TimeInterval(
0684:                                duration);
0685:                        log.debug("tiso.getDuration(): " + tiso.getDuration());
0686:
0687:                        if (tiso == null) {
0688:                            throw new Iso8601FormatException(
0689:                                    "Assessment duration could not be resolved.");
0690:                        }
0691:                        long millisecondsDuration = tiso.getDuration();
0692:                        int seconds = (int) millisecondsDuration / 1000;
0693:                        control.setTimeLimit(new Integer(seconds));
0694:                        if (seconds != 0) {
0695:                            control
0696:                                    .setTimedAssessment(AssessmentAccessControl.TIMED_ASSESSMENT);
0697:                            assessment.getData().addAssessmentMetaData(
0698:                                    "hasTimeAssessment", "true");
0699:                        } else {
0700:                            control.setTimeLimit(new Integer(0));
0701:                            control
0702:                                    .setTimedAssessment(AssessmentAccessControl.DO_NOT_TIMED_ASSESSMENT);
0703:                        }
0704:                    } catch (Iso8601FormatException ex) {
0705:                        log.warn("Can't format assessment duration. " + ex);
0706:                        control.setTimeLimit(new Integer(0));
0707:                        control
0708:                                .setTimedAssessment(AssessmentAccessControl.DO_NOT_TIMED_ASSESSMENT);
0709:                    }
0710:                } else {
0711:                    control.setTimeLimit(new Integer(0));
0712:                    control
0713:                            .setTimedAssessment(AssessmentAccessControl.DO_NOT_TIMED_ASSESSMENT);
0714:                }
0715:
0716:                log
0717:                        .debug("assessment.getAssessmentMetaDataByLabel(AUTO_SUBMIT): "
0718:                                + assessment
0719:                                        .getAssessmentMetaDataByLabel("AUTO_SUBMIT"));
0720:
0721:                if ("TRUE".equalsIgnoreCase(assessment
0722:                        .getAssessmentMetaDataByLabel("AUTO_SUBMIT"))) {
0723:                    log.debug("AUTO SUBMIT IS TRUE");
0724:                    control.setAutoSubmit(AssessmentAccessControl.AUTO_SUBMIT);
0725:                    assessment.getData().addAssessmentMetaData("hasAutoSubmit",
0726:                            "true");
0727:                } else {
0728:                    control
0729:                            .setAutoSubmit(AssessmentAccessControl.DO_NOT_AUTO_SUBMIT);
0730:                }
0731:
0732:                // Assessment Organization
0733:                // navigation
0734:                if ("LINEAR".equalsIgnoreCase(assessment
0735:                        .getAssessmentMetaDataByLabel("NAVIGATION"))) {
0736:                    control.setItemNavigation(control.LINEAR_ACCESS);
0737:                } else {
0738:                    control.setItemNavigation(control.RANDOM_ACCESS);
0739:                }
0740:
0741:                // numbering
0742:                if ("CONTINUOUS".equalsIgnoreCase(assessment
0743:                        .getAssessmentMetaDataByLabel("QUESTION_NUMBERING"))) {
0744:                    control.setItemNumbering(control.CONTINUOUS_NUMBERING);
0745:                } else if ("RESTART".equalsIgnoreCase(assessment
0746:                        .getAssessmentMetaDataByLabel("QUESTION_NUMBERING"))) {
0747:                    control.setItemNumbering(control.RESTART_NUMBERING_BY_PART);
0748:                }
0749:
0750:                //question layout
0751:                if ("I".equalsIgnoreCase(assessment
0752:                        .getAssessmentMetaDataByLabel("QUESTION_LAYOUT"))) {
0753:                    control.setAssessmentFormat(control.BY_QUESTION);
0754:                } else if ("S".equalsIgnoreCase(assessment
0755:                        .getAssessmentMetaDataByLabel("QUESTION_LAYOUT"))) {
0756:                    control.setAssessmentFormat(control.BY_PART);
0757:                } else {
0758:                    control.setAssessmentFormat(control.BY_ASSESSMENT);
0759:                }
0760:
0761:                //Submissions
0762:                // submissions allowed
0763:                String maxAttempts = ""
0764:                        + assessment
0765:                                .getAssessmentMetaDataByLabel("MAX_ATTEMPTS");
0766:                String unlimited = AuthoringConstantStrings.UNLIMITED_SUBMISSIONS;
0767:                log.debug("maxAttempts: '" + maxAttempts + "'");
0768:                log.debug("unlimited: '" + unlimited + "'");
0769:
0770:                if (unlimited.equals(maxAttempts.trim())) {
0771:                    log.debug("unlimited.equals(maxAttempts.trim()");
0772:                    control.setUnlimitedSubmissions(Boolean.TRUE);
0773:                    control
0774:                            .setSubmissionsAllowed(AssessmentAccessControlIfc.UNLIMITED_SUBMISSIONS);
0775:                } else {
0776:                    control.setUnlimitedSubmissions(Boolean.FALSE);
0777:                    try {
0778:                        control.setSubmissionsAllowed(new Integer(maxAttempts));
0779:                    } catch (NumberFormatException ex1) {
0780:                        control.setSubmissionsAllowed(new Integer("1"));
0781:                    }
0782:                }
0783:                log.debug("Set: control.getSubmissionsAllowed()="
0784:                        + control.getSubmissionsAllowed());
0785:                log.debug("Set: control.getUnlimitedSubmissions()="
0786:                        + control.getUnlimitedSubmissions());
0787:
0788:                // late submissions
0789:                // I am puzzled as to why there is no ACCEPT_LATE_SUBMISSION, assuming it =T
0790:                if ("FALSE".equalsIgnoreCase(assessment
0791:                        .getAssessmentMetaDataByLabel("LATE_HANDLING"))) {
0792:                    control.setLateHandling(control.NOT_ACCEPT_LATE_SUBMISSION);
0793:                } else {
0794:                    control.setLateHandling(new Integer(1));
0795:
0796:                }
0797:
0798:                // auto save
0799:                if ("TRUE".equalsIgnoreCase(assessment
0800:                        .getAssessmentMetaDataByLabel("AUTO_SAVE"))) {
0801:                    control.setAutoSubmit(control.AUTO_SAVE);
0802:                }
0803:
0804:                // Submission Message
0805:                /*
0806:                String submissionMessage = assessment.getAssessmentMetaDataByLabel(
0807:                    "SUBMISSION_MESSAGE");
0808:                if (submissionMessage != null)
0809:                {
0810:                  control.setSubmissionMessage(submissionMessage);
0811:                }
0812:                 */
0813:
0814:                // Username, password, finalPageUrl
0815:                //    String considerUserId = assessment.getAssessmentMetaDataByLabel(
0816:                //        "CONSIDER_USERID"); //
0817:                String userId = assessment
0818:                        .getAssessmentMetaDataByLabel("USERID");
0819:                String password = assessment
0820:                        .getAssessmentMetaDataByLabel("PASSWORD");
0821:                String finalPageUrl = assessment
0822:                        .getAssessmentMetaDataByLabel("FINISH_URL");
0823:
0824:                if (//"TRUE".equalsIgnoreCase(considerUserId) &&
0825:                notNullOrEmpty(userId) && notNullOrEmpty(password)) {
0826:                    control.setUsername(userId);
0827:                    control.setPassword(password);
0828:                    assessment.getData().addAssessmentMetaData(
0829:                            "hasUsernamePassword", "true");
0830:                }
0831:                control.setFinalPageUrl(finalPageUrl);
0832:
0833:                assessment.setAssessmentAccessControl(control);
0834:            }
0835:
0836:            /**
0837:             * the ip address is in a newline delimited string
0838:             * @param assessment
0839:             */
0840:            public void makeSecuredIPAddressSet(AssessmentFacade assessment,
0841:                    String ipList) {
0842:                Set securedIPAddressSet = (Set) assessment
0843:                        .getSecuredIPAddressSet();
0844:                AssessmentBaseIfc data = assessment.getData();
0845:
0846:                if (securedIPAddressSet == null) {
0847:                    securedIPAddressSet = new HashSet();
0848:                }
0849:                //log.info("Getting securedIPAddressSet=" + securedIPAddressSet);
0850:
0851:                //log.info("ipList: " + ipList);
0852:
0853:                if (ipList == null)
0854:                    ipList = "";
0855:                String[] ip = ipList.split("\\n");
0856:
0857:                for (int j = 0; j < ip.length; j++) {
0858:                    //log.info("ip # " + j + ": " + ip[j]);
0859:                    if (ip[j] != null) {
0860:                        SecuredIPAddress sip = new SecuredIPAddress(data, null,
0861:                                ip[j]);
0862:                        //sip.setAssessment(data);
0863:                        securedIPAddressSet.add(sip);
0864:                    }
0865:                }
0866:
0867:                //log.info("securedIPAddressSet.size()=" + securedIPAddressSet.size());
0868:                if (securedIPAddressSet.size() > 0) {
0869:                    //log.info("Setting securedIPAddressSet;addAssessmentMetaData(hasIpAddress, true)");
0870:                    //AssessmentService assessmentService = new AssessmentService();
0871:                    //      assessment.getData().setSecuredIPAddressSet(securedIPAddressSet);
0872:                    //      assessment.getData().addAssessmentMetaData("hasIpAddress", "true");
0873:                    //      assessment.getData().addAssessmentMetaData("hasSpecificIP", "true");
0874:                    //      data.setSecuredIPAddressSet(securedIPAddressSet);
0875:                    data.addAssessmentMetaData("hasIpAddress", "true");
0876:                    data.addAssessmentMetaData("hasSpecificIP", "true");
0877:                    assessment.updateData(data);
0878:                    assessment.setSecuredIPAddressSet(securedIPAddressSet);
0879:
0880:                }
0881:            }
0882:
0883:            /**
0884:             * the ip address is in a newline delimited string
0885:             * @param assessment
0886:             */
0887:            public void makeAssessmentAttachmentSet(AssessmentFacade assessment) {
0888:                // if unzipLocation is null, there is no assessment attachment - no action is needed
0889:                if (unzipLocation == null) {
0890:                    return;
0891:                }
0892:                // first check if there is any attachment
0893:                // if no attachment - no action is needed
0894:                String attachment = assessment
0895:                        .getAssessmentAttachmentMetaData();
0896:                if (attachment == null || "".equals(attachment)) {
0897:                    return;
0898:                }
0899:
0900:                Set assessmentAttachmentSet = (Set) assessment
0901:                        .getAssessmentAttachmentSet();
0902:                if (assessmentAttachmentSet == null) {
0903:                    assessmentAttachmentSet = new HashSet();
0904:                }
0905:
0906:                AssessmentAttachmentIfc assessmentAttachment;
0907:                String[] attachmentArray = attachment.split("\\n");
0908:                HashSet set = new HashSet();
0909:                for (int i = 0; i < attachmentArray.length; i++) {
0910:                    String[] attachmentInfo = attachmentArray[i].split("\\|");
0911:                    String fullFilePath = unzipLocation + "/"
0912:                            + attachmentInfo[0];
0913:                    String filename = attachmentInfo[1];
0914:                    AttachmentHelper attachementHelper = new AttachmentHelper();
0915:                    ContentResource contentResource = attachementHelper
0916:                            .createContentResource(fullFilePath, filename,
0917:                                    attachmentInfo[2]);
0918:                    AssessmentService assessmentService = new AssessmentService();
0919:                    assessmentAttachment = assessmentService
0920:                            .createAssessmentAttachment(assessment,
0921:                                    contentResource.getId(), filename,
0922:                                    ServerConfigurationService.getServerUrl());
0923:                    assessmentAttachment
0924:                            .setAssessment((AssessmentIfc) assessment.getData());
0925:                    set.add(assessmentAttachment);
0926:                }
0927:                assessment.setAssessmentAttachmentSet(set);
0928:            }
0929:
0930:            /**
0931:             * the ip address is in a newline delimited string
0932:             * @param assessment
0933:             */
0934:            public void makeSectionAttachmentSet(SectionFacade section,
0935:                    Map sectionMap) {
0936:                // if unzipLocation is null, there is no assessment attachment - no action is needed
0937:                if (unzipLocation == null) {
0938:                    return;
0939:                }
0940:                // first check if there is any attachment
0941:                // if no attachment - no action is needed
0942:                String attachment = (String) sectionMap.get("attachment");
0943:                if (attachment == null || "".equals(attachment)) {
0944:                    return;
0945:                }
0946:
0947:                Set sectionAttachmentSet = (Set) section
0948:                        .getSectionAttachmentSet();
0949:                if (sectionAttachmentSet == null) {
0950:                    sectionAttachmentSet = new HashSet();
0951:                }
0952:
0953:                SectionAttachmentIfc sectionAttachment;
0954:                String[] attachmentArray = attachment.split("\\n");
0955:                HashSet set = new HashSet();
0956:                for (int i = 0; i < attachmentArray.length; i++) {
0957:                    String[] attachmentInfo = attachmentArray[i].split("\\|");
0958:                    String fullFilePath = unzipLocation + "/"
0959:                            + attachmentInfo[0];
0960:                    String filename = attachmentInfo[1];
0961:                    AttachmentHelper attachementHelper = new AttachmentHelper();
0962:                    ContentResource contentResource = attachementHelper
0963:                            .createContentResource(fullFilePath, filename,
0964:                                    attachmentInfo[2]);
0965:                    AssessmentService assessmentService = new AssessmentService();
0966:                    sectionAttachment = assessmentService
0967:                            .createSectionAttachment(section, contentResource
0968:                                    .getId(), filename,
0969:                                    ServerConfigurationService.getServerUrl());
0970:                    sectionAttachment.setSection(section.getData());
0971:                    set.add(sectionAttachment);
0972:                }
0973:                section.setSectionAttachmentSet(set);
0974:            }
0975:
0976:            /**
0977:             * the ip address is in a newline delimited string
0978:             * @param assessment
0979:             */
0980:            public void makeItemAttachmentSet(ItemFacade item) {
0981:                // if unzipLocation is null, there is no assessment attachment - no action is needed
0982:                if (unzipLocation == null) {
0983:                    return;
0984:                }
0985:                // first check if there is any attachment
0986:                // if no attachment - no action is needed
0987:                String attachment = item.getItemAttachmentMetaData();
0988:                if (attachment == null || "".equals(attachment)) {
0989:                    return;
0990:                }
0991:
0992:                Set itemAttachmentSet = (Set) item.getItemAttachmentSet();
0993:                if (itemAttachmentSet == null) {
0994:                    itemAttachmentSet = new HashSet();
0995:                }
0996:
0997:                ItemAttachmentIfc itemAttachment;
0998:                String[] attachmentArray = attachment.split("\\n");
0999:                HashSet set = new HashSet();
1000:                for (int i = 0; i < attachmentArray.length; i++) {
1001:                    String[] attachmentInfo = attachmentArray[i].split("\\|");
1002:                    String fullFilePath = unzipLocation + "/"
1003:                            + attachmentInfo[0];
1004:                    String filename = attachmentInfo[1];
1005:                    AttachmentHelper attachementHelper = new AttachmentHelper();
1006:                    ContentResource contentResource = attachementHelper
1007:                            .createContentResource(fullFilePath, filename,
1008:                                    attachmentInfo[2]);
1009:                    AssessmentService assessmentService = new AssessmentService();
1010:                    itemAttachment = assessmentService.createItemAttachment(
1011:                            item, contentResource.getId(), filename,
1012:                            ServerConfigurationService.getServerUrl());
1013:                    itemAttachment.setItem(item.getData());
1014:                    set.add(itemAttachment);
1015:                }
1016:                item.setItemAttachmentSet(set);
1017:            }
1018:
1019:            /**
1020:             * the ip address is in a newline delimited string
1021:             * @param assessment
1022:             */
1023:            public String makeFCKAttachment(String text) {
1024:                // if unzipLocation is null, there is no assessment attachment - no action is needed
1025:                if (unzipLocation == null) {
1026:                    return text;
1027:                }
1028:                // first check if there is any content resource attachment
1029:                // if no - no action is needed
1030:                String accessURL = ServerConfigurationService.getAccessUrl();
1031:                String referenceRoot = ContentHostingService.REFERENCE_ROOT;
1032:                String prependString = accessURL + referenceRoot;
1033:                String importedPrependString = getImportedPrependString(text);
1034:                if (text == null || importedPrependString == null) {
1035:                    return text;
1036:                } else {
1037:                    String[] splittedString = text.split(importedPrependString);
1038:                    int endIndex = 0;
1039:                    String filename = null;
1040:                    String contentType = null;
1041:                    String fullFilePath = null;
1042:                    String oldResourceId = null;
1043:                    String resourceId = null;
1044:                    ContentResource contentResource = null;
1045:                    StringBuffer updatedText = new StringBuffer(
1046:                            splittedString[0]);
1047:                    for (int i = 1; i < splittedString.length; i++) {
1048:                        log.debug("splittedString[" + i + "] = "
1049:                                + splittedString[i]);
1050:                        // Here is an example, splittedString will be something like:
1051:                        // /group/b917f0b9-e21d-4819-80ee-35feac91c9eb/Blue Hill.jpg" alt="...  or
1052:                        // /user/ktsao/Blue Hill.jpg" alt="...
1053:                        // oldResourceId = /group/b917f0b9-e21d-4819-80ee-35feac91c9eb/Blue Hill.jpg or /user/ktsao/Blue Hill.jpg
1054:                        // oldSplittedResourceId[0] = ""
1055:                        // oldSplittedResourceId[1] = group or user
1056:                        // oldSplittedResourceId[2] = b917f0b9-e21d-4819-80ee-35feac91c9eb or ktsao
1057:                        // oldSplittedResourceId[3] = Blue Hill.jpg
1058:                        endIndex = splittedString[i].indexOf("\"");
1059:                        oldResourceId = splittedString[i]
1060:                                .substring(0, endIndex);
1061:                        String[] oldSplittedResourceId = oldResourceId
1062:                                .split("/");
1063:                        fullFilePath = unzipLocation + "/"
1064:                                + oldResourceId.replace(" ", "");
1065:                        filename = oldSplittedResourceId[3];
1066:                        MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap();
1067:                        contentType = mimetypesFileTypeMap
1068:                                .getContentType(filename);
1069:                        AttachmentHelper attachementHelper = new AttachmentHelper();
1070:                        contentResource = attachementHelper
1071:                                .createContentResource(fullFilePath, filename,
1072:                                        contentType);
1073:
1074:                        if (contentResource != null) {
1075:                            resourceId = contentResource.getId();
1076:                            updatedText.append(prependString);
1077:                            updatedText.append(resourceId);
1078:                            updatedText.append(splittedString[i]
1079:                                    .substring(endIndex));
1080:                        } else {
1081:                            throw new RuntimeException("resourceId is null");
1082:                        }
1083:                    }
1084:                    return updatedText.toString();
1085:                }
1086:            }
1087:
1088:            private String getImportedPrependString(String text) {
1089:                String accessPath = ServerConfigurationService.getAccessPath();
1090:                String referenceRoot = ContentHostingService.REFERENCE_ROOT;
1091:                String importedPrependString = accessPath + referenceRoot;
1092:
1093:                String[] splittedString = text.split("src=\"");
1094:                for (int i = 0; i < splittedString.length; i++) {
1095:                    if (splittedString[i].indexOf(importedPrependString) > -1) {
1096:                        int length = importedPrependString.length();
1097:                        return splittedString[i].substring(0, splittedString[i]
1098:                                .indexOf(importedPrependString)
1099:                                + length);
1100:                    }
1101:                }
1102:                return null;
1103:            }
1104:
1105:            /**
1106:             * Update questionpool from the extracted properties.
1107:             * Note: you need to do a save when you are done.
1108:             * @param questionpool, which will  be persisted
1109:             * @param assessmentMap, the extracted properties
1110:             */
1111:            public void updateQuestionPool(QuestionPoolFacade questionpool,
1112:                    Map assessmentMap) {
1113:
1114:                String title = ((String) assessmentMap.get("title"));
1115:                questionpool.setDescription((String) assessmentMap
1116:                        .get("description"));
1117:                //questionpool.setLastModifiedById("Sakai Import");
1118:                questionpool.setLastModified(new Date());
1119:                // note: currently dateCreated field not in use 	  
1120:                //questionpool.setDateCreated(new Date());
1121:                questionpool.setOrganizationName((String) assessmentMap
1122:                        .get("ASSESSMENT_ORGANIZATIONNAME"));
1123:                questionpool.setObjectives((String) assessmentMap
1124:                        .get("ASSESSMENT_OBJECTIVES"));
1125:                questionpool.setKeywords((String) assessmentMap
1126:                        .get("ASSESSMENT_KEYWORDS"));
1127:                questionpool.setRubric((String) assessmentMap
1128:                        .get("ASSESSMENT_RUBRICS"));
1129:                questionpool.setIntellectualPropertyId((Long) assessmentMap
1130:                        .get("INTELLECTUALPROPERTYID"));
1131:
1132:                log.debug("QPOOL ASSESSMENT updating metadata information");
1133:
1134:            }
1135:
1136:            /**
1137:             * Update section from the extracted properties.
1138:             * Note: you need to do a save when you are done.
1139:             * @param section the section, which will  be persisted
1140:             * @param sectionMap the extracted properties
1141:             */
1142:            public void updateSection(SectionFacade section, Map sectionMap) {
1143:                section.setTitle((String) sectionMap.get("title"));
1144:                section.setDescription(makeFCKAttachment((String) sectionMap
1145:                        .get("description")));
1146:                section.setLastModifiedBy("Sakai Import");
1147:                section.setLastModifiedDate(new Date());
1148:            }
1149:
1150:            /**
1151:             * Update item from the extracted properties.
1152:             * Note: you need to do a save when you are done.
1153:             * @param item the item, which will  be persisted
1154:             * @param itemMap the extracted properties
1155:             */
1156:            public void updateItem(ItemFacade item, Map itemMap) {
1157:                // type and title
1158:                String title = (String) itemMap.get("title");
1159:                item.setDescription(title);
1160:
1161:                // set meta data
1162:                List metalist = (List) itemMap.get("metadata");
1163:                MetaDataList metadataList = new MetaDataList(metalist);
1164:                metadataList.addTo(item);
1165:
1166:                // type
1167:                log.debug("itemMap=" + itemMap);
1168:                String qmd = item.getItemMetaDataByLabel("qmd_itemtype");
1169:                String itemIntrospect = (String) itemMap.get("itemIntrospect");
1170:                log.debug("Calling ItemTypeExtractionStrategy.calculate(");
1171:                log.debug("    title=" + title);
1172:                log.debug("    , itemIntrospect=" + itemIntrospect);
1173:                log.debug("    ,  qmd=" + qmd);
1174:                log.debug(");");
1175:
1176:                Long typeId = ItemTypeExtractionStrategy.calculate(title,
1177:                        itemIntrospect, qmd);
1178:                item.setTypeId(typeId);
1179:
1180:                // basic properties
1181:                addItemProperties(item, itemMap);
1182:
1183:                // feedback
1184:                // correct, incorrect, general
1185:                addFeedback(item, itemMap, typeId);
1186:
1187:                // item text and answers
1188:                if (TypeIfc.FILL_IN_BLANK.longValue() == typeId.longValue()) {
1189:                    addFibTextAndAnswers(item, itemMap);
1190:                }
1191:
1192:                else if (TypeIfc.FILL_IN_NUMERIC.longValue() == typeId
1193:                        .longValue()) {
1194:                    addFibTextAndAnswers(item, itemMap);
1195:                    //addFinTextAndAnswers(item, itemMap);  // 10/3/2006: Diego's code, duplicate of addFibTextAndAnswers
1196:                }
1197:
1198:                else if (TypeIfc.MATCHING.longValue() == typeId.longValue()) {
1199:                    addMatchTextAndAnswers(item, itemMap);
1200:                } else {
1201:                    addTextAndAnswers(item, itemMap);
1202:                }
1203:
1204:            }
1205:
1206:            /**
1207:             *
1208:             * @param item
1209:             * @param itemMap
1210:             */
1211:            private void addItemProperties(ItemFacade item, Map itemMap) {
1212:                //String duration = (String) itemMap.get("duration");
1213:                //String triesAllowed = (String) itemMap.get("triesAllowed");
1214:
1215:                String score = (String) itemMap.get("score");
1216:                String hasRationale = item
1217:                        .getItemMetaDataByLabel("hasRationale");//rshastri :SAK-1824
1218:                String status = (String) itemMap.get("status");
1219:                String createdBy = (String) itemMap.get("createdBy");
1220:
1221:                // not being set yet
1222:                String instruction = (String) itemMap.get("instruction");
1223:                String hint = (String) itemMap.get("hint");
1224:
1225:                // created by is not nullable
1226:                if (createdBy == null) {
1227:                    createdBy = "Imported by Sakai";
1228:                }
1229:
1230:                String createdDate = (String) itemMap.get("createdDate");
1231:
1232:                // get Duration and TriesAllowed from metadata.
1233:                /*
1234:                   if (notNullOrEmpty(duration))
1235:                  {
1236:                    item.setDuration(new Integer(duration));
1237:                  }
1238:                  if (notNullOrEmpty(triesAllowed))
1239:                  {
1240:                    item.setTriesAllowed(new Integer(triesAllowed));
1241:                  }
1242:                 */
1243:
1244:                item.setInstruction((String) itemMap.get("instruction"));
1245:                if (notNullOrEmpty(score)) {
1246:                    item.setScore(new Float(score));
1247:                } else {
1248:                    item.setScore(new Float(0));
1249:                }
1250:                item.setHint((String) itemMap.get("hint"));
1251:                if (notNullOrEmpty(hasRationale)) {
1252:                    item.setHasRationale(new Boolean(hasRationale));
1253:                }
1254:                if (notNullOrEmpty(status)) {
1255:                    item.setStatus(new Integer(status));
1256:                }
1257:                item.setCreatedBy(createdBy);
1258:                try {
1259:                    Iso8601DateFormat iso = new Iso8601DateFormat();
1260:                    Calendar cal = iso.parse(createdDate);
1261:                    item.setCreatedDate(cal.getTime());
1262:                } catch (Exception ex) {
1263:                    item.setCreatedDate(new Date());
1264:                }
1265:                item.setLastModifiedBy("Sakai Import");
1266:                item.setLastModifiedDate(new Date());
1267:            }
1268:
1269:            /**
1270:             * add feedback
1271:             * @param item
1272:             * @param itemMap
1273:             * @param typeId
1274:             */
1275:            private void addFeedback(ItemFacade item, Map itemMap, Long typeId) {
1276:                // write the map out
1277:                Iterator iter = itemMap.keySet().iterator();
1278:                while (iter.hasNext()) {
1279:                    String key = (String) iter.next();
1280:                    Object o = itemMap.get(key);
1281:                    log.debug("itemMap: " + key + "=" + itemMap.get(key));
1282:                }
1283:
1284:                String correctItemFeedback = (String) itemMap
1285:                        .get("correctItemFeedback");
1286:                String incorrectItemFeedback = (String) itemMap
1287:                        .get("incorrectItemFeedback");
1288:                String generalItemFeedback = (String) itemMap
1289:                        .get("generalItemFeedback");
1290:                if (generalItemFeedback == null)
1291:                    generalItemFeedback = "";
1292:
1293:                // NOTE:
1294:                // in early Samigo (aka Navigo) general feedback exported as "InCorrect"!
1295:                // now if this is an Audio, File Upload or Short Answer question additional
1296:                // feedback will append feedback to general, this should be OK, since
1297:                // QTI with general feedback for these types will leave them empty
1298:                if (TypeIfc.AUDIO_RECORDING.longValue() == typeId.longValue()
1299:                        || TypeIfc.FILE_UPLOAD.longValue() == typeId
1300:                                .longValue()
1301:                        || TypeIfc.ESSAY_QUESTION.longValue() == typeId
1302:                                .longValue()) {
1303:                    if (notNullOrEmpty(incorrectItemFeedback)) {
1304:                        generalItemFeedback += " " + incorrectItemFeedback;
1305:                    }
1306:                    if (notNullOrEmpty(correctItemFeedback)) {
1307:                        generalItemFeedback += " " + correctItemFeedback;
1308:                    }
1309:                }
1310:
1311:                if (notNullOrEmpty(correctItemFeedback)) {
1312:                    item
1313:                            .setCorrectItemFeedback(makeFCKAttachment(correctItemFeedback));
1314:                }
1315:                if (notNullOrEmpty(incorrectItemFeedback)) {
1316:                    item
1317:                            .setInCorrectItemFeedback(makeFCKAttachment(incorrectItemFeedback));
1318:                }
1319:                if (notNullOrEmpty(generalItemFeedback)) {
1320:                    item
1321:                            .setGeneralItemFeedback(makeFCKAttachment(generalItemFeedback));
1322:                }
1323:
1324:            }
1325:
1326:            /**
1327:             * create the answer feedback set for an answer
1328:             * @param item
1329:             * @param itemMap
1330:             */
1331:            private void addAnswerFeedback(Answer answer, String value) {
1332:                HashSet answerFeedbackSet = new HashSet();
1333:                answerFeedbackSet.add(new AnswerFeedback(answer,
1334:                        AnswerFeedbackIfc.ANSWER_FEEDBACK, value));
1335:                answer.setAnswerFeedbackSet(answerFeedbackSet);
1336:            }
1337:
1338:            /**
1339:             * @param item
1340:             * @param itemMap
1341:             */
1342:            private void addTextAndAnswers(ItemFacade item, Map itemMap) {
1343:                List itemTextList = (List) itemMap.get("itemText");
1344:                HashSet itemTextSet = new HashSet();
1345:                for (int i = 0; i < itemTextList.size(); i++) {
1346:                    ItemText itemText = new ItemText();
1347:                    String text = (String) itemTextList.get(i);
1348:                    // should be allow this or, continue??
1349:                    // for now, empty string OK, setting to empty string if null
1350:                    if (text == null) {
1351:                        text = "";
1352:                    }
1353:                    text = text.replaceAll("\\?\\?", " ");//SAK-2298
1354:                    log.debug("text: " + text);
1355:
1356:                    itemText.setText(makeFCKAttachment(text));
1357:                    itemText.setItem(item.getData());
1358:                    itemText.setSequence(new Long(i + 1));
1359:                    List answerList = new ArrayList();
1360:                    List aList = (List) itemMap.get("itemAnswer");
1361:                    answerList = aList == null ? answerList : aList;
1362:                    HashSet answerSet = new HashSet();
1363:                    char answerLabel = 'A';
1364:                    List answerFeedbackList = (List) itemMap
1365:                            .get("itemAnswerFeedback");
1366:
1367:                    ArrayList correctLabels;
1368:                    correctLabels = (ArrayList) itemMap
1369:                            .get("itemAnswerCorrectLabel");
1370:                    if (correctLabels == null) {
1371:                        correctLabels = new ArrayList();
1372:                    }
1373:                    for (int a = 0; a < answerList.size(); a++) {
1374:                        Answer answer = new Answer();
1375:                        String answerText = (String) answerList.get(a);
1376:                        // these are not supposed to be empty
1377:                        if (notNullOrEmpty(answerText)) {
1378:                            answerText = answerText.replaceAll("\\?\\?", " ");//SAK-2298
1379:                            log.debug("answerText: " + answerText);
1380:
1381:                            // normalize all true/false questions
1382:                            if (answerList.size() == 2) {
1383:                                if (answerText.equalsIgnoreCase("true"))
1384:                                    answerText = "true";
1385:                                if (answerText.equalsIgnoreCase("false"))
1386:                                    answerText = "false";
1387:                            }
1388:                            String label = "" + answerLabel++;
1389:                            answer.setLabel(label); // up to 26, is this a problem?
1390:
1391:                            // correct answer and score
1392:                            float score = 0;
1393:                            // if label matches correct answer it is correct
1394:                            if (isCorrectLabel(label, correctLabels)) {
1395:                                answer.setIsCorrect(Boolean.TRUE);
1396:                                // manual authoring disregards correctness
1397:                                // commented out: what we'd have if we looked at correctness
1398:                                //            score = getCorrectScore(item, 1);
1399:                            } else {
1400:                                answer.setIsCorrect(Boolean.FALSE);
1401:                            }
1402:                            // manual authoring disregards correctness
1403:                            // so we will do the same.
1404:                            score = getCorrectScore(item, 1);
1405:                            log.debug("setting answer" + label + " score to:"
1406:                                    + score);
1407:                            answer.setScore(new Float(score));
1408:
1409:                            answer.setText(makeFCKAttachment(answerText));
1410:                            answer.setItemText(itemText);
1411:                            answer.setItem(item.getData());
1412:                            int sequence = a + 1;
1413:                            answer.setSequence(new Long(sequence));
1414:                            // prepare answer feedback - daisyf added this on 2/21/05
1415:                            // need to check if this works for question type other than
1416:                            // MC
1417:                            HashSet set = new HashSet();
1418:                            if (answerFeedbackList != null) {
1419:                                AnswerFeedback answerFeedback = new AnswerFeedback();
1420:                                answerFeedback.setAnswer(answer);
1421:                                answerFeedback
1422:                                        .setTypeId(AnswerFeedbackIfc.GENERAL_FEEDBACK);
1423:                                if (answerFeedbackList.get(sequence - 1) != null) {
1424:                                    answerFeedback
1425:                                            .setText(makeFCKAttachment((String) answerFeedbackList
1426:                                                    .get(sequence - 1)));
1427:                                    set.add(answerFeedback);
1428:                                    answer.setAnswerFeedbackSet(set);
1429:                                }
1430:                            }
1431:
1432:                            answerSet.add(answer);
1433:                        }
1434:                    }
1435:                    itemText.setAnswerSet(answerSet);
1436:                    itemTextSet.add(itemText);
1437:                }
1438:                item.setItemTextSet(itemTextSet);
1439:            }
1440:
1441:            private float getCorrectScore(ItemDataIfc item, int answerSize) {
1442:                float score = 0;
1443:                if (answerSize > 0 && item != null && item.getScore() != null) {
1444:                    score = item.getScore().floatValue() / answerSize;
1445:                }
1446:                return score;
1447:            }
1448:
1449:            /**
1450:             * Check to find out it response label is in the list of correct responses
1451:             * @param testLabel response label
1452:             * @param labels the list of correct responses
1453:             * @return
1454:             */
1455:            private boolean isCorrectLabel(String testLabel, ArrayList labels) {
1456:                if (testLabel == null || labels == null
1457:                        || labels.indexOf(testLabel) == -1) {
1458:                    return false;
1459:                }
1460:
1461:                return true;
1462:            }
1463:
1464:            /**
1465:             * FIB questions ONLY
1466:             * @param item
1467:             * @param itemMap
1468:             */
1469:            private void addFibTextAndAnswers(ItemFacade item, Map itemMap) {
1470:                List itemTextList = new ArrayList();
1471:                List iList = (List) itemMap.get("itemFibText");
1472:                itemTextList = iList == null ? itemTextList : iList;
1473:
1474:                List itemTList = new ArrayList();
1475:                List tList = (List) itemMap.get("itemText");
1476:                itemTList = iList == null ? itemTList : tList;
1477:
1478:                HashSet itemTextSet = new HashSet();
1479:                ItemText itemText = new ItemText();
1480:                String itemTextString = "";
1481:                List answerFeedbackList = (List) itemMap.get("itemFeedback");
1482:
1483:                List answerList = new ArrayList();
1484:                List aList = (List) itemMap.get("itemFibAnswer");
1485:                answerList = aList == null ? answerList : aList;
1486:
1487:                // handle FIB with instructional text
1488:                // sneak it into first text
1489:                if (!itemTList.isEmpty() && !itemTextList.isEmpty()
1490:                        && !(itemTextList.size() > 1)) {
1491:                    try {
1492:                        String firstFib = (String) itemTextList.get(0);
1493:                        String firstText = (String) itemTList.get(0);
1494:                        if (firstFib.equals(firstText)) {
1495:                            log.debug("Setting FIB instructional text.");
1496:                            //          itemTextList.remove(0);
1497:                            String newFirstFib = firstFib + "<br />"
1498:                                    + itemTextList.get(0);
1499:                            itemTextList.set(0, newFirstFib);
1500:                        }
1501:                    } catch (Exception ex) {
1502:                        log
1503:                                .warn("Thought we found an instructional text but couldn't put it in."
1504:                                        + " " + ex);
1505:                    }
1506:                }
1507:                // loop through all our extracted FIB texts interposing FIB_BLANK_INDICATOR
1508:                for (int i = 0; i < itemTextList.size(); i++) {
1509:                    String text = (String) itemTextList.get(i);
1510:                    // we are assuming non-empty text/answer/non-empty text/answer etc.
1511:                    if (text == null || text == "") {
1512:                        continue;
1513:                    }
1514:                    itemTextString += text;
1515:                    if (i < answerList.size()) {
1516:                        itemTextString += FIB_BLANK_INDICATOR;
1517:                    }
1518:                }
1519:                itemTextString = itemTextString.replaceAll("\\?\\?", " ");//SAK-2298
1520:                log.debug("itemTextString=" + itemTextString);
1521:                itemText.setText(makeFCKAttachment(itemTextString));
1522:                itemText.setItem(item.getData());
1523:                itemText.setSequence(new Long(0));
1524:                HashSet answerSet = new HashSet();
1525:                char answerLabel = 'A';
1526:                for (int a = 0; a < answerList.size(); a++) {
1527:                    Answer answer = new Answer();
1528:                    String answerText = (String) answerList.get(a);
1529:                    // these are not supposed to be empty
1530:                    if (notNullOrEmpty(answerText)) {
1531:                        answerText = answerText.replaceAll("\\?\\?", " ");//SAK-2298
1532:                        log.debug("answerText=" + answerText);
1533:
1534:                        String label = "" + answerLabel++;
1535:                        answer.setLabel(label); // up to 26, is this a problem?
1536:                        answer.setText(makeFCKAttachment(answerText));
1537:                        answer.setItemText(itemText);
1538:
1539:                        // correct answer and score
1540:                        answer.setIsCorrect(Boolean.TRUE);
1541:                        // manual authoring disregards the number of partial answers
1542:                        // so we will do the same.
1543:                        float score = getCorrectScore(item, 1);
1544:                        //        float score = getCorrectScore(item, answerList.size());
1545:
1546:                        log.debug("setting answer " + label + " score to:"
1547:                                + score);
1548:                        answer.setScore(new Float(score));
1549:
1550:                        answer.setItem(item.getData());
1551:                        int sequence = a + 1;
1552:                        answer.setSequence(new Long(sequence));
1553:                        HashSet set = new HashSet();
1554:                        if (answerFeedbackList != null) {
1555:                            AnswerFeedback answerFeedback = new AnswerFeedback();
1556:                            answerFeedback.setAnswer(answer);
1557:                            answerFeedback
1558:                                    .setTypeId(AnswerFeedbackIfc.GENERAL_FEEDBACK);
1559:                            if (answerFeedbackList.get(sequence - 1) != null) {
1560:                                answerFeedback
1561:                                        .setText(makeFCKAttachment((String) answerFeedbackList
1562:                                                .get(sequence - 1)));
1563:                                set.add(answerFeedback);
1564:                                answer.setAnswerFeedbackSet(set);
1565:                            }
1566:                        }
1567:                        answerSet.add(answer);
1568:                    }
1569:                }
1570:
1571:                itemText.setAnswerSet(answerSet);
1572:                itemTextSet.add(itemText);
1573:                item.setItemTextSet(itemTextSet);
1574:            }
1575:
1576:            /**
1577:             * MATCHING questions ONLY
1578:             * @param item
1579:             * @param itemMap
1580:             */
1581:            private void addMatchTextAndAnswers(ItemFacade item, Map itemMap) {
1582:
1583:                List sourceList = (List) itemMap.get("itemMatchSourceText");
1584:                List targetList = (List) itemMap.get("itemMatchTargetText");
1585:                List indexList = (List) itemMap.get("itemMatchIndex");
1586:                List answerFeedbackList = (List) itemMap.get("itemFeedback");
1587:                List correctMatchFeedbackList = (List) itemMap
1588:                        .get("itemMatchCorrectFeedback");
1589:                List incorrectMatchFeedbackList = (List) itemMap
1590:                        .get("itemMatchIncorrectFeedback");
1591:                List itemTextList = (List) itemMap.get("itemText");
1592:
1593:                sourceList = sourceList == null ? new ArrayList() : sourceList;
1594:                targetList = targetList == null ? new ArrayList() : targetList;
1595:                indexList = indexList == null ? new ArrayList() : indexList;
1596:                answerFeedbackList = answerFeedbackList == null ? new ArrayList()
1597:                        : answerFeedbackList;
1598:                correctMatchFeedbackList = correctMatchFeedbackList == null ? new ArrayList()
1599:                        : correctMatchFeedbackList;
1600:                incorrectMatchFeedbackList = incorrectMatchFeedbackList == null ? new ArrayList()
1601:                        : incorrectMatchFeedbackList;
1602:
1603:                log.debug("*** original incorrect order");
1604:                for (int i = 0; i < incorrectMatchFeedbackList.size(); i++) {
1605:                    log.debug("incorrectMatchFeedbackList.get(" + i + ")="
1606:                            + incorrectMatchFeedbackList.get(i));
1607:                }
1608:                int maxNumCorrectFeedback = sourceList.size();
1609:                int numIncorrectFeedback = incorrectMatchFeedbackList.size();
1610:
1611:                if (maxNumCorrectFeedback > 0 && numIncorrectFeedback > 0) {
1612:                    incorrectMatchFeedbackList = reassembleIncorrectMatches(
1613:                            incorrectMatchFeedbackList, maxNumCorrectFeedback);
1614:                }
1615:
1616:                log.debug("*** NEW order");
1617:                for (int i = 0; i < incorrectMatchFeedbackList.size(); i++) {
1618:                    log.debug("incorrectMatchFeedbackList.get(" + i + ")="
1619:                            + incorrectMatchFeedbackList.get(i));
1620:
1621:                }
1622:
1623:                itemTextList = itemTextList == null ? new ArrayList()
1624:                        : itemTextList;
1625:
1626:                if (targetList.size() < indexList.size()) {
1627:                    log.debug("targetList.size(): " + targetList.size());
1628:                    log.debug("indexList.size(): " + indexList.size());
1629:                }
1630:
1631:                String itemTextString = "";
1632:                if (itemTextList.size() > 0) {
1633:                    itemTextString = (String) itemTextList.get(0);
1634:                }
1635:
1636:                HashSet itemTextSet = new HashSet();
1637:
1638:                // first, add the question text
1639:                if (itemTextString == null)
1640:                    itemTextString = "";
1641:                itemTextString = itemTextString.replaceAll("\\?\\?", " ");//SAK-2298
1642:                log.debug("item.setInstruction itemTextString: "
1643:                        + itemTextString);
1644:                item.setInstruction(itemTextString);
1645:
1646:                // loop through source texts indicating answers (targets)
1647:                for (int i = 0; i < sourceList.size(); i++) {
1648:                    // create the entry for the matching item (source)
1649:                    String sourceText = (String) sourceList.get(i);
1650:                    if (sourceText == null)
1651:                        sourceText = "";
1652:                    sourceText = sourceText.replaceAll("\\?\\?", " ");//SAK-2298
1653:                    log.debug("sourceText: " + sourceText);
1654:
1655:                    ItemText sourceItemText = new ItemText();
1656:                    sourceItemText.setText(makeFCKAttachment(sourceText));
1657:                    sourceItemText.setItem(item.getData());
1658:                    sourceItemText.setSequence(new Long(i + 1));
1659:
1660:                    // find the matching answer (target)
1661:                    HashSet targetSet = new HashSet();
1662:                    String targetString;
1663:                    int targetIndex = 999;// obviously not matching value
1664:                    try {
1665:                        targetIndex = Integer.parseInt((String) indexList
1666:                                .get(i));
1667:                    } catch (NumberFormatException ex) {
1668:                        log.warn("No match for " + sourceText + "."); // default to no match
1669:                    } catch (IndexOutOfBoundsException ex) {
1670:                        log
1671:                                .error("Corrupt index list.  Cannot assign match for: "
1672:                                        + sourceText + ".");
1673:                    }
1674:                    // loop through all possible targets (matching answers)
1675:                    char answerLabel = 'A';
1676:                    for (int a = 0; a < targetList.size(); a++) {
1677:                        targetString = (String) targetList.get(a);
1678:                        if (targetString == null) {
1679:                            targetString = "";
1680:                        }
1681:                        targetString = targetString.replaceAll("\\?\\?", " ");//SAK-2298
1682:                        log.debug("targetString: " + targetString);
1683:
1684:                        Answer target = new Answer();
1685:
1686:                        //feedback
1687:                        HashSet answerFeedbackSet = new HashSet();
1688:
1689:                        if (correctMatchFeedbackList.size() > i) {
1690:                            String fb = (String) correctMatchFeedbackList
1691:                                    .get(i);
1692:                            answerFeedbackSet.add(new AnswerFeedback(target,
1693:                                    AnswerFeedbackIfc.CORRECT_FEEDBACK, fb));
1694:                        }
1695:                        if (incorrectMatchFeedbackList.size() > i) {
1696:                            String fb = (String) incorrectMatchFeedbackList
1697:                                    .get(i);
1698:                            log.debug("setting incorrect fb=" + fb);
1699:                            answerFeedbackSet.add(new AnswerFeedback(target,
1700:                                    AnswerFeedbackIfc.INCORRECT_FEEDBACK, fb));
1701:                        }
1702:
1703:                        target.setAnswerFeedbackSet(answerFeedbackSet);
1704:
1705:                        String label = "" + answerLabel++;
1706:                        target.setLabel(label); // up to 26, is this a problem?
1707:                        target.setText(makeFCKAttachment(targetString));
1708:                        target.setItemText(sourceItemText);
1709:                        target.setItem(item.getData());
1710:                        target.setSequence(new Long(a + 1));
1711:
1712:                        // correct answer and score
1713:                        // manual authoring disregards the number of partial answers
1714:                        // or whether the answer is correct so we will do the same.
1715:                        //        float score = 0;
1716:                        float score = getCorrectScore(item, 1);
1717:
1718:                        // if this answer is the indexed one, flag as correct
1719:                        if (a + 1 == targetIndex) {
1720:                            target.setIsCorrect(Boolean.TRUE);
1721:                            //          score = getCorrectScore(item, targetList.size());
1722:                            log.debug("source: " + sourceText
1723:                                    + " matches target: " + targetString);
1724:                        } else {
1725:                            target.setIsCorrect(Boolean.FALSE);
1726:                        }
1727:                        log.debug("setting answer " + a + " score to:" + score);
1728:                        target.setScore(new Float(score));
1729:
1730:                        if (answerFeedbackList != null) {
1731:                            Set targetFeedbackSet = new HashSet();
1732:                            AnswerFeedback tAnswerFeedback = new AnswerFeedback();
1733:                            tAnswerFeedback.setAnswer(target);
1734:                            tAnswerFeedback
1735:                                    .setTypeId(AnswerFeedbackIfc.GENERAL_FEEDBACK);
1736:                            String targetFeedback = "";
1737:                            if (answerFeedbackList.size() > 0) {
1738:                                targetFeedback = (String) answerFeedbackList
1739:                                        .get(targetIndex);
1740:                            }
1741:                            if (targetFeedback.length() > 0) {
1742:                                tAnswerFeedback
1743:                                        .setText(makeFCKAttachment(targetFeedback));
1744:                                targetFeedbackSet.add(tAnswerFeedback);
1745:                                target.setAnswerFeedbackSet(targetFeedbackSet);
1746:                            }
1747:                        }
1748:                        targetSet.add(target);
1749:                    }
1750:
1751:                    sourceItemText.setAnswerSet(targetSet);
1752:                    itemTextSet.add(sourceItemText);
1753:                }
1754:
1755:                item.setItemTextSet(itemTextSet);
1756:            }
1757:
1758:            /**
1759:             * Helper method rotates the first n.
1760:             * This will work with Samigo matching where
1761:             * incorrect matches (n) = the square of the correct matches (n**2)
1762:             * and the 0th displayfeedback is correct and the next n are incorrect
1763:             * feedback.  In export Samigo uses the incorrect feedback redundantly.
1764:             *
1765:             * For example, if there are 5 matches, there are 25 matches and mismatched,
1766:             * 5 of which are correct and 20 of which are not, so there is redundancy in
1767:             * Samigo.
1768:             *
1769:             * In non-Samigo matching, there may be more than one incorrect
1770:             * feedback for a failed matching.
1771:             *
1772:             * @param list the list
1773:             * @return a reassembled list of size n
1774:             */
1775:            private List reassembleIncorrectMatches(List list, int n) {
1776:                // make sure we have a reasonable value
1777:                if (n < 0)
1778:                    n = -n;
1779:                if (n == 0)
1780:                    return list;
1781:
1782:                // pad input list if too small or null
1783:                if (list == null)
1784:                    list = new ArrayList();
1785:                for (int i = 0; i < n && list.size() < n + 1; i++) {
1786:                    list.add("");
1787:                }
1788:
1789:                // our output value
1790:                List newList = new ArrayList();
1791:
1792:                // move the last of the n entries (0-index) up to the front
1793:                newList.add(list.get(n - 1));
1794:
1795:                // add the 2nd entry and so forth
1796:                for (int i = 0; i < n - 1; i++) {
1797:                    String s = (String) list.get(i);
1798:                    newList.add(s);
1799:                }
1800:
1801:                return newList;
1802:            }
1803:
1804:            /**
1805:             * helper method
1806:             * @param s
1807:             * @return
1808:             */
1809:            private boolean notNullOrEmpty(String s) {
1810:                return s != null && s.trim().length() > 0 ? true : false;
1811:            }
1812:
1813:            /**
1814:             * Append "  - 2", "  - 3", etc. incrementing as you go.
1815:             * @param title the original
1816:             * @return the title with versioning appended
1817:             */
1818:            public String renameDuplicate(String title) {
1819:                if (title == null)
1820:                    title = "";
1821:
1822:                String rename = "";
1823:                int index = title.lastIndexOf(VERSION_START);
1824:
1825:                if (index > -1)//if is versioned
1826:                {
1827:                    String mainPart = "";
1828:                    String versionPart = title.substring(index);
1829:                    if (index > 0) {
1830:                        mainPart = title.substring(0, index);
1831:                    }
1832:
1833:                    int nindex = index + VERSION_START.length();
1834:
1835:                    String version = title.substring(nindex);
1836:
1837:                    int versionNumber = 0;
1838:                    try {
1839:                        versionNumber = Integer.parseInt(version);
1840:                        if (versionNumber < 2)
1841:                            versionNumber = 2;
1842:                        versionPart = VERSION_START + (versionNumber + 1);
1843:
1844:                        rename = mainPart + versionPart;
1845:                    } catch (NumberFormatException ex) {
1846:                        rename = title + VERSION_START + "2";
1847:                    }
1848:                } else {
1849:                    rename = title + VERSION_START + "2";
1850:                }
1851:
1852:                return rename;
1853:
1854:            }
1855:
1856:            /**
1857:             * Primarily for testing purposes.
1858:             * @return an overridden path if not null
1859:             */
1860:            public String getOverridePath() {
1861:                return overridePath;
1862:            }
1863:
1864:            /**
1865:             * Primarily for testing purposes.
1866:             * @param overridePath an overriding path
1867:             */
1868:            public void setOverridePath(String overridePath) {
1869:                this .overridePath = overridePath;
1870:            }
1871:
1872:            public void setUnzipLocation(String unzipLocation) {
1873:                this.unzipLocation = unzipLocation;
1874:            }
1875:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.