001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/sam/trunk/component/src/java/org/sakaiproject/tool/assessment/qti/helper/item/ItemHelperBase.java $
003: * $Id: ItemHelperBase.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.helper.item;
021:
022: import java.io.IOException;
023: import java.io.InputStream;
024: import java.util.Iterator;
025: import java.util.List;
026: import javax.xml.parsers.ParserConfigurationException;
027:
028: import org.apache.commons.logging.Log;
029: import org.apache.commons.logging.LogFactory;
030:
031: import org.w3c.dom.CharacterData;
032: import org.w3c.dom.DOMException;
033: import org.w3c.dom.Node;
034: import org.xml.sax.SAXException;
035:
036: import org.sakaiproject.tool.assessment.data.ifc.assessment.ItemMetaDataIfc;
037: import org.sakaiproject.tool.assessment.data.ifc.shared.TypeIfc;
038: import org.sakaiproject.tool.assessment.qti.asi.Item;
039: import org.sakaiproject.tool.assessment.qti.helper.AuthoringHelper;
040: import org.sakaiproject.tool.assessment.qti.helper.AuthoringXml;
041:
042: public abstract class ItemHelperBase implements ItemHelperIfc {
043: private static Log log = LogFactory.getLog(ItemHelperBase.class);
044:
045: protected static final long ITEM_AUDIO = TypeIfc.AUDIO_RECORDING
046: .longValue();
047: protected static final long ITEM_ESSAY = TypeIfc.ESSAY_QUESTION
048: .longValue();
049: protected static final long ITEM_FILE = TypeIfc.FILE_UPLOAD
050: .longValue();
051: protected static final long ITEM_FIB = TypeIfc.FILL_IN_BLANK
052: .longValue();
053: protected static final long ITEM_FIN = TypeIfc.FILL_IN_NUMERIC
054: .longValue();
055: protected static final long ITEM_MCSC = TypeIfc.MULTIPLE_CHOICE
056: .longValue();
057: protected static final long ITEM_SURVEY = TypeIfc.MULTIPLE_CHOICE_SURVEY
058: .longValue();
059: protected static final long ITEM_MCMC = TypeIfc.MULTIPLE_CORRECT
060: .longValue();
061: protected static final long ITEM_TF = TypeIfc.TRUE_FALSE
062: .longValue();
063: protected static final long ITEM_MATCHING = TypeIfc.MATCHING
064: .longValue();
065:
066: /**
067: * We will have a versioned AuthoringXml in subclasses.
068: * @return
069: */
070: protected abstract AuthoringXml getAuthoringXml();
071:
072: /**
073: * Get the QTI version for each subclass.
074: * @return a QTIVersion.VERSION_... constant
075: */
076: protected abstract int getQtiVersion();
077:
078: /**
079: * Read an item XML document from a stream into an Item XML object
080: *
081: * @param inputStream XML document stream
082: *
083: * @return an Item XML object
084: */
085: public Item readXMLDocument(InputStream inputStream) {
086: if (log.isDebugEnabled()) {
087: log.debug("readDocument(InputStream " + inputStream);
088: }
089:
090: Item itemXml = null;
091:
092: try {
093: AuthoringHelper authoringHelper = new AuthoringHelper(
094: getQtiVersion());
095: itemXml = new Item(authoringHelper.readXMLDocument(
096: inputStream).getDocument(), getQtiVersion());
097: } catch (ParserConfigurationException e) {
098: log.error(e.getMessage(), e);
099: } catch (SAXException e) {
100: log.error(e.getMessage(), e);
101: } catch (IOException e) {
102: log.error(e.getMessage(), e);
103: }
104:
105: return itemXml;
106: }
107:
108: /**
109: * Get Item Xml for a given item type as a TypeIfc.
110: * @param type item type as a TypeIfc
111: * @return
112: */
113:
114: public Item readTypeXMLItem(Long type) {
115: AuthoringXml ax = getAuthoringXml();
116: InputStream is;
117: String template = getTemplateFromType(type);
118: is = ax.getTemplateInputStream(template);
119: Item itemXml = readXMLDocument(is);
120: return itemXml;
121: }
122:
123: /**
124: * Get Item Xml for a given survey item scale name.
125: * @param scaleName
126: * @return
127: */
128: public Item readTypeSurveyItem(String scaleName) {
129: AuthoringXml ax = getAuthoringXml();
130: InputStream is = null;
131: if (scaleName == null) {
132: log
133: .warn("missing survey scale name, set to: STRONGLY_AGREE");
134: scaleName = "STRONGLY_AGREE";
135: }
136: String template = getTemplateFromScale(scaleName);
137: is = ax.getTemplateInputStream(template);
138: Item itemXml = readXMLDocument(is);
139: return itemXml;
140:
141: }
142:
143: /**
144: * Get XML template for a given item type
145: * @param type
146: * @return
147: */
148: private String getTemplateFromScale(String scalename) {
149: AuthoringXml ax = getAuthoringXml();
150: String template = ax.SURVEY_10; //default
151:
152: // 2/19/2006: for backward compatibility,need to keep YESNO, SCALEFIVE, and SCALETEN
153: if ((ItemMetaDataIfc.SURVEY_YES.equals(scalename))
154: || (ItemMetaDataIfc.SURVEY_YESNO.equals(scalename))) {
155: template = ax.SURVEY_YES;
156: } else if (ItemMetaDataIfc.SURVEY_AGREE.equals(scalename)) {
157: template = ax.SURVEY_AGREE;
158: } else if (ItemMetaDataIfc.SURVEY_UNDECIDED.equals(scalename)) {
159: template = ax.SURVEY_UNDECIDED;
160: } else if (ItemMetaDataIfc.SURVEY_AVERAGE.equals(scalename)) {
161: template = ax.SURVEY_AVERAGE;
162: } else if (ItemMetaDataIfc.SURVEY_STRONGLY_AGREE
163: .equals(scalename)) {
164: template = ax.SURVEY_STRONGLY;
165: } else if (ItemMetaDataIfc.SURVEY_EXCELLENT.equals(scalename)) {
166: template = ax.SURVEY_EXCELLENT;
167: } else if ((ItemMetaDataIfc.SURVEY_5.equals(scalename))
168: || (ItemMetaDataIfc.SURVEY_SCALEFIVE.equals(scalename))) {
169: template = ax.SURVEY_5;
170: } else if ((ItemMetaDataIfc.SURVEY_10.equals(scalename))
171: || (ItemMetaDataIfc.SURVEY_SCALETEN.equals(scalename))) {
172: template = ax.SURVEY_10;
173: }
174:
175: log.debug("scale: " + scalename);
176: log.debug("template: " + template);
177:
178: return template;
179: }
180:
181: /**
182: * Get XML template for a given item type
183: * @param type
184: * @return
185: */
186: private String getTemplateFromType(Long type) {
187: String template = "";
188: AuthoringXml ax = getAuthoringXml();
189: long typeId = ITEM_TF;
190:
191: if (type != null) {
192: typeId = type.longValue();
193: }
194:
195: if (ITEM_AUDIO == typeId) {
196: template = ax.ITEM_AUDIO;
197: } else if (ITEM_ESSAY == typeId) {
198: template = ax.ITEM_ESSAY;
199: } else if (ITEM_FILE == typeId) {
200: template = ax.ITEM_FILE;
201: } else if (ITEM_FIB == typeId) {
202: template = ax.ITEM_FIB;
203: } else if (ITEM_FIN == typeId) {
204: template = ax.ITEM_FIN;
205: } else if (ITEM_MCSC == typeId) {
206: template = ax.ITEM_MCSC;
207: } else if (ITEM_SURVEY == typeId) {
208: template = ax.ITEM_SURVEY;
209: } else if (ITEM_MCMC == typeId) {
210: template = ax.ITEM_MCMC;
211: } else if (ITEM_TF == typeId) {
212: template = ax.ITEM_TF;
213: } else if (ITEM_MATCHING == typeId) {
214: template = ax.ITEM_MATCHING;
215: }
216:
217: log.debug("typeId: " + typeId);
218: log.debug("template: " + template);
219:
220: return template;
221: }
222:
223: /**
224: * Get item type string which is used for the title of a given item type
225: * @param type
226: * @return
227: */
228: public String getItemTypeString(TypeIfc type) {
229: long typeId = 0;
230: if (type != null) {
231: typeId = type.getTypeId().longValue();
232: }
233:
234: int itemType = type.getTypeId().intValue();
235: if (itemType < 1 || itemType > itemTypes.length) {
236: itemType = 0;
237: }
238: return itemTypes[itemType];
239: }
240:
241: /**
242: * Update path with value
243: *
244: * @param itemXml the item xml
245: * @param xpath the xpath
246: * @param value the value to set
247: *
248: * @return the item xml
249: */
250: public Item updateItemXml(Item itemXml, String xpath, String value) {
251: if (log.isDebugEnabled()) {
252: log.debug("updateItemXml(Item " + itemXml + ", String"
253: + xpath + ", String" + value + ")");
254: }
255:
256: try {
257: itemXml.update(xpath, value);
258: } catch (DOMException e) {
259: log.error(e.getMessage(), e);
260: } catch (Exception e) {
261: log.error(e.getMessage(), e);
262: }
263:
264: return itemXml;
265: }
266:
267: /**
268: * Concatenate nodes for xpath
269: * @param itemXml
270: * @param xpath
271: * @return
272: */
273: protected String makeItemNodeText(Item itemXml, String xpath) {
274: String text = "";
275: List nodes = itemXml.selectNodes(xpath);
276: Iterator iter = nodes.iterator();
277: while (iter.hasNext()) {
278: Node node = (Node) iter.next();
279: Node child = node.getFirstChild();
280: if ((child != null) && child instanceof CharacterData) {
281: CharacterData cdi = (CharacterData) child;
282: text = text + " " + cdi.getData();
283: }
284: }
285: return text;
286: }
287:
288: }
|