/********************************************************************************** * $URL: https://source.sakaiproject.org/svn/sam/trunk/samigo-qti/src/java/org/sakaiproject/tool/assessment/qti/helper/item/ItemHelperBase.java $ * $Id: ItemHelperBase.java 106463 2012-04-02 12:20:09Z david.horwitz@uct.ac.za $ *********************************************************************************** * * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009 The Sakai Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.opensource.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **********************************************************************************/ package org.sakaiproject.tool.assessment.qti.helper.item; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.CharacterData; import org.w3c.dom.DOMException; import org.w3c.dom.Node; import org.xml.sax.SAXException; import org.sakaiproject.tool.assessment.data.ifc.assessment.ItemMetaDataIfc; import org.sakaiproject.tool.assessment.data.ifc.shared.TypeIfc; import org.sakaiproject.tool.assessment.qti.asi.Item; import org.sakaiproject.tool.assessment.qti.helper.AuthoringHelper; import org.sakaiproject.tool.assessment.qti.helper.AuthoringXml; public abstract class ItemHelperBase implements ItemHelperIfc { private static Log log = LogFactory.getLog(ItemHelperBase.class); protected static final long ITEM_AUDIO = TypeIfc.AUDIO_RECORDING.longValue(); protected static final long ITEM_ESSAY = TypeIfc.ESSAY_QUESTION.longValue(); protected static final long ITEM_FILE = TypeIfc.FILE_UPLOAD.longValue(); protected static final long ITEM_FIB = TypeIfc.FILL_IN_BLANK.longValue(); protected static final long ITEM_FIN = TypeIfc.FILL_IN_NUMERIC.longValue(); protected static final long ITEM_MCSC = TypeIfc.MULTIPLE_CHOICE.longValue(); protected static final long ITEM_SURVEY = TypeIfc.MULTIPLE_CHOICE_SURVEY. longValue(); protected static final long ITEM_MCMC = TypeIfc.MULTIPLE_CORRECT.longValue(); protected static final long ITEM_MCMC_SS = TypeIfc.MULTIPLE_CORRECT_SINGLE_SELECTION.longValue(); protected static final long ITEM_TF = TypeIfc.TRUE_FALSE.longValue(); protected static final long ITEM_MATCHING = TypeIfc.MATCHING.longValue(); protected static final long ITEM_MXSURVEY = TypeIfc.MATRIX_CHOICES_SURVEY.longValue(); protected static final long ITEM_CALCQ = TypeIfc.CALCULATED_QUESTION.longValue(); // CALCULATED_QUESTION /** * We will have a versioned AuthoringXml in subclasses. * @return */ protected abstract AuthoringXml getAuthoringXml(); /** * Get the QTI version for each subclass. * @return a QTIVersion.VERSION_... constant */ protected abstract int getQtiVersion(); /** * Read an item XML document from a stream into an Item XML object * * @param inputStream XML document stream * * @return an Item XML object */ public Item readXMLDocument( InputStream inputStream) { if (log.isDebugEnabled()) { log.debug("readDocument(InputStream " + inputStream); } Item itemXml = null; try { AuthoringHelper authoringHelper = new AuthoringHelper(getQtiVersion()); itemXml = new Item( authoringHelper.readXMLDocument(inputStream).getDocument(), getQtiVersion()); } catch (ParserConfigurationException e) { log.error(e.getMessage(), e); } catch (SAXException e) { log.error(e.getMessage(), e); } catch (IOException e) { log.error(e.getMessage(), e); } return itemXml; } /** * Get Item Xml for a given item type as a TypeIfc. * @param type item type as a TypeIfc * @return */ public Item readTypeXMLItem(Long type) { AuthoringXml ax = getAuthoringXml(); InputStream is; String template = getTemplateFromType(type); is = ax.getTemplateInputStream(template); Item itemXml = readXMLDocument(is); return itemXml; } /** * Get Item Xml for a given survey item scale name. * @param scaleName * @return */ public Item readTypeSurveyItem(String scaleName) { AuthoringXml ax = getAuthoringXml(); InputStream is = null; if (scaleName==null) { log.warn("missing survey scale name, set to: STRONGLY_AGREE"); scaleName = "STRONGLY_AGREE"; } String template = getTemplateFromScale(scaleName); is = ax.getTemplateInputStream(template); Item itemXml = readXMLDocument(is); return itemXml; } /** * Get XML template for a given item type * @param type * @return */ private String getTemplateFromScale(String scalename) { String template = AuthoringXml.SURVEY_10; //default // 2/19/2006: for backward compatibility,need to keep YESNO, SCALEFIVE, and SCALETEN if ((ItemMetaDataIfc.SURVEY_YES.equals(scalename)) || (ItemMetaDataIfc.SURVEY_YESNO.equals(scalename)) ) { template = AuthoringXml.SURVEY_YES; } else if (ItemMetaDataIfc.SURVEY_AGREE.equals(scalename)) { template = AuthoringXml.SURVEY_AGREE; } else if (ItemMetaDataIfc.SURVEY_UNDECIDED.equals(scalename)) { template = AuthoringXml.SURVEY_UNDECIDED; } else if (ItemMetaDataIfc.SURVEY_AVERAGE.equals(scalename)) { template = AuthoringXml.SURVEY_AVERAGE; } else if (ItemMetaDataIfc.SURVEY_STRONGLY_AGREE.equals(scalename)) { template = AuthoringXml.SURVEY_STRONGLY; } else if (ItemMetaDataIfc.SURVEY_EXCELLENT.equals(scalename)) { template = AuthoringXml.SURVEY_EXCELLENT; } else if ((ItemMetaDataIfc.SURVEY_5.equals(scalename)) || (ItemMetaDataIfc.SURVEY_SCALEFIVE.equals(scalename)) ) { template = AuthoringXml.SURVEY_5; } else if ((ItemMetaDataIfc.SURVEY_10.equals(scalename)) || (ItemMetaDataIfc.SURVEY_SCALETEN.equals(scalename)) ) { template = AuthoringXml.SURVEY_10; } log.debug("scale: " + scalename); log.debug("template: " + template); return template; } /** * Get XML template for a given item type * @param type * @return */ private String getTemplateFromType(Long type) { String template = ""; long typeId = ITEM_TF; if (type != null) { typeId = type.longValue(); } if (ITEM_AUDIO == typeId) { template = AuthoringXml.ITEM_AUDIO; } else if (ITEM_ESSAY == typeId) { template = AuthoringXml.ITEM_ESSAY; } else if (ITEM_FILE == typeId) { template = AuthoringXml.ITEM_FILE; } else if (ITEM_FIB == typeId) { template = AuthoringXml.ITEM_FIB; } else if (ITEM_FIN == typeId) { template = AuthoringXml.ITEM_FIN; } else if (ITEM_MCSC == typeId) { template = AuthoringXml.ITEM_MCSC; } else if (ITEM_SURVEY == typeId) { template = AuthoringXml.ITEM_SURVEY; } else if (ITEM_MCMC == typeId) { template = AuthoringXml.ITEM_MCMC; } else if (ITEM_MCMC_SS == typeId) { template = AuthoringXml.ITEM_MCMC_SS; } else if (ITEM_TF == typeId) { template = AuthoringXml.ITEM_TF; } else if (ITEM_MATCHING == typeId) { template = AuthoringXml.ITEM_MATCHING; } else if (ITEM_MXSURVEY == typeId) { template = AuthoringXml.ITEM_MXSURVEY; } // CALCULATED_QUESTION else if (ITEM_CALCQ == typeId) { template = AuthoringXml.ITEM_CALCQ; } log.debug("typeId: " + typeId); log.debug("template: " + template); return template; } /** * Update path with value * * @param itemXml the item xml * @param xpath the xpath * @param value the value to set * * @return the item xml */ public Item updateItemXml( Item itemXml, String xpath, String value) { if (log.isDebugEnabled()) { log.debug( "updateItemXml(Item " + itemXml + ", String" + xpath + ", String" + value + ")"); } try { itemXml.update(xpath, value); } catch (DOMException e) { log.error(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); } return itemXml; } /** * Concatenate nodes for xpath * @param itemXml * @param xpath * @return */ protected String makeItemNodeText(Item itemXml, String xpath) { //String text = ""; List nodes = itemXml.selectNodes(xpath); Iterator iter = nodes.iterator(); StringBuilder textbuf = new StringBuilder(); while (iter.hasNext()) { Node node = (Node) iter.next(); Node child = node.getFirstChild(); if ( (child != null) && child instanceof CharacterData) { CharacterData cdi = (CharacterData) child; textbuf.append(" " + cdi.getData()); } } String text = textbuf.toString(); return text; } }