001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/sam/trunk/component/src/java/org/sakaiproject/tool/assessment/qti/asi/Item.java $
003: * $Id: Item.java 9274 2006-05-10 22:50:48Z daisyf@stanford.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the"License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.tool.assessment.qti.asi;
021:
022: import java.util.ArrayList;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Set;
026:
027: import org.apache.commons.logging.Log;
028: import org.apache.commons.logging.LogFactory;
029: import org.w3c.dom.Document;
030: import org.w3c.dom.Element;
031:
032: import org.sakaiproject.tool.assessment.data.dao.assessment.AttachmentData;
033: import org.sakaiproject.tool.assessment.data.ifc.assessment.ItemDataIfc;
034: import org.sakaiproject.tool.assessment.data.ifc.assessment.ItemMetaDataIfc;
035: import org.sakaiproject.tool.assessment.data.ifc.shared.TypeIfc;
036: import org.sakaiproject.tool.assessment.qti.constants.AuthoringConstantStrings;
037: import org.sakaiproject.tool.assessment.qti.constants.QTIConstantStrings;
038: import org.sakaiproject.tool.assessment.qti.constants.QTIVersion;
039: import org.sakaiproject.tool.assessment.qti.helper.QTIHelperFactory;
040: import org.sakaiproject.tool.assessment.qti.helper.item.ItemHelperIfc;
041:
042: /**
043: * <p>Copyright: Copyright (c) 2004</p>
044: * <p>Organization: Sakai Project</p>
045: * @author rshastri
046: * @author Ed Smiley esmiley@stanford.edu
047: * @version $Id: Item.java 9274 2006-05-10 22:50:48Z daisyf@stanford.edu $
048: */
049: public class Item extends ASIBaseClass {
050: private static Log log = LogFactory.getLog(Item.class);
051: private int qtiVersion;
052: private ItemHelperIfc helper;
053:
054: /**
055: * Explicitly setting serialVersionUID insures future versions can be
056: * successfully restored. It is essential this variable name not be changed
057: * to SERIALVERSIONUID, as the default serialization methods expects this
058: * exact name.
059: */
060: private static final long serialVersionUID = 1;
061: private String basePath;
062: private String identity;
063:
064: /**
065: * Creates a new Item object.
066: */
067: public Item(int qtiVersion) {
068: super ();
069: initVersion(qtiVersion);
070: }
071:
072: /**
073: * Creates a new Item object.
074: *
075: * @param document an item XML document
076: */
077: public Item(Document document, int qtiVersion) {
078: super (document);
079: initVersion(qtiVersion);
080: }
081:
082: private void initVersion(int qtiVersion) {
083: if (!QTIVersion.isValid(qtiVersion)) {
084: throw new IllegalArgumentException(
085: "Invalid Item QTI version.");
086: }
087: this .qtiVersion = qtiVersion;
088: switch (qtiVersion) {
089: case QTIVersion.VERSION_1_2:
090: basePath = QTIConstantStrings.ITEM; // for v 1.2
091: identity = QTIConstantStrings.IDENT;
092: case QTIVersion.VERSION_2_0:
093: basePath = QTIConstantStrings.ASSESSMENTITEM;// for v 2.0
094: identity = QTIConstantStrings.AITEM_IDENT;
095: default:
096: basePath = QTIConstantStrings.ITEM; // DEFAULT
097: identity = QTIConstantStrings.IDENT;
098: }
099:
100: QTIHelperFactory factory = new QTIHelperFactory();
101: helper = factory.getItemHelperInstance(qtiVersion);
102: log.debug("Item XML class.initVersion(int qtiVersion)");
103: log.debug("qtiVersion=" + qtiVersion);
104: log.debug("basePath=" + basePath);
105: log.debug("identity=" + identity);
106: }
107:
108: /**
109: * set identity attribute (ident/identioty)
110: * @param ident the value
111: */
112:
113: public void setIdent(String ident) {
114: String xpath = basePath;
115: List list = this .selectNodes(xpath);
116: if (list.size() > 0) {
117: Element element = (Element) list.get(0);
118: element.setAttribute(identity, ident);
119: }
120: }
121:
122: /**
123: * set title attribute
124: * @param ident the value
125: */
126: public void setTitle(String title) {
127: String xpath = basePath;
128: List list = this .selectNodes(xpath);
129: if (list.size() > 0) {
130: Element element = (Element) list.get(0);
131: element.setAttribute(QTIConstantStrings.TITLE,
132: escapeXml(title));
133: }
134: }
135:
136: /**
137: * Update XML from perisistence
138: * @param item
139: */
140: public void update(ItemDataIfc item) {
141: // metadata
142: setFieldentry("ITEM_OBJECTIVE", item
143: .getItemMetaDataByLabel(ItemMetaDataIfc.OBJECTIVE));
144: setFieldentry("ITEM_KEYWORD", item
145: .getItemMetaDataByLabel(ItemMetaDataIfc.KEYWORD));
146: setFieldentry("ITEM_RUBRIC", item
147: .getItemMetaDataByLabel(ItemMetaDataIfc.RUBRIC));
148: setFieldentry("ATTACHMENT", getAttachment(item));
149:
150: // set TIMEALLOWED and NUM_OF_ATTEMPTS for audio recording questions:
151: if (item.getDuration() != null) {
152: setFieldentry("TIMEALLOWED", item.getDuration().toString());
153: }
154: if (item.getTriesAllowed() != null) {
155: setFieldentry("NUM_OF_ATTEMPTS", item.getTriesAllowed()
156: .toString());
157: }
158: // rshastri: SAK-1824
159: if (item != null
160: && (item.getTypeId().equals(TypeIfc.TRUE_FALSE)
161: || item.getTypeId().equals(
162: TypeIfc.MULTIPLE_CHOICE) || item
163: .getTypeId().equals(TypeIfc.MULTIPLE_CORRECT))
164: && item.getHasRationale() != null) {
165: setFieldentry("hasRationale", item.getHasRationale()
166: .toString());
167: }
168: // rshastri: SAK-1824
169: // item data
170: // ItemHelper helper = new ItemHelper();
171: if (!this .isSurvey()) //surveys are unscored
172: {
173: helper.addMaxScore(item.getScore(), this );
174: helper.addMinScore(item.getScore(), this );
175: }
176:
177: if (item != null
178: && (item.getTypeId().equals(TypeIfc.FILL_IN_BLANK))) {
179: setFieldentry(
180: "MUTUALLY_EXCLUSIVE",
181: item
182: .getItemMetaDataByLabel(ItemMetaDataIfc.MUTUALLY_EXCLUSIVE_FOR_FIB));
183: setFieldentry(
184: "CASE_SENSITIVE",
185: item
186: .getItemMetaDataByLabel(ItemMetaDataIfc.CASE_SENSITIVE_FOR_FIB));
187: }
188:
189: String instruction = item.getInstruction();
190: if (this .isMatching() || this .isFIB() || this .isFIN()) {
191: if (instruction != null) {
192: helper.setItemText(instruction, this );
193: }
194: }
195: ArrayList itemTexts = item.getItemTextArraySorted();
196:
197: setItemTexts(itemTexts);
198: if (this .isTrueFalse()) // we know what the answers are (T/F)
199: {
200: Boolean isTrue = item.getIsTrue();
201: if (isTrue == null)
202: isTrue = Boolean.FALSE;
203: setAnswerTrueFalse(isTrue.booleanValue());
204: } else if (!this .isSurvey()) //answers for surveys are a stereotyped scale
205: {
206: setAnswers(itemTexts);
207: }
208: setFeedback(itemTexts);
209: }
210:
211: /**
212: * Set the answer texts for item.
213: * @param itemTextList the text(s) for item
214: */
215: public void setAnswerTrueFalse(boolean isTrue) {
216: log.debug("isTrue=" + isTrue);
217: if (isTrue) {
218: helper.addCorrectAnswer("A", this );
219: helper.addIncorrectAnswer("B", this );
220: } else {
221: helper.addCorrectAnswer("B", this );
222: helper.addIncorrectAnswer("A", this );
223:
224: }
225: }
226:
227: /**
228: * method for meta data
229: *
230: * @param fieldlabel to get
231: *
232: * @return the value
233: */
234: public String getFieldentry(String fieldlabel) {
235: if (log.isDebugEnabled()) {
236: log.debug("getFieldentry(String " + fieldlabel + ")");
237: }
238: String xpath = helper.getMetaLabelXPath(fieldlabel);
239: return super .getFieldentry(xpath);
240: }
241:
242: /**
243: * method for meta data
244: *
245: * @param fieldlabel to get
246: *
247: * @param setValue the value
248: */
249: public void setFieldentry(String fieldlabel, String setValue) {
250: if (log.isDebugEnabled()) {
251: log.debug("setFieldentry(String " + fieldlabel
252: + ", String " + setValue + ")");
253: }
254:
255: String xpath = helper.getMetaLabelXPath(fieldlabel);
256: super .setFieldentry(xpath, setValue);
257: }
258:
259: /**
260: * Create a metadata field entry
261: *
262: * @param fieldlabel the field label
263: */
264: public void createFieldentry(String fieldlabel) {
265: if (log.isDebugEnabled()) {
266: log.debug("createFieldentry(String " + fieldlabel + ")");
267: }
268:
269: String xpath = helper.getMetaXPath();
270: super .createFieldentry(xpath, fieldlabel);
271: }
272:
273: public String getItemType() {
274: String type = this .getFieldentry("qmd_itemtype");
275:
276: return type;
277: }
278:
279: /**
280: * Set the item texts.
281: * Valid for single and multiple texts.
282: * @param itemText text to be updated
283: */
284: public void setItemTexts(ArrayList itemTextList) {
285: helper.setItemTexts(itemTextList, this );
286: }
287:
288: public boolean isEssay() {
289: boolean essay = AuthoringConstantStrings.ESSAY.equals(this
290: .getItemType())
291: || AuthoringConstantStrings.ESSAY_ALT.equals(this
292: .getItemType());
293: return essay ? true : false;
294: }
295:
296: public boolean isSurvey() {
297: return AuthoringConstantStrings.SURVEY.equals(this
298: .getItemType()) ? true : false;
299: }
300:
301: public boolean isAudio() {
302: return AuthoringConstantStrings.AUDIO
303: .equals(this .getItemType()) ? true : false;
304: }
305:
306: public boolean isFile() {
307: return AuthoringConstantStrings.FILE.equals(this .getItemType()) ? true
308: : false;
309: }
310:
311: public boolean isMatching() {
312: return AuthoringConstantStrings.MATCHING.equals(this
313: .getItemType()) ? true : false;
314: }
315:
316: public boolean isFIB() {
317: return AuthoringConstantStrings.FIB.equals(this .getItemType()) ? true
318: : false;
319: }
320:
321: public boolean isFIN() {
322: return AuthoringConstantStrings.FIN.equals(this .getItemType()) ? true
323: : false;
324: }
325:
326: public boolean isMCMC() {
327: return AuthoringConstantStrings.MCMC.equals(this .getItemType()) ? true
328: : false;
329: }
330:
331: public boolean isMCSC() {
332: return AuthoringConstantStrings.MCSC.equals(this .getItemType()) ? true
333: : false;
334: }
335:
336: private boolean isTrueFalse() {
337: return AuthoringConstantStrings.TF.equals(this .getItemType()) ? true
338: : false;
339: }
340:
341: /**
342: * Set the answer texts for item.
343: * @param itemTextList the text(s) for item
344: */
345: public void setAnswers(ArrayList itemTextList) {
346: helper.setAnswers(itemTextList, this );
347: }
348:
349: /**
350: * Set the feedback texts for item.
351: * @param itemTextList the text(s) for item
352: */
353: public void setFeedback(ArrayList itemTextList) {
354: helper.setFeedback(itemTextList, this );
355: }
356:
357: /**
358: * Get the text for the item
359: * @return the text
360: */
361: public String getItemText() {
362: return helper.getText(this );
363: }
364:
365: public String getBasePath() {
366: return basePath;
367: }
368:
369: public void setBasePath(String basePath) {
370: this .basePath = basePath;
371: }
372:
373: private String getAttachment(ItemDataIfc item) {
374: Set attachmentSet = (Set) item.getItemAttachmentSet();
375: if (attachmentSet != null && attachmentSet.size() != 0) {
376: Iterator iter = attachmentSet.iterator();
377: AttachmentData attachmentData = null;
378: StringBuffer attachment = new StringBuffer();
379: while (iter.hasNext()) {
380: attachmentData = (AttachmentData) iter.next();
381: attachment.append(attachmentData.getResourceId()
382: .replaceAll(" ", ""));
383: attachment.append("|");
384: attachment.append(attachmentData.getFilename());
385: attachment.append("|");
386: attachment.append(attachmentData.getMimeType());
387: attachment.append("\n");
388: }
389: return attachment.toString();
390: } else {
391: return null;
392: }
393: }
394: }
|