Source Code Cross Referenced for ItemHelper12Impl.java in  » ERP-CRM-Financial » sakai » org » sakaiproject » tool » assessment » qti » helper » item » 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.item 
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/item/ItemHelper12Impl.java $
0003:         * $Id: ItemHelper12Impl.java 9274 2006-05-10 22:50:48Z daisyf@stanford.edu $
0004:         ***********************************************************************************
0005:         *
0006:         * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
0007:         *
0008:         * Licensed under the Educational Community License, Version 1.0 (the"License");
0009:         * you may not use this file except in compliance with the License.
0010:         * You may obtain a copy of the License at
0011:         *
0012:         *      http://www.opensource.org/licenses/ecl1.php
0013:         *
0014:         * Unless required by applicable law or agreed to in writing, software
0015:         * distributed under the License is distributed on an "AS IS" BASIS,
0016:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017:         * See the License for the specific language governing permissions and
0018:         * limitations under the License.
0019:         *
0020:         **********************************************************************************/package org.sakaiproject.tool.assessment.qti.helper.item;
0021:
0022:        import java.util.ArrayList;
0023:        import java.util.Arrays;
0024:        import java.util.HashMap;
0025:        import java.util.HashSet;
0026:        import java.util.Iterator;
0027:        import java.util.List;
0028:        import java.util.Map;
0029:        import java.util.Set;
0030:        import java.util.StringTokenizer;
0031:
0032:        import org.apache.commons.logging.Log;
0033:        import org.apache.commons.logging.LogFactory; //import org.w3c.dom.Document;
0034:        import org.w3c.dom.Element;
0035:        import org.w3c.dom.Node;
0036:
0037:        import org.sakaiproject.tool.assessment.data.ifc.assessment.AnswerIfc;
0038:        import org.sakaiproject.tool.assessment.data.ifc.assessment.ItemTextIfc;
0039:        import org.sakaiproject.tool.assessment.qti.asi.Item;
0040:        import org.sakaiproject.tool.assessment.qti.constants.AuthoringConstantStrings;
0041:        import org.sakaiproject.tool.assessment.qti.constants.QTIVersion;
0042:        import org.sakaiproject.tool.assessment.qti.helper.AuthoringXml;
0043:        import org.sakaiproject.tool.assessment.data.ifc.assessment.AnswerFeedbackIfc;
0044:
0045:        /**
0046:         * <p>Version for QTI 1.2 item XML, significant differences between 1.2 and 2.0</p>
0047:         * * @version $Id: ItemHelper12Impl.java 9274 2006-05-10 22:50:48Z daisyf@stanford.edu $
0048:         * 
0049:         * Many methods in Fill in Blank and Numerical Responses(FIN) are identical for now.  
0050:         * This might change if we want to add random variable, parameterized calculation....
0051:         * 
0052:         */
0053:
0054:        public class ItemHelper12Impl extends ItemHelperBase implements 
0055:                ItemHelperIfc {
0056:            private static Log log = LogFactory.getLog(ItemHelper12Impl.class);
0057:            private static final String MATCH_XPATH = "item/presentation/flow/response_grp/render_choice";
0058:            private static final String NBSP = "&#160;";
0059:
0060:            //private Document doc;
0061:
0062:            protected String[] itemTypes = AuthoringConstantStrings.itemTypes;
0063:            private AuthoringXml authoringXml;
0064:            private List allIdents;
0065:            private Float currentMaxScore = new Float(0);
0066:            private float currentPerItemScore = 0;
0067:
0068:            /**
0069:             *
0070:             */
0071:            public ItemHelper12Impl() {
0072:                super ();
0073:                authoringXml = new AuthoringXml(getQtiVersion());
0074:                allIdents = new ArrayList();
0075:
0076:                log.debug("ItemHelper12Impl");
0077:            }
0078:
0079:            protected AuthoringXml getAuthoringXml() {
0080:                return authoringXml;
0081:            }
0082:
0083:            /**
0084:             * get the qti version
0085:             * @return
0086:             */
0087:            protected int getQtiVersion() {
0088:                return QTIVersion.VERSION_1_2;
0089:            }
0090:
0091:            /**
0092:             * Add maximum  score to item XML.
0093:             * @param score
0094:             * @param itemXml
0095:             */
0096:            public void addMaxScore(Float score, Item itemXml) {
0097:                String xPath = "item/resprocessing/outcomes/decvar/@maxvalue";
0098:                if (score == null) {
0099:                    score = new Float(0);
0100:                }
0101:                currentMaxScore = score;
0102:                updateItemXml(itemXml, xPath, "" + score.toString());
0103:            }
0104:
0105:            /**
0106:             * Add minimum score to item XML
0107:             * @param score
0108:             * @param itemXml
0109:             */
0110:            public void addMinScore(Float score, Item itemXml) {
0111:                String xPath = "item/resprocessing/outcomes/decvar/@minvalue";
0112:                updateItemXml(itemXml, xPath, "0");
0113:            }
0114:
0115:            /**
0116:             * Flags an answer as correct.
0117:             * @param correctAnswerLabel the answer that is correct
0118:             * @param itemXml the encapsulation of the item xml
0119:             */
0120:            public void addCorrectAnswer(String correctAnswerLabel, Item itemXml) {
0121:                this .flagAnswerCorrect(correctAnswerLabel, itemXml, true);
0122:            }
0123:
0124:            /**
0125:             * Flags an answer as INCORRECT.
0126:             * Currently, only used for true false questions.
0127:             * @param incorrectAnswerLabel the answer that is NOT correct
0128:             * @param itemXml the encapsulation of the item xml
0129:             */
0130:            public void addIncorrectAnswer(String incorrectAnswerLabel,
0131:                    Item itemXml) {
0132:                this .flagAnswerCorrect(incorrectAnswerLabel, itemXml, false);
0133:            }
0134:
0135:            /**
0136:             * Flags an answer as correct/incorrect.
0137:             * @param correctAnswerLabel the answer that is correct
0138:             * @param itemXml the encapsulation of the item xml
0139:             * @param correct true, or false if not correct
0140:             */
0141:            public void flagAnswerCorrect(String answerLabel, Item itemXml,
0142:                    boolean correct) {
0143:                if (answerLabel == null) {
0144:                    answerLabel = "";
0145:                }
0146:                String flag;
0147:                if (correct) {
0148:                    flag = "Correct";
0149:
0150:                } else {
0151:                    flag = "InCorrect";
0152:                }
0153:
0154:                String respProcBaseXPath = "item/resprocessing/respcondition";
0155:                String respProcCondXPath = "/conditionvar/varequal";
0156:                String respProcFeedbackXPath = "/displayfeedback/@linkrefid";
0157:
0158:                int respSize = 0;
0159:
0160:                // now get each response and flag correct answer
0161:                List resp = itemXml.selectNodes(respProcBaseXPath);
0162:
0163:                if ((resp != null) && (resp.size() > 0)) {
0164:                    respSize = resp.size();
0165:                }
0166:
0167:                for (int i = 1; i <= respSize; i++) {
0168:                    String index = ("[" + i) + "]";
0169:                    String answerVar = itemXml.selectSingleValue(
0170:                            respProcBaseXPath + index + respProcCondXPath,
0171:                            "element");
0172:
0173:                    if (answerLabel.equals(answerVar)) //found right displayfeedback
0174:                    {
0175:                        String xPath = respProcBaseXPath + index + "/@title";
0176:                        String xfPath = respProcBaseXPath + index
0177:                                + respProcFeedbackXPath;
0178:                        updateItemXml(itemXml, xPath, flag);
0179:                        updateItemXml(itemXml, xfPath, flag);
0180:                        break; //done
0181:                    }
0182:                }
0183:            }
0184:
0185:            /**
0186:             * Add/update a response label entry
0187:             * @param itemXml
0188:             * @param xpath
0189:             * @param itemText
0190:             * @param isInsert
0191:             * @param responseNo
0192:             * @param responseLabelIdent
0193:             */
0194:            public void addResponseEntry(Item itemXml, String xpath,
0195:                    String value, boolean isInsert, String responseNo,
0196:                    String responseLabel) {
0197:                if (isInsert) {
0198:                    String nextNode = "response_label[" + responseNo + "]";
0199:                    itemXml.insertElement(nextNode, xpath, "response_label");
0200:                    itemXml.add(xpath + "/response_label[" + responseNo + "]",
0201:                            "material/mattext");
0202:                } else {
0203:                    itemXml.add(xpath, "response_label/material/mattext");
0204:                }
0205:                try {
0206:                    // put CDATA around answers 
0207:                    log.debug("putting CDATA around : " + value);
0208:                    value = "<![CDATA[" + value + "]]>";
0209:                    itemXml.update(xpath + "/response_label[" + responseNo
0210:                            + "]/material/mattext", value);
0211:                } catch (Exception ex) {
0212:                    log.error("Cannot update value in addResponselEntry(): "
0213:                            + ex);
0214:                }
0215:
0216:                String newPath = xpath + "/response_label[" + responseNo + "]";
0217:                itemXml.addAttribute(newPath, "ident");
0218:                newPath = xpath + "/response_label[" + responseNo + "]/@ident";
0219:                updateItemXml(itemXml, newPath, responseLabel);
0220:            }
0221:
0222:            /**
0223:             * Add Item Feedback for a given response number.
0224:             * @param itemXml the item xml
0225:             * @param responseNo the numnber
0226:             */
0227:            private void addItemfeedback(Item itemXml, String value,
0228:                    boolean isInsert, String responseNo, String responseLabel)
0229:
0230:            {
0231:                String xpath = "item";
0232:
0233:                String nextNode = "itemfeedback[" + responseNo + "]";
0234:
0235:                if (isInsert) {
0236:                    itemXml.insertElement(nextNode, xpath, "itemfeedback");
0237:                    itemXml.add(xpath + "/itemfeedback[" + responseNo + "]",
0238:                            "flow_mat/material/mattext");
0239:
0240:                    /*
0241:                     itemXml.add(
0242:                     xpath, "itemfeedback/flow_mat/material/mattext");
0243:                     */
0244:                } else {
0245:                }
0246:                try {
0247:                    if (value == null) {
0248:                        value = "";
0249:                    }
0250:                    value = "<![CDATA[" + value + "]]>";
0251:                    itemXml.update(xpath + "/itemfeedback[" + responseNo
0252:                            + "]/flow_mat/material/mattext", value);
0253:                } catch (Exception ex) {
0254:                    log
0255:                            .error("Cannot update value in addItemfeedback(): "
0256:                                    + ex);
0257:                }
0258:
0259:                String newPath = xpath + "/itemfeedback[" + responseNo + "]";
0260:                itemXml.addAttribute(newPath, "ident");
0261:                newPath = xpath + "/itemfeedback[" + responseNo + "]/@ident";
0262:                String feedbackIdent = responseLabel;
0263:                updateItemXml(itemXml, newPath, feedbackIdent);
0264:
0265:            }
0266:
0267:            /**
0268:             * Get the metadata field entry XPath
0269:             * @return the XPath
0270:             */
0271:            public String getMetaXPath() {
0272:                String xpath = "item/itemmetadata/qtimetadata";
0273:                return xpath;
0274:            }
0275:
0276:            /**
0277:             * Get the metadata field entry XPath for a given label
0278:             * @param fieldlabel
0279:             * @return the XPath
0280:             */
0281:            public String getMetaLabelXPath(String fieldlabel) {
0282:                String xpath = "item/itemmetadata/qtimetadata/qtimetadatafield/fieldlabel[text()='"
0283:                        + fieldlabel + "']/following-sibling::fieldentry";
0284:                return xpath;
0285:            }
0286:
0287:            /**
0288:             * Get the text for the item
0289:             * @param itemXml
0290:             * @return the text
0291:             */
0292:            public String getText(Item itemXml) {
0293:                String xpath = "item/presentation/flow/material/mattext";
0294:                String itemType = itemXml.getItemType();
0295:                if (itemType.equals(AuthoringConstantStrings.MATCHING)) {
0296:                    xpath = "item/presentation/flow//mattext";
0297:                }
0298:
0299:                return makeItemNodeText(itemXml, xpath);
0300:            }
0301:
0302:            /**
0303:             * Matching only, sets each source to be matched to.
0304:             * It also sets the the matching target.
0305:             * @param itemTextList lvalue of matches
0306:             * @param itemXml
0307:             */
0308:            private void setItemTextMatching(List itemTextList, Item itemXml) {
0309:                String xpath = MATCH_XPATH;
0310:                Map allTargets = new HashMap();
0311:                itemXml.add(xpath, "response_label");
0312:                String randomNumber = ("" + Math.random()).substring(2);
0313:                Iterator iter = itemTextList.iterator();
0314:                float itSize = itemTextList.size();
0315:
0316:                // just in case we screw up
0317:                if (itSize > 0) {
0318:                    currentPerItemScore = currentMaxScore.floatValue() / itSize;
0319:                }
0320:                int respCondCount = 0; //used to count the respconditions
0321:
0322:                while (iter.hasNext()) {
0323:                    ItemTextIfc itemText = (ItemTextIfc) iter.next();
0324:                    String text = itemText.getText();
0325:                    Long sequence = itemText.getSequence();
0326:
0327:                    String responseLabelIdent = "MS-" + randomNumber + "-"
0328:                            + sequence;
0329:
0330:                    List answerList = itemText.getAnswerArray();
0331:                    Iterator aiter = answerList.iterator();
0332:                    int noSources = answerList.size();
0333:                    while (aiter.hasNext()) {
0334:                        respCondCount++;
0335:                        AnswerIfc answer = (AnswerIfc) aiter.next();
0336:                        String answerText = answer.getText();
0337:                        String label = answer.getLabel();
0338:                        Long answerSequence = answer.getSequence();
0339:                        Boolean correct = answer.getIsCorrect();
0340:                        String responseFeedback = "";
0341:                        if (correct.booleanValue()) {
0342:                            responseFeedback = answer
0343:                                    .getAnswerFeedback(AnswerFeedbackIfc.CORRECT_FEEDBACK);
0344:                        } else {
0345:                            responseFeedback = answer
0346:                                    .getAnswerFeedback(AnswerFeedbackIfc.INCORRECT_FEEDBACK);
0347:                        }
0348:
0349:                        if (responseFeedback == null) {
0350:                            responseFeedback = "";
0351:                        }
0352:                        String responseNo = ""
0353:                                + (answerSequence.longValue() - noSources + 1);
0354:                        String respIdent = "MT-" + randomNumber + "-" + label;
0355:
0356:                        String respCondNo = "" + respCondCount;
0357:                        responseFeedback = "<![CDATA[" + responseFeedback
0358:                                + "]]>";
0359:                        // add source (addMatchingRespcondition())
0360:                        if (Boolean.TRUE.equals(correct)) {
0361:                            log.debug("Matching: matched.");
0362:                            allIdents.add(respIdent); // put in global (ewww) ident list
0363:                            allTargets.put(respIdent, answerText);
0364:                            addMatchingRespcondition(true, itemXml, respCondNo,
0365:                                    respIdent, responseLabelIdent,
0366:                                    responseFeedback);
0367:                        } else {
0368:                            log.debug("Matching: NOT matched.");
0369:                            addMatchingRespcondition(false, itemXml,
0370:                                    respCondNo, respIdent, responseLabelIdent,
0371:                                    responseFeedback);
0372:                            continue; // we skip adding the response label when false
0373:                        }
0374:                    }
0375:
0376:                    String responseNo = "" + sequence;
0377:                    addMatchingResponseLabelSource(itemXml, responseNo,
0378:                            responseLabelIdent, text);
0379:                }
0380:
0381:                // add targets (addMatchingResponseLabelTarget())
0382:                for (int i = 0; i < allIdents.size(); i++) {
0383:                    String respIdent = (String) allIdents.get(i);
0384:                    String answerText = (String) allTargets.get(respIdent);
0385:                    String responseNo = "" + (i + 1);
0386:                    addMatchingResponseLabelTarget(itemXml, responseNo,
0387:                            respIdent, answerText);
0388:
0389:                }
0390:                updateAllSourceMatchGroup(itemXml);
0391:            }
0392:
0393:            //////////////////////////////////////////////////////////////////////////////
0394:            // FILL IN THE BLANK
0395:            //////////////////////////////////////////////////////////////////////////////
0396:
0397:            /**
0398:             * Set the item text.
0399:             * This is only valid for FIB,a single item text separated by '{}'.
0400:             * @param itemText text to be updated, the syntax is in the form:
0401:             * 'roses are {} and violets are {}.' -> 'roses are ',' and violets are ','.'
0402:             * @param itemXml
0403:             */
0404:            private void setItemTextFIB(String fibAns, Item itemXml) {
0405:                if ((fibAns != null) && (fibAns.trim().length() > 0)) {
0406:                    List fibList = parseFillInBlank(fibAns);
0407:                    Map valueMap = null;
0408:                    //Set newSet = null;
0409:                    String mattext = null;
0410:                    String respStr = null;
0411:                    String xpath = "item/presentation/flow/flow";
0412:                    //String position = null;
0413:                    //String[] responses = null;
0414:
0415:                    if ((fibList != null) && (fibList.size() > 0)) {
0416:
0417:                        //List idsAndResponses = new ArrayList();
0418:                        //1. add Mattext And Responses
0419:                        for (int i = 0; i < fibList.size(); i++) {
0420:
0421:                            valueMap = (Map) fibList.get(i);
0422:
0423:                            if ((valueMap != null) && (valueMap.size() > 0)) {
0424:                                mattext = (String) valueMap.get("text");
0425:                                //wrap mattext with cdata
0426:                                mattext = "<![CDATA[" + mattext + "]]>";
0427:
0428:                                if (mattext != null) {
0429:                                    //add mattext
0430:                                    itemXml.add(xpath, "material/mattext");
0431:                                    String newXpath = xpath
0432:                                            + "/material["
0433:                                            + (new Integer(i + 1).toString() + "]/mattext");
0434:
0435:                                    updateItemXml(itemXml, newXpath, mattext);
0436:                                }
0437:
0438:                                respStr = (String) valueMap.get("ans");
0439:
0440:                                if (respStr != null) {
0441:                                    //add response_str
0442:                                    itemXml.add(xpath,
0443:                                            "response_str/render_fib");
0444:                                    String newXpath = xpath
0445:                                            + "/response_str["
0446:                                            + (new Integer(i + 1).toString() + "]");
0447:
0448:                                    itemXml.addAttribute(newXpath, "ident");
0449:                                    String ident = "FIB0" + i;
0450:                                    updateItemXml(itemXml,
0451:                                            newXpath + "/@ident", ident);
0452:
0453:                                    itemXml.addAttribute(newXpath,
0454:                                            "rcardinality");
0455:                                    updateItemXml(itemXml, newXpath
0456:                                            + "/@rcardinality", "Ordered");
0457:
0458:                                    newXpath = newXpath + "/render_fib";
0459:                                    itemXml.addAttribute(newXpath, "fibtype");
0460:                                    updateItemXml(itemXml, newXpath
0461:                                            + "/@fibtype", "String");
0462:
0463:                                    itemXml.addAttribute(newXpath, "prompt");
0464:                                    updateItemXml(itemXml, newXpath
0465:                                            + "/@prompt", "Box");
0466:
0467:                                    itemXml.addAttribute(newXpath, "columns");
0468:                                    updateItemXml(itemXml, newXpath
0469:                                            + "/@columns", (new Integer(respStr
0470:                                            .length() + 5).toString()));
0471:
0472:                                    itemXml.addAttribute(newXpath, "rows");
0473:                                    updateItemXml(itemXml, newXpath + "/@rows",
0474:                                            "1");
0475:
0476:                                    // we throw this into our global (ugh) list of idents
0477:                                    allIdents.add(ident);
0478:                                }
0479:                            }
0480:                        }
0481:                    }
0482:                }
0483:            }
0484:
0485:            /**
0486:             * we ensure that answer text between brackets is always nonempty, also that
0487:             * starting text is nonempty, we use a non-breaking space for this purpose
0488:             * @param fib
0489:             * @return
0490:             */
0491:            private static String padFibWithNonbreakSpacesText(String fib) {
0492:
0493:                if (fib.startsWith("{")) {
0494:                    fib = NBSP + fib;
0495:                }
0496:                return fib.replaceAll("\\}\\{", "}" + NBSP + "{");
0497:            }
0498:
0499:            /**
0500:             * Special FIB processing.
0501:             * @param itemXml
0502:             * @param responseCondNo
0503:             * @param respIdent
0504:             * @param points
0505:             * @param responses
0506:             * @return
0507:             */
0508:            private Item addFIBRespconditionNotMutuallyExclusive(Item itemXml,
0509:                    String responseCondNo, String respIdent, String points,
0510:                    String[] responses) {
0511:                String xpath = "item/resprocessing";
0512:                itemXml.add(xpath, "respcondition");
0513:                String respCond = "item/resprocessing/respcondition["
0514:                        + responseCondNo + "]";
0515:                itemXml.addAttribute(respCond, "continue");
0516:                updateItemXml(itemXml, respCond + "/@continue", "Yes");
0517:
0518:                String or = "";
0519:
0520:                itemXml.add(respCond, "conditionvar/or");
0521:                or = respCond + "/conditionvar/or";
0522:
0523:                for (int i = 0; i < responses.length; i++) {
0524:                    itemXml.add(or, "varequal");
0525:                    int iString = i + 1;
0526:                    String varequal = or + "/varequal[" + iString + "]";
0527:                    itemXml.addAttribute(varequal, "case");
0528:                    itemXml.addAttribute(varequal, "respident");
0529:
0530:                    updateItemXml(itemXml, varequal + "/@case", "No");
0531:
0532:                    updateItemXml(itemXml, varequal + "/@respident", respIdent);
0533:                    // need to wrap CDATA for responses[i]  .  
0534:                    String wrapcdata_response = "<![CDATA[" + responses[i]
0535:                            + "]]>";
0536:                    updateItemXml(itemXml, varequal, wrapcdata_response);
0537:                }
0538:
0539:                //Add setvar
0540:                itemXml.add(respCond, "setvar");
0541:                itemXml.addAttribute(respCond + "/setvar", "action");
0542:
0543:                updateItemXml(itemXml, respCond + "/setvar/@action", "Add");
0544:                itemXml.addAttribute(respCond + "/setvar", "varname");
0545:
0546:                updateItemXml(itemXml, respCond + "/setvar/@varname", "SCORE");
0547:
0548:                updateItemXml(itemXml, respCond + "/setvar", points); // this should be minimum value
0549:
0550:                return itemXml;
0551:            }
0552:
0553:            /**
0554:             * Special FIB processing.
0555:             * @param itemXml
0556:             * @param responseCondNo
0557:             * @param respIdents
0558:             * @param points
0559:             * @param response
0560:             * @return
0561:             */
0562:            private Item addFIBRespconditionMutuallyExclusive(Item itemXml,
0563:                    String responseCondNo, ArrayList respIdents, String points,
0564:                    String response) {
0565:                String xpath = "item/resprocessing";
0566:                itemXml.add(xpath, "respcondition");
0567:                String respCond = "item/resprocessing/respcondition["
0568:                        + responseCondNo + "]";
0569:                itemXml.addAttribute(respCond, "continue");
0570:
0571:                updateItemXml(itemXml, respCond + "/@continue", "Yes");
0572:
0573:                String or = "";
0574:                itemXml.add(respCond, "conditionvar/or");
0575:                or = respCond + "/conditionvar/or";
0576:
0577:                for (int i = 0; i < respIdents.size(); i++) {
0578:                    int iString = i + 1;
0579:
0580:                    itemXml.add(or, "varequal");
0581:                    String varequal = or + "/varequal[" + (i + 1) + "]";
0582:                    itemXml.addAttribute(varequal, "case");
0583:                    itemXml.addAttribute(varequal, "respident");
0584:
0585:                    updateItemXml(itemXml, varequal + "/@case", "No");
0586:
0587:                    updateItemXml(itemXml, varequal + "/@respident",
0588:                            (String) respIdents.get(i));
0589:                    updateItemXml(itemXml, varequal, response);
0590:                }
0591:
0592:                //Add setvar
0593:                itemXml.add(respCond, "setvar");
0594:                itemXml.addAttribute(respCond + "/setvar", "action");
0595:
0596:                updateItemXml(itemXml, respCond + "/setvar/@action", "Add");
0597:                itemXml.addAttribute(respCond + "/setvar", "varname");
0598:
0599:                updateItemXml(itemXml, respCond + "/setvar/@varname", "SCORE");
0600:
0601:                updateItemXml(itemXml, respCond + "/setvar", points); // this should be minimum value
0602:
0603:                return itemXml;
0604:            }
0605:
0606:            /**
0607:             * Special FIB processing.
0608:             * @param itemXml
0609:             * @param responseCondNo
0610:             * @return
0611:             */
0612:            private Item addFIBRespconditionCorrectFeedback(Item itemXml,
0613:                    String responseCondNo) {
0614:                String xpath = "item/resprocessing";
0615:                itemXml.add(xpath, "respcondition");
0616:                String respCond = "item/resprocessing/respcondition["
0617:                        + responseCondNo + "]";
0618:                itemXml.addAttribute(respCond, "continue");
0619:
0620:                updateItemXml(itemXml, respCond + "/@continue", "Yes");
0621:
0622:                String and = "";
0623:
0624:                itemXml.add(respCond, "conditionvar/and");
0625:                and = respCond + "/conditionvar/and";
0626:
0627:                for (int i = 1; i < (new Integer(responseCondNo)).intValue(); i++) {
0628:                    List or = itemXml
0629:                            .selectNodes("item/resprocessing/respcondition["
0630:                                    + i + "]/conditionvar/or");
0631:                    if (or != null) {
0632:                        itemXml.addElement(and, ((Element) or.get(0)));
0633:                    }
0634:                }
0635:
0636:                //Add display feedback
0637:                itemXml.add(respCond, "displayfeedback");
0638:                itemXml.addAttribute(respCond + "/displayfeedback",
0639:                        "feedbacktype");
0640:
0641:                updateItemXml(itemXml, respCond
0642:                        + "/displayfeedback/@feedbacktype", "Response");
0643:                itemXml
0644:                        .addAttribute(respCond + "/displayfeedback",
0645:                                "linkrefid");
0646:
0647:                updateItemXml(itemXml,
0648:                        respCond + "/displayfeedback/@linkrefid", "Correct");
0649:                return itemXml;
0650:            }
0651:
0652:            /**
0653:             * Special FIB processing.
0654:             * @param itemXml
0655:             * @param responseCondNo
0656:             * @return
0657:             */
0658:            private Item addFIBRespconditionInCorrectFeedback(Item itemXml,
0659:                    String responseCondNo) {
0660:                String xpath = "item/resprocessing";
0661:                itemXml.add(xpath, "respcondition");
0662:                String respCond = "item/resprocessing/respcondition["
0663:                        + responseCondNo + "]";
0664:                itemXml.addAttribute(respCond, "continue");
0665:
0666:                updateItemXml(itemXml, respCond + "/@continue", "No");
0667:
0668:                itemXml.add(respCond, "conditionvar/other");
0669:
0670:                //			Add display feedback
0671:                itemXml.add(respCond, "displayfeedback");
0672:                itemXml.addAttribute(respCond + "/displayfeedback",
0673:                        "feedbacktype");
0674:
0675:                updateItemXml(itemXml, respCond
0676:                        + "/displayfeedback/@feedbacktype", "Response");
0677:                itemXml
0678:                        .addAttribute(respCond + "/displayfeedback",
0679:                                "linkrefid");
0680:
0681:                updateItemXml(itemXml,
0682:                        respCond + "/displayfeedback/@linkrefid", "InCorrect");
0683:                return itemXml;
0684:            }
0685:
0686:            //////////////////////////////////////////////////////////////////////////////
0687:            // Numeric Response
0688:            //////////////////////////////////////////////////////////////////////////////
0689:
0690:            /**
0691:             * Set the item text.
0692:             * This is only valid for FIN,a single item text separated by '{}'.
0693:             * @param itemText text to be updated, the syntax is in the form:
0694:             * 'roses are {} and violets are {}.' -> 'roses are ',' and violets are ','.'
0695:             * @param itemXml
0696:             */
0697:            private void setItemTextFIN(String finAns, Item itemXml) {
0698:                if ((finAns != null) && (finAns.trim().length() > 0)) {
0699:                    List finList = parseFillInNumeric(finAns);
0700:                    Map valueMap = null;
0701:                    Set newSet = null;
0702:                    String mattext = null;
0703:                    String respStr = null;
0704:                    String xpath = "item/presentation/flow/flow";
0705:                    String position = null;
0706:                    String[] responses = null;
0707:
0708:                    if ((finList != null) && (finList.size() > 0)) {
0709:
0710:                        List idsAndResponses = new ArrayList();
0711:                        //1. add Mattext And Responses
0712:                        for (int i = 0; i < finList.size(); i++) {
0713:
0714:                            valueMap = (Map) finList.get(i);
0715:
0716:                            if ((valueMap != null) && (valueMap.size() > 0)) {
0717:                                mattext = (String) valueMap.get("text");
0718:                                //          wrap mattext with cdata
0719:                                mattext = "<![CDATA[" + mattext + "]]>";
0720:
0721:                                if (mattext != null) {
0722:                                    //add mattext
0723:                                    itemXml.add(xpath, "material/mattext");
0724:                                    String newXpath = xpath
0725:                                            + "/material["
0726:                                            + (new Integer(i + 1).toString() + "]/mattext");
0727:
0728:                                    updateItemXml(itemXml, newXpath, mattext);
0729:                                }
0730:
0731:                                respStr = (String) valueMap.get("ans");
0732:
0733:                                if (respStr != null) {
0734:                                    //add response_str
0735:                                    itemXml.add(xpath,
0736:                                            "response_str/render_fin");
0737:                                    String newXpath = xpath
0738:                                            + "/response_str["
0739:                                            + (new Integer(i + 1).toString() + "]");
0740:
0741:                                    itemXml.addAttribute(newXpath, "ident");
0742:                                    String ident = "FIN0" + i;
0743:                                    updateItemXml(itemXml,
0744:                                            newXpath + "/@ident", ident);
0745:
0746:                                    itemXml.addAttribute(newXpath,
0747:                                            "rcardinality");
0748:                                    updateItemXml(itemXml, newXpath
0749:                                            + "/@rcardinality", "Ordered");
0750:
0751:                                    newXpath = newXpath + "/render_fin";
0752:                                    itemXml.addAttribute(newXpath, "fintype");
0753:                                    updateItemXml(itemXml, newXpath
0754:                                            + "/@fintype", "String");
0755:
0756:                                    itemXml.addAttribute(newXpath, "prompt");
0757:                                    updateItemXml(itemXml, newXpath
0758:                                            + "/@prompt", "Box");
0759:
0760:                                    itemXml.addAttribute(newXpath, "columns");
0761:                                    updateItemXml(itemXml, newXpath
0762:                                            + "/@columns", (new Integer(respStr
0763:                                            .length() + 5).toString()));
0764:
0765:                                    itemXml.addAttribute(newXpath, "rows");
0766:                                    updateItemXml(itemXml, newXpath + "/@rows",
0767:                                            "1");
0768:
0769:                                    // we throw this into our global (ugh) list of idents
0770:                                    allIdents.add(ident);
0771:                                }
0772:                            }
0773:                        }
0774:                    }
0775:                }
0776:            }
0777:
0778:            /**
0779:             * we ensure that answer text between brackets is always nonempty, also that
0780:             * starting text is nonempty, we use a non-breaking space for this purpose
0781:             * @param fin
0782:             * @return
0783:             */
0784:            private static String padFinWithNonbreakSpacesText(String fin) {
0785:
0786:                if (fin.startsWith("{")) {
0787:                    fin = NBSP + fin;
0788:                }
0789:                return fin.replaceAll("\\}\\{", "}" + NBSP + "{");
0790:            }
0791:
0792:            /**
0793:             * Special FIN processing.
0794:             * @param itemXml
0795:             * @param responseCondNo
0796:             * @param respIdent
0797:             * @param points
0798:             * @param responses
0799:             * @return
0800:             */
0801:            private Item addFINRespconditionNotMutuallyExclusive(Item itemXml,
0802:                    String responseCondNo, String respIdent, String points,
0803:                    String[] responses) {
0804:                String xpath = "item/resprocessing";
0805:                itemXml.add(xpath, "respcondition");
0806:                String respCond = "item/resprocessing/respcondition["
0807:                        + responseCondNo + "]";
0808:                itemXml.addAttribute(respCond, "continue");
0809:                updateItemXml(itemXml, respCond + "/@continue", "Yes");
0810:
0811:                String or = "";
0812:
0813:                itemXml.add(respCond, "conditionvar/or");
0814:                or = respCond + "/conditionvar/or";
0815:
0816:                for (int i = 0; i < responses.length; i++) {
0817:                    itemXml.add(or, "varequal");
0818:                    int iString = i + 1;
0819:                    String varequal = or + "/varequal[" + iString + "]";
0820:                    itemXml.addAttribute(varequal, "case");
0821:                    itemXml.addAttribute(varequal, "respident");
0822:
0823:                    updateItemXml(itemXml, varequal + "/@case", "No");
0824:
0825:                    updateItemXml(itemXml, varequal + "/@respident", respIdent);
0826:                    // need to wrap CDATA for responses[i]  .  
0827:                    String wrapcdata_response = "<![CDATA[" + responses[i]
0828:                            + "]]>";
0829:
0830:                    updateItemXml(itemXml, varequal, wrapcdata_response);
0831:                }
0832:
0833:                //Add setvar
0834:                itemXml.add(respCond, "setvar");
0835:                itemXml.addAttribute(respCond + "/setvar", "action");
0836:
0837:                updateItemXml(itemXml, respCond + "/setvar/@action", "Add");
0838:                itemXml.addAttribute(respCond + "/setvar", "varname");
0839:
0840:                updateItemXml(itemXml, respCond + "/setvar/@varname", "SCORE");
0841:
0842:                updateItemXml(itemXml, respCond + "/setvar", points); // this should be minimum value
0843:
0844:                return itemXml;
0845:            }
0846:
0847:            /**
0848:             * Special FIN processing.
0849:             * @param itemXml
0850:             * @param responseCondNo
0851:             * @param respIdents
0852:             * @param points
0853:             * @param response
0854:             * @return
0855:             */
0856:            private Item addFINRespconditionMutuallyExclusive(Item itemXml,
0857:                    String responseCondNo, ArrayList respIdents, String points,
0858:                    String response) {
0859:                String xpath = "item/resprocessing";
0860:                itemXml.add(xpath, "respcondition");
0861:                String respCond = "item/resprocessing/respcondition["
0862:                        + responseCondNo + "]";
0863:                itemXml.addAttribute(respCond, "continue");
0864:
0865:                updateItemXml(itemXml, respCond + "/@continue", "Yes");
0866:
0867:                String or = "";
0868:                itemXml.add(respCond, "conditionvar/or");
0869:                or = respCond + "/conditionvar/or";
0870:
0871:                for (int i = 0; i < respIdents.size(); i++) {
0872:                    int iString = i + 1;
0873:
0874:                    itemXml.add(or, "varequal");
0875:                    String varequal = or + "/varequal[" + (i + 1) + "]";
0876:                    itemXml.addAttribute(varequal, "case");
0877:                    itemXml.addAttribute(varequal, "respident");
0878:
0879:                    updateItemXml(itemXml, varequal + "/@case", "No");
0880:
0881:                    updateItemXml(itemXml, varequal + "/@respident",
0882:                            (String) respIdents.get(i));
0883:                    updateItemXml(itemXml, varequal, response);
0884:                }
0885:
0886:                //Add setvar
0887:                itemXml.add(respCond, "setvar");
0888:                itemXml.addAttribute(respCond + "/setvar", "action");
0889:
0890:                updateItemXml(itemXml, respCond + "/setvar/@action", "Add");
0891:                itemXml.addAttribute(respCond + "/setvar", "varname");
0892:
0893:                updateItemXml(itemXml, respCond + "/setvar/@varname", "SCORE");
0894:
0895:                updateItemXml(itemXml, respCond + "/setvar", points); // this should be minimum value
0896:
0897:                return itemXml;
0898:            }
0899:
0900:            /**
0901:             * Special FIN processing.
0902:             * @param itemXml
0903:             * @param responseCondNo
0904:             * @return
0905:             */
0906:            private Item addFINRespconditionCorrectFeedback(Item itemXml,
0907:                    String responseCondNo) {
0908:                String xpath = "item/resprocessing";
0909:                itemXml.add(xpath, "respcondition");
0910:                String respCond = "item/resprocessing/respcondition["
0911:                        + responseCondNo + "]";
0912:                itemXml.addAttribute(respCond, "continue");
0913:
0914:                updateItemXml(itemXml, respCond + "/@continue", "Yes");
0915:
0916:                String and = "";
0917:
0918:                itemXml.add(respCond, "conditionvar/and");
0919:                and = respCond + "/conditionvar/and";
0920:
0921:                for (int i = 1; i < (new Integer(responseCondNo)).intValue(); i++) {
0922:                    List or = itemXml
0923:                            .selectNodes("item/resprocessing/respcondition["
0924:                                    + i + "]/conditionvar/or");
0925:                    if (or != null) {
0926:                        itemXml.addElement(and, ((Element) or.get(0)));
0927:                    }
0928:                }
0929:
0930:                //Add display feedback
0931:                itemXml.add(respCond, "displayfeedback");
0932:                itemXml.addAttribute(respCond + "/displayfeedback",
0933:                        "feedbacktype");
0934:
0935:                updateItemXml(itemXml, respCond
0936:                        + "/displayfeedback/@feedbacktype", "Response");
0937:                itemXml
0938:                        .addAttribute(respCond + "/displayfeedback",
0939:                                "linkrefid");
0940:
0941:                updateItemXml(itemXml,
0942:                        respCond + "/displayfeedback/@linkrefid", "Correct");
0943:                return itemXml;
0944:            }
0945:
0946:            /**
0947:             * Special FIN processing.
0948:             * @param itemXml
0949:             * @param responseCondNo
0950:             * @return
0951:             */
0952:            private Item addFINRespconditionInCorrectFeedback(Item itemXml,
0953:                    String responseCondNo) {
0954:                String xpath = "item/resprocessing";
0955:                itemXml.add(xpath, "respcondition");
0956:                String respCond = "item/resprocessing/respcondition["
0957:                        + responseCondNo + "]";
0958:                itemXml.addAttribute(respCond, "continue");
0959:
0960:                updateItemXml(itemXml, respCond + "/@continue", "No");
0961:
0962:                itemXml.add(respCond, "conditionvar/other");
0963:
0964:                //			Add display feedback
0965:                itemXml.add(respCond, "displayfeedback");
0966:                itemXml.addAttribute(respCond + "/displayfeedback",
0967:                        "feedbacktype");
0968:
0969:                updateItemXml(itemXml, respCond
0970:                        + "/displayfeedback/@feedbacktype", "Response");
0971:                itemXml
0972:                        .addAttribute(respCond + "/displayfeedback",
0973:                                "linkrefid");
0974:
0975:                updateItemXml(itemXml,
0976:                        respCond + "/displayfeedback/@linkrefid", "InCorrect");
0977:                return itemXml;
0978:            }
0979:
0980:            /**
0981:             *
0982:             * @param idsAndResponses
0983:             * @return
0984:             */
0985:            private ArrayList getSimilarCorrectAnswerIDs(List idsAndResponses) {
0986:                String[] compareResponse = null;
0987:                ArrayList finalArray = new ArrayList(); // this is list of maps which contains arrayList  correct responses and ids
0988:                ArrayList idList = new ArrayList();
0989:                //ArrayList responseList = new ArrayList();
0990:                Map intermediaryMap = new HashMap();
0991:                for (int l = 0; l < idsAndResponses.size(); l++) {
0992:                    Map idsAndResponsesMap = (Map) idsAndResponses.get(l);
0993:                    Set set = idsAndResponsesMap.keySet();
0994:                    Iterator keys = set.iterator();
0995:                    while (keys.hasNext()) {
0996:                        String respIdent = (String) keys.next();
0997:                        String[] responses = null;
0998:                        if ((respIdent != null) && (respIdent.length() > 0)) {
0999:                            responses = (String[]) idsAndResponsesMap
1000:                                    .get(respIdent);
1001:                        }
1002:
1003:                        boolean newElement = true;
1004:                        for (int i = 0; i < finalArray.size(); i++) {
1005:                            Map currentEntry = (Map) finalArray.get(i);
1006:                            Set entrySet = currentEntry.keySet();
1007:                            Iterator entrykeys = entrySet.iterator();
1008:                            while (entrykeys.hasNext()) {
1009:                                compareResponse = (String[]) entrykeys.next();
1010:                                if (Arrays.equals(responses, compareResponse)) {
1011:                                    idList = (ArrayList) currentEntry
1012:                                            .get(compareResponse);
1013:                                    idList.add(respIdent);
1014:                                    newElement = false;
1015:                                }
1016:                            }
1017:                        }
1018:
1019:                        if ((finalArray.size() == 0) || (newElement)) {
1020:                            idList = new ArrayList();
1021:                            idList.add(respIdent);
1022:                            intermediaryMap = new HashMap();
1023:                            intermediaryMap.put(responses, idList);
1024:                            finalArray.add(intermediaryMap);
1025:                        }
1026:                    }
1027:                }
1028:                return finalArray;
1029:            }
1030:
1031:            /**
1032:             * Special FIB processing.
1033:             * @param itemXml
1034:             * @param idsAndResponses
1035:             * @param allIdents
1036:             * @param isMutuallyExclusive
1037:             * @param points
1038:             * @return
1039:             */
1040:            private Item addFIBRespconditions(Item itemXml,
1041:                    List idsAndResponses, List allIdents,
1042:                    boolean isMutuallyExclusive, String points) {
1043:                if (idsAndResponses.size() > 0) {
1044:                    ArrayList combinationResponses = getSimilarCorrectAnswerIDs(idsAndResponses);
1045:                    if (combinationResponses != null
1046:                            && combinationResponses.size() > 0) {
1047:                        int respConditionNo = 1;
1048:                        for (int i = 0; i < combinationResponses.size(); i++) {
1049:                            Map currentEntry = (Map) combinationResponses
1050:                                    .get(i);
1051:                            Set entrySet = currentEntry.keySet();
1052:                            Iterator entrykeys = entrySet.iterator();
1053:                            while (entrykeys.hasNext()) {
1054:                                String[] responses = (String[]) entrykeys
1055:                                        .next();
1056:                                ArrayList idList = (ArrayList) currentEntry
1057:                                        .get(responses);
1058:                                if (idList != null && idList.size() > 0) {
1059:                                    if (idList.size() == 1) {
1060:                                        addFIBRespconditionNotMutuallyExclusive(
1061:                                                itemXml, new Integer(
1062:                                                        respConditionNo)
1063:                                                        .toString(),
1064:                                                (String) idList.get(0), points,
1065:                                                responses);
1066:                                        respConditionNo = respConditionNo + 1;
1067:                                    } else {
1068:                                        for (int k = 0; k < responses.length; k++) {
1069:
1070:                                            addFIBRespconditionMutuallyExclusive(
1071:                                                    itemXml, new Integer(
1072:                                                            respConditionNo)
1073:                                                            .toString(),
1074:                                                    idList, points,
1075:                                                    responses[k]);
1076:                                            respConditionNo = respConditionNo + 1;
1077:
1078:                                        }
1079:
1080:                                    }
1081:                                }
1082:                            }
1083:                        }
1084:                        // add respcondition for all correct answers
1085:                        addFIBRespconditionCorrectFeedback(itemXml,
1086:                                new Integer(respConditionNo).toString());
1087:                        respConditionNo = respConditionNo + 1;
1088:                        //add respcondition for all incorrect answers
1089:                        addFIBRespconditionInCorrectFeedback(itemXml,
1090:                                new Integer(respConditionNo).toString());
1091:                    }
1092:
1093:                }
1094:                return itemXml;
1095:            }
1096:
1097:            /**
1098:             * Special FIN processing.
1099:             * @param itemXml
1100:             * @param idsAndResponses
1101:             * @param allIdents
1102:             * @param isMutuallyExclusive
1103:             * @param points
1104:             * @return
1105:             */
1106:
1107:            private Item addFINRespconditions(Item itemXml,
1108:                    List idsAndResponses, List allIdents,
1109:                    boolean isMutuallyExclusive, String points) {
1110:                if (idsAndResponses.size() > 0) {
1111:                    ArrayList combinationResponses = getSimilarCorrectAnswerIDs(idsAndResponses);
1112:                    if (combinationResponses != null
1113:                            && combinationResponses.size() > 0) {
1114:                        int respConditionNo = 1;
1115:                        for (int i = 0; i < combinationResponses.size(); i++) {
1116:                            Map currentEntry = (Map) combinationResponses
1117:                                    .get(i);
1118:                            Set entrySet = currentEntry.keySet();
1119:                            Iterator entrykeys = entrySet.iterator();
1120:                            while (entrykeys.hasNext()) {
1121:                                String[] responses = (String[]) entrykeys
1122:                                        .next();
1123:                                ArrayList idList = (ArrayList) currentEntry
1124:                                        .get(responses);
1125:                                if (idList != null && idList.size() > 0) {
1126:                                    if (idList.size() == 1) {
1127:                                        addFINRespconditionNotMutuallyExclusive(
1128:                                                itemXml, new Integer(
1129:                                                        respConditionNo)
1130:                                                        .toString(),
1131:                                                (String) idList.get(0), points,
1132:                                                responses);
1133:                                        respConditionNo = respConditionNo + 1;
1134:                                    } else {
1135:                                        for (int k = 0; k < responses.length; k++) {
1136:
1137:                                            addFINRespconditionMutuallyExclusive(
1138:                                                    itemXml, new Integer(
1139:                                                            respConditionNo)
1140:                                                            .toString(),
1141:                                                    idList, points,
1142:                                                    responses[k]);
1143:                                            respConditionNo = respConditionNo + 1;
1144:
1145:                                        }
1146:
1147:                                    }
1148:                                }
1149:                            }
1150:                        }
1151:                        // add respcondition for all correct answers
1152:                        addFINRespconditionCorrectFeedback(itemXml,
1153:                                new Integer(respConditionNo).toString());
1154:                        respConditionNo = respConditionNo + 1;
1155:                        // add respcondition for all incorrect answers
1156:                        addFINRespconditionInCorrectFeedback(itemXml,
1157:                                new Integer(respConditionNo).toString());
1158:                    }
1159:
1160:                }
1161:                return itemXml;
1162:            }
1163:
1164:            /**
1165:             *  Get list of form:
1166:             *  {ans=red, text=Roses are},
1167:             *  {ans=blue, text=and violets are},
1168:             *  {ans=null, text=.}
1169:             *  From String of form "Roses are {red} and violets are {blue}."
1170:             *
1171:             * @param input
1172:             * @return list of Maps
1173:             */
1174:            private static List parseFillInBlank(String input) {
1175:                input = padFibWithNonbreakSpacesText(input);
1176:
1177:                Map tempMap = null;
1178:                List storeParts = new ArrayList();
1179:                if (input == null) {
1180:                    return storeParts;
1181:                }
1182:
1183:                StringTokenizer st = new StringTokenizer(input, "}");
1184:                String tempToken = "";
1185:                String[] splitArray = null;
1186:
1187:                while (st.hasMoreTokens()) {
1188:                    tempToken = st.nextToken();
1189:                    tempMap = new HashMap();
1190:
1191:                    //split out text and answer parts from token
1192:                    splitArray = tempToken.trim().split("\\{", 2);
1193:                    tempMap.put("text", splitArray[0].trim());
1194:                    if (splitArray.length > 1) {
1195:
1196:                        tempMap.put("ans", (splitArray[1]));
1197:                    } else {
1198:                        tempMap.put("ans", null);
1199:                    }
1200:
1201:                    storeParts.add(tempMap);
1202:                }
1203:
1204:                return storeParts;
1205:            }
1206:
1207:            private static List parseFillInNumeric(String input) {
1208:                input = padFinWithNonbreakSpacesText(input);
1209:
1210:                Map tempMap = null;
1211:                List storeParts = new ArrayList();
1212:                if (input == null) {
1213:                    return storeParts;
1214:                }
1215:
1216:                StringTokenizer st = new StringTokenizer(input, "}");
1217:                String tempToken = "";
1218:                String[] splitArray = null;
1219:
1220:                while (st.hasMoreTokens()) {
1221:                    tempToken = st.nextToken();
1222:                    tempMap = new HashMap();
1223:
1224:                    //split out text and answer parts from token
1225:                    splitArray = tempToken.trim().split("\\{", 2);
1226:                    tempMap.put("text", splitArray[0].trim());
1227:                    if (splitArray.length > 1) {
1228:
1229:                        tempMap.put("ans", (splitArray[1]));
1230:                    } else {
1231:                        tempMap.put("ans", null);
1232:                    }
1233:
1234:                    storeParts.add(tempMap);
1235:                }
1236:
1237:                return storeParts;
1238:            }
1239:
1240:            private static String[] getPossibleCorrectResponses(String inputStr) {
1241:                String patternStr = ",";
1242:                String[] responses = inputStr.split(patternStr);
1243:                for (int i = 0; i < responses.length; i++) {
1244:                    responses[i] = responses[i].trim();
1245:                }
1246:                Arrays.sort(responses);
1247:
1248:                return responses;
1249:            }
1250:
1251:            /**
1252:             * Set the item text.
1253:             * This is valid for all undelimited single item texts.
1254:             * Not valid for matching or fill in the blank, but OK for instructional text
1255:             * @param itemText text to be updated
1256:             * @param itemXml
1257:             */
1258:            public void setItemText(String itemText, Item itemXml) {
1259:                String xpath = "item/presentation/flow/material/mattext";
1260:
1261:                List list = itemXml.selectNodes(xpath);
1262:                log.debug("in ItemHelper12Impl.java: setItemText() text = "
1263:                        + itemText);
1264:                itemText = "<![CDATA[" + itemText + "]]>";
1265:                log
1266:                        .debug("in ItemHelperBase.java: setItemText() wrapped CDATA text is = "
1267:                                + itemText);
1268:
1269:                try {
1270:                    itemXml.update(xpath, itemText);
1271:                } catch (Exception ex) {
1272:                    log.error(ex.getMessage(), ex);
1273:                }
1274:            }
1275:
1276:            /**
1277:             * Set the (one or more) item texts.
1278:             * Valid for single and multiple texts.
1279:             * @param itemXml
1280:             * @param itemText text to be updated
1281:             */
1282:            public void setItemTexts(ArrayList itemTextList, Item itemXml) {
1283:                if (itemTextList.size() < 1) {
1284:                    return;
1285:                }
1286:
1287:                if (itemXml.isMatching()) {
1288:                    setItemTextMatching(itemTextList, itemXml);
1289:                    return;
1290:                }
1291:
1292:                String text = ((ItemTextIfc) itemTextList.get(0)).getText();
1293:                if (itemXml.isFIB()) {
1294:                    setItemTextFIB(text, itemXml);
1295:                    return;
1296:                } else if (itemXml.isFIN()) {
1297:                    setItemTextFIN(text, itemXml);
1298:                    return;
1299:                } else {
1300:                    setItemText(text, itemXml);
1301:                    return;
1302:                }
1303:
1304:            }
1305:
1306:            /**
1307:             * get item type string
1308:             * @param itemXml
1309:             * @return type as string
1310:             */
1311:            public String getItemType(Item itemXml)
1312:
1313:            {
1314:                String type = itemXml.getFieldentry("qmd_itemtype");
1315:
1316:                return type;
1317:            }
1318:
1319:            /**
1320:             * Set the answer texts for item.
1321:             * @param itemTextList the text(s) for item
1322:             */
1323:
1324:            public void setAnswers(ArrayList itemTextList, Item itemXml) {
1325:
1326:                log.debug("entered setAnswers()");
1327:                log.debug("size=" + itemTextList.size());
1328:                // other types either have no answer or include them in their template, or,
1329:                // in matching, generate all in setItemTextMatching()
1330:                if (!itemXml.isFIB() && !itemXml.isMCSC() && !itemXml.isFIN()
1331:                        && !itemXml.isMCMC() && !itemXml.isEssay()) {
1332:                    return;
1333:                }
1334:
1335:                // OK, so now we are in business.
1336:                String xpath = "item/presentation/flow/response_lid/render_choice";
1337:
1338:                List list = itemXml.selectNodes(xpath);
1339:                Iterator nodeIter = list.iterator();
1340:
1341:                Iterator iter = itemTextList.iterator();
1342:                Set answerSet = new HashSet();
1343:
1344:                char label = 'A';
1345:                int xpathIndex = 1;
1346:                int respIdentCount = 0;
1347:                while (iter.hasNext()) {
1348:                    answerSet = ((ItemTextIfc) iter.next()).getAnswerSet();
1349:                    log.debug("answersize=" + answerSet.size());
1350:                    //System.out.println("answersize=" + answerSet.size());
1351:                    Iterator aiter = answerSet.iterator();
1352:                    while (aiter.hasNext()) {
1353:                        AnswerIfc answer = (AnswerIfc) aiter.next();
1354:                        if (Boolean.TRUE.equals(answer.getIsCorrect())) {
1355:                            this .addCorrectAnswer("" + label, itemXml);
1356:                        }
1357:                        String value = answer.getText();
1358:                        log.debug("\n\n***The answer is: " + value);
1359:                        //System.out.println("\n\n***The answer is: " + value);
1360:                        // if and only if FIB we do special processing
1361:                        if (itemXml.isFIB()) {
1362:                            String[] responses = { value }; // one possible for now
1363:                            String respIdent = (String) allIdents
1364:                                    .get(respIdentCount++);
1365:                            addFIBRespconditionNotMutuallyExclusive(itemXml, ""
1366:                                    + xpathIndex, respIdent, "0", responses);
1367:                            label++;
1368:                            xpathIndex++;
1369:                            continue; //
1370:                        }
1371:
1372:                        if (itemXml.isFIN()) {
1373:                            String[] responses = { value }; // one possible for now
1374:                            String respIdent = (String) allIdents
1375:                                    .get(respIdentCount++);
1376:                            addFINRespconditionNotMutuallyExclusive(itemXml, ""
1377:                                    + xpathIndex, respIdent, "0", responses);
1378:                            label++;
1379:                            xpathIndex++;
1380:                            continue; //
1381:                        }
1382:
1383:                        // process into XML
1384:                        // we assume that we have equal to or more than the requisite elements
1385:                        // if we have more than the existing elements we manufacture more
1386:                        // with labels 'A', 'B'....etc.
1387:                        Node node = null;
1388:                        try {
1389:                            boolean isInsert = true;
1390:                            if (nodeIter.hasNext()) {
1391:                                isInsert = false;
1392:                            }
1393:                            this .addResponseEntry(itemXml, xpath, value,
1394:                                    isInsert, "" + xpathIndex, "" + label);
1395:                        } catch (Exception ex) {
1396:                            log.error("Cannot process source document.", ex);
1397:                        }
1398:
1399:                        label++;
1400:                        xpathIndex++;
1401:                    }
1402:                }
1403:            }
1404:
1405:            /**
1406:             * Set the feedback texts for item.
1407:             * @param itemTextList the text(s) for item
1408:             * @param itemXml
1409:             */
1410:
1411:            public void setFeedback(ArrayList itemTextList, Item itemXml) {
1412:                //log.info("setFeedback()");
1413:
1414:                boolean hasAnswerLevelFeedback = itemXml.isMCMC()
1415:                        || itemXml.isMCSC();
1416:                //log.info("itemXml.getItemType(): " + itemXml.getItemType());
1417:                //log.info("hasAnswerLevelFeedback: " + hasAnswerLevelFeedback);
1418:
1419:                // for any answers that are now in the template, create a feedback
1420:                String xpath = "item/itemfeedback/flow/response_lid/render_choice";
1421:                int xpathIndex = 1;
1422:
1423:                List list = itemXml.selectNodes(xpath);
1424:                Iterator nodeIter = list.iterator();
1425:
1426:                Iterator iter = itemTextList.iterator();
1427:                Set answerSet = new HashSet();
1428:
1429:                char label = 'A';
1430:                boolean first = true;
1431:                while (iter.hasNext()) {
1432:                    ItemTextIfc itemTextIfc = (ItemTextIfc) iter.next();
1433:
1434:                    if (first) // then do once
1435:                    {
1436:                        addCorrectAndIncorrectFeedback(itemXml, itemTextIfc);
1437:                        xpathIndex = 1;
1438:                        first = false;
1439:                    }
1440:
1441:                    if (hasAnswerLevelFeedback) {
1442:                        log.debug("Setting answer level feedback");
1443:
1444:                        answerSet = itemTextIfc.getAnswerSet();
1445:                        log.debug("answerSet.size(): " + answerSet.size());
1446:
1447:                        Iterator aiter = answerSet.iterator();
1448:                        while (aiter.hasNext()) {
1449:                            AnswerIfc answer = (AnswerIfc) aiter.next();
1450:                            //log.info("Setting answer feedback for: " + answer.getText());
1451:                            //log.info("xpathIndex: " + xpathIndex);
1452:                            //log.info("label: " + label);
1453:
1454:                            String value = answer.getGeneralAnswerFeedback();
1455:                            boolean isInsert = true;
1456:                            if (nodeIter.hasNext()) {
1457:                                isInsert = false;
1458:                            }
1459:
1460:                            addAnswerFeedback(itemXml, value, isInsert,
1461:                                    xpathIndex, "" + label);
1462:                            label++;
1463:                            xpathIndex++;
1464:                        }
1465:                    }
1466:
1467:                    addGeneralFeedback(itemXml, xpathIndex, itemTextIfc);
1468:                }
1469:
1470:            }
1471:
1472:            /**
1473:             * Adds feedback with idents of Correct and InCorrect
1474:             * @param itemXml
1475:             * @param itemTextIfc
1476:             */
1477:
1478:            private void addCorrectAndIncorrectFeedback(Item itemXml,
1479:                    ItemTextIfc itemTextIfc) {
1480:                String correctFeedback = itemTextIfc.getItem()
1481:                        .getCorrectItemFeedback();
1482:                String incorrectFeedback = itemTextIfc.getItem()
1483:                        .getInCorrectItemFeedback();
1484:                log.debug("CORRECT FEEDBACK: " + correctFeedback);
1485:                if (correctFeedback != null) {
1486:                    this .addItemfeedback(itemXml, correctFeedback, false, "1",
1487:                            "" + "Correct");
1488:                }
1489:                log.debug("INCORRECT FEEDBACK: " + incorrectFeedback);
1490:                if (incorrectFeedback != null) {
1491:                    this .addItemfeedback(itemXml, incorrectFeedback, false,
1492:                            "2", "" + "InCorrect");
1493:                }
1494:            }
1495:
1496:            /**
1497:             * Adds feedback with ident referencing item ident
1498:             * @param itemXml
1499:             * @param xpathIndex
1500:             * @param itemTextIfc
1501:             */
1502:            private void addGeneralFeedback(Item itemXml, int xpathIndex,
1503:                    ItemTextIfc itemTextIfc) {
1504:                log.debug("\nDebug add in General Feedback");
1505:                String generalFeedback = itemTextIfc.getItem()
1506:                        .getGeneralItemFeedback();
1507:                String itemId = itemTextIfc.getItem().getItemIdString();
1508:                if (generalFeedback != null) {
1509:                    addItemfeedback(itemXml, generalFeedback, true, ""
1510:                            + xpathIndex++, itemId);
1511:                }
1512:            }
1513:
1514:            /**
1515:             * Adds feedback with ident referencing answer ident.
1516:             *
1517:             * @param itemXml
1518:             * @param value
1519:             * @param isInsert
1520:             * @param responseNo
1521:             * @param responseLabel
1522:             */
1523:            private void addAnswerFeedback(Item itemXml, String value,
1524:                    boolean isInsert, int responseNo, String responseLabel) {
1525:                log.debug("addAnswerFeedback()");
1526:                log.debug("answer feedback value: " + value);
1527:                if (value == null) {
1528:                    value = "<![CDATA[]]>";
1529:                } else {
1530:                    value = "<![CDATA[" + value + "]]>";
1531:                }
1532:                String respCond = "item/resprocessing/respcondition["
1533:                        + responseNo + "]";
1534:                updateItemXml(itemXml, respCond + "/setvar", ""
1535:                        + currentPerItemScore);
1536:                updateItemXml(itemXml, respCond
1537:                        + "/displayfeedback[2]/@linkrefid", "AnswerFeedback");
1538:                updateItemXml(itemXml, respCond + "/displayfeedback[2]", value);
1539:            }
1540:
1541:            ////////////////////////////////////////////////////////////////
1542:            // MATCHING
1543:            ////////////////////////////////////////////////////////////////
1544:
1545:            /**
1546:             * Add the matching response label entry source.
1547:             * @param itemXml
1548:             * @param responseNo
1549:             * @param responseLabelIdent
1550:             * @param value
1551:             */
1552:            private void addMatchingResponseLabelTarget(Item itemXml,
1553:                    String responseNo, String respIdent, String value) {
1554:                String xpath = MATCH_XPATH;
1555:                insertResponseLabelMattext(itemXml, responseNo, value, xpath);
1556:
1557:                String newPath = xpath + "/response_label[" + responseNo + "]";
1558:                itemXml.addAttribute(newPath, "ident");
1559:                newPath = xpath + "/response_label[" + responseNo + "]/@ident";
1560:                updateItemXml(itemXml, newPath, respIdent);
1561:            }
1562:
1563:            /**
1564:             * Add the matching response label entry source.
1565:             * @param itemXml
1566:             * @param responseNo
1567:             * @param responseLabelIdent
1568:             * @param value
1569:             */
1570:            private void addMatchingResponseLabelSource(Item itemXml,
1571:                    String responseNo, String responseLabelIdent, String value) {
1572:                String xpath = MATCH_XPATH;
1573:
1574:                insertResponseLabelMattext(itemXml, responseNo, value, xpath);
1575:
1576:                itemXml.addAttribute(xpath + "/response_label[" + responseNo
1577:                        + "]", "match_max");
1578:                itemXml.addAttribute(xpath + "/response_label[" + responseNo
1579:                        + "]", "match_group");
1580:
1581:                updateItemXml(itemXml, xpath + "/response_label[" + responseNo
1582:                        + "]" + "/@match_max", "1");
1583:
1584:                String newPath = xpath + "/response_label[" + responseNo + "]";
1585:                itemXml.addAttribute(newPath, "ident");
1586:                newPath = xpath + "/response_label[" + responseNo + "]/@ident";
1587:                updateItemXml(itemXml, newPath, responseLabelIdent);
1588:            }
1589:
1590:            /**
1591:             * utility method for addMatchingResponseLabelTarget(), addMatchingResponseLabelSource()
1592:             * @param itemXml
1593:             * @param responseNo
1594:             * @param value
1595:             * @param xpath
1596:             */
1597:            private void insertResponseLabelMattext(Item itemXml,
1598:                    String responseNo, String value, String xpath) {
1599:                String nextNode = "response_label[" + responseNo + "]";
1600:                itemXml.insertElement(nextNode, xpath, "response_label");
1601:                itemXml.add(xpath + "/response_label[" + responseNo + "]",
1602:                        "material/mattext");
1603:                try {
1604:
1605:                    log
1606:                            .debug("in ItemHelper12Impl.java: insertResponseLabelMattext() text = "
1607:                                    + value);
1608:                    value = "<![CDATA[" + value + "]]>";
1609:                    log
1610:                            .debug("in ItemHelperBase.java: insertResponseLabelMattext() wrapped CDATA text is = "
1611:                                    + value);
1612:
1613:                    itemXml.update(xpath + "/response_label[" + responseNo
1614:                            + "]/material/mattext", value);
1615:                } catch (Exception ex) {
1616:                    log.warn("Unable to set mattext in '" + xpath
1617:                            + "/response_label[" + responseNo + "]' to '"
1618:                            + value + "'");
1619:                }
1620:            }
1621:
1622:            /**
1623:             * Add the matching item feedback.
1624:             *
1625:             * @param itemXml
1626:             * @param feedbackIdent
1627:             * @param responseNo
1628:             */
1629:            private void addMatchingItemfeedback(Item itemXml,
1630:                    String feedbackIdent, String responseNo) {
1631:                String xpath = "item";
1632:
1633:                String nextNode = "itemfeedback[" + responseNo + "]";
1634:                itemXml.insertElement(nextNode, xpath, "itemfeedback");
1635:                itemXml.add(xpath + "/itemfeedback[" + responseNo + "]",
1636:                        "flow_mat/material/mattext");
1637:
1638:                String newPath = xpath + "/itemfeedback[" + responseNo + "]";
1639:                itemXml.addAttribute(newPath, "ident");
1640:                newPath = xpath + "/itemfeedback[" + responseNo + "]/@ident";
1641:
1642:                updateItemXml(itemXml, newPath, feedbackIdent);
1643:
1644:                //Add placeholder for image
1645:                xpath = xpath + "/itemfeedback[" + responseNo + "]/flow_mat";
1646:                itemXml.add(xpath, "material/matimage");
1647:                xpath = xpath + "/flow_mat/material[2]/matimage";
1648:
1649:                //Image attributes
1650:                itemXml.addAttribute(xpath, "uri");
1651:                itemXml.addAttribute(xpath, "imagetype");
1652:                xpath = xpath + "/@imagetype";
1653:                updateItemXml(itemXml, xpath, "text/html");
1654:            }
1655:
1656:            /**
1657:             * Add matching response condition.
1658:             * @param itemXml
1659:             * @param responseNo
1660:             * @param respident
1661:             * @param responseLabelIdent
1662:             */
1663:            private void addMatchingRespcondition(boolean correct,
1664:                    Item itemXml, String responseNo, String respident,
1665:                    String responseLabelIdent, String responseFeedback) {
1666:
1667:                String xpath = "item/resprocessing";
1668:                itemXml.add(xpath, "respcondition/conditionvar/varequal");
1669:
1670:                String respCond = "item/resprocessing/respcondition["
1671:                        + responseNo + "]";
1672:                itemXml.addAttribute(respCond, "continue");
1673:                updateItemXml(itemXml, respCond + "/@continue", "No");
1674:                itemXml.addAttribute(respCond + "/conditionvar/varequal",
1675:                        "case");
1676:                updateItemXml(itemXml, respCond
1677:                        + "/conditionvar/varequal/@case", "Yes");
1678:                itemXml.addAttribute(respCond + "/conditionvar/varequal",
1679:                        "respident");
1680:                itemXml.addAttribute(respCond + "/conditionvar/varequal",
1681:                        "index");
1682:                updateItemXml(itemXml, respCond
1683:                        + "/conditionvar/varequal/@index", responseNo);
1684:
1685:                if (respident != null) {
1686:
1687:                    updateItemXml(itemXml, respCond
1688:                            + "/conditionvar/varequal/@respident", respident);
1689:                }
1690:
1691:                updateItemXml(itemXml, respCond + "/conditionvar/varequal",
1692:                        responseLabelIdent);
1693:
1694:                //Add setvar
1695:                itemXml.add(respCond, "setvar");
1696:                itemXml.addAttribute(respCond + "/setvar", "action");
1697:                updateItemXml(itemXml, respCond + "/setvar/@action", "Add");
1698:                itemXml.addAttribute(respCond + "/setvar", "varname");
1699:
1700:                updateItemXml(itemXml, respCond + "/setvar/@varname", "SCORE");
1701:
1702:                //Add display feedback
1703:
1704:                itemXml.add(respCond, "displayfeedback");
1705:                itemXml.addAttribute(respCond + "/displayfeedback",
1706:                        "feedbacktype");
1707:                updateItemXml(itemXml, respCond
1708:                        + "/displayfeedback/@feedbacktype", "Response");
1709:                itemXml
1710:                        .addAttribute(respCond + "/displayfeedback",
1711:                                "linkrefid");
1712:
1713:                if (correct) {
1714:                    updateItemXml(itemXml, respCond + "/setvar", ""
1715:                            + currentPerItemScore);
1716:                    updateItemXml(itemXml, respCond
1717:                            + "/displayfeedback/@linkrefid", "CorrectMatch");
1718:                } else {
1719:                    updateItemXml(itemXml, respCond + "/setvar", "0");
1720:                    updateItemXml(itemXml, respCond
1721:                            + "/displayfeedback/@linkrefid", "InCorrectMatch");
1722:                }
1723:
1724:                updateItemXml(itemXml, respCond + "/displayfeedback",
1725:                        responseFeedback);
1726:            }
1727:
1728:            /**
1729:             * Update match group.
1730:             * Uses global internal list of all target idents.
1731:             * (... response_label[not(@match_group)]/@ident)
1732:             * DO NOT CALL before we have all the target idents ready
1733:             * @param itemXml
1734:             */
1735:            private void updateAllSourceMatchGroup(Item itemXml) {
1736:                String matchGroupsXpath = "item/presentation/flow/response_grp/render_choice/response_label[(@match_group)]";
1737:
1738:                if (allIdents.size() > 0) {
1739:                    Iterator iter = allIdents.iterator();
1740:                    String targetIdent = null;
1741:                    String match_group = null;
1742:                    while (iter.hasNext()) {
1743:                        targetIdent = (String) iter.next();
1744:                        if (match_group == null) {
1745:                            match_group = targetIdent;
1746:                        } else {
1747:                            match_group = match_group + "," + targetIdent;
1748:                        }
1749:                    }
1750:
1751:                    if (match_group != null) {
1752:                        int noOfSources = (itemXml
1753:                                .selectNodes(matchGroupsXpath)).size();
1754:                        for (int i = 1; i <= noOfSources; i++) {
1755:                            String xpath = "item/presentation/flow/response_grp/render_choice/response_label["
1756:                                    + i + "]/@match_group";
1757:
1758:                            updateItemXml(itemXml, xpath, match_group);
1759:                        }
1760:                    }
1761:                }
1762:            }
1763:
1764:        }
w__ww__._j___av__a_2s_.c__om__ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.