org.sakaiproject.tool.assessment.qti.asi.ASIBaseClass.java Source code

Java tutorial

Introduction

Here is the source code for org.sakaiproject.tool.assessment.qti.asi.ASIBaseClass.java

Source

/**********************************************************************************
 * $URL$
 * $Id$
 ***********************************************************************************
 *
 * 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.asi;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Comment;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;

import org.sakaiproject.tool.assessment.qti.constants.QTIConstantStrings;
import org.sakaiproject.tool.assessment.qti.util.XmlStringBuffer;

/**
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Organization: Sakai Project</p>
 * @author rshastri
 * @author Ed Smiley esmiley@stanford.edu
 * @version $Id$
 */
public abstract class ASIBaseClass extends XmlStringBuffer {
    private static Log log = LogFactory.getLog(ASIBaseClass.class);
    private static final long serialVersionUID = 5670937321581940933L;
    private String idString;

    /**
     * Creates a new ASIBaseClass object.
     */
    protected ASIBaseClass() {
        super();
    }

    /**
     * Creates a new ASIBaseClass object.
     *
     * @param xml XML string
     */
    protected ASIBaseClass(String xml) {
        super(xml);
    }

    /**
     * Creates a new ASIBaseClass object.
     *
     * @param document Document
     */
    protected ASIBaseClass(Document document) {
        super(document);
    }

    /**
     * extract string for tag
     * @param tagName name of tag
     * @return a String
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     * @throws DOMException
     */
    protected String extractString(String tagName)
            throws ParserConfigurationException, SAXException, IOException, DOMException {
        if (log.isDebugEnabled()) {
            log.debug("extractString(String " + tagName + ")");
        }

        String title = null;
        String description = null;
        NodeList nodes = this.getDocument().getElementsByTagName(tagName);
        Element element = (Element) nodes.item(0);
        title = element.getAttribute(QTIConstantStrings.TITLE);
        description = title;

        int size = nodes.getLength();
        for (int i = 0; i < size; i++) {
            Element node = (Element) nodes.item(i);
            node.setAttribute(QTIConstantStrings.IDENT, this.getIdString());
        }

        return this.stringValue();
    }

    /**
     * Simple wrapper over commons lang util method, but we may add additional
     * logic in the future for special QTI export purposes.
     * @param s
     * @return escaped string e.g.
     * < \u04D0rnesen & Jones > becomes &lt;&#1232;rnesen &amp; Jones &gt;
     */
    public static String escapeXml(String s) {
        if (s == null)
            return "";
        return StringEscapeUtils.escapeXml(s);
    }

    /**
     * DOCUMENTATION PENDING
     *
     * @param xpath DOCUMENTATION PENDING
     *
     * @return DOCUMENTATION PENDING
     */
    protected String getFieldentry(String xpath) {
        if (log.isDebugEnabled()) {
            log.debug("getFieldentry(String " + xpath + ")");
        }

        String val = null;
        int no = 0;

        List metadataList;
        try {
            metadataList = this.selectNodes(xpath);
            no = metadataList.size();

            if (metadataList.size() > 0) {
                Document document = this.getDocument();
                Element fieldentry = (Element) metadataList.get(0);
                CharacterData fieldentryText = (CharacterData) fieldentry.getFirstChild();

                Integer getTime = null;
                if ((fieldentryText != null) && (fieldentryText.getNodeValue() != null)
                        && (fieldentryText.getNodeValue().trim().length() > 0)) {
                    val = fieldentryText.getNodeValue();
                }
            }
        } catch (DOMException ex) {
            log.error(ex.getMessage(), ex);
        }

        catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }

        return val;
    }

    /**
     * Set field entry.
     *
     * @param xpath
     * @param setValue
     */
    protected void setFieldentry(String xpath, String value) {
        setFieldentry(xpath, value, false);
    }

    /**
     * Set field entry.
     *
     * @param xpath
     * @param setValue
     * @param noEscapeXML
     */
    protected void setFieldentry(String xpath, String value, boolean noEscapeXML) {
        String setValue = null;

        if (noEscapeXML) {
            setValue = value;
        } else {
            setValue = escapeXml(value);
        }

        if (log.isDebugEnabled()) {
            log.debug("setFieldentry(String " + xpath + ", String " + setValue + ")");
        }

        List metadataList;
        try {
            metadataList = this.selectNodes(xpath);
            int no = metadataList.size();
            String val = null;

            if (metadataList.size() > 0) {
                Document document = this.getDocument();
                Element fieldentry = (Element) metadataList.get(0);
                CharacterData fieldentryText = (CharacterData) fieldentry.getFirstChild();

                Integer getTime = null;
                if ((fieldentryText != null) && (fieldentryText.getNodeValue() != null)
                        && (fieldentryText.getNodeValue().trim().length() > 0)) {
                    val = fieldentryText.getNodeValue();
                }

                if (setValue != null) {
                    if (fieldentryText == null) {
                        Text newElementText = fieldentry.getOwnerDocument().createTextNode(setValue);

                        fieldentry.appendChild(newElementText);
                        fieldentryText = (CharacterData) fieldentry.getFirstChild();
                    } else {
                        fieldentryText.setNodeValue(setValue);
                    }
                }
            }
        } catch (ParserConfigurationException e) {
            log.error(e.getMessage(), e);
        } catch (SAXException e) {
            log.error(e.getMessage(), e);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     *
     *
     * @param xpath
     * @param fieldlabel
     */
    protected void createFieldentry(String xpath, String fieldlabel) {
        if (log.isDebugEnabled()) {
            log.debug("createFieldentry(String " + xpath + ", String " + fieldlabel + ")");
        }

        try {
            List qtimetadataNodes = this.selectNodes(xpath);
            if (qtimetadataNodes.size() > 0) {
                Node qtimetadataNode = (Node) qtimetadataNodes.get(0);
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                DocumentBuilder db = dbf.newDocumentBuilder();
                Document newDocument = db.newDocument();

                Element qtimetadataField = newDocument.createElement(QTIConstantStrings.QTIMETADATAFIELD);
                Element fieldlabelElement = newDocument.createElement(QTIConstantStrings.FIELDLABEL);
                Element fieldentryElement = newDocument.createElement(QTIConstantStrings.FIELDENTRY);

                Text fieldlabelText = newDocument.createTextNode(QTIConstantStrings.FIELDLABEL);
                fieldlabelText.setNodeValue(fieldlabel);
                fieldlabelElement.appendChild(fieldlabelText);

                Text fieldentryText = newDocument.createTextNode(QTIConstantStrings.FIELDENTRY);
                fieldentryElement.appendChild(fieldentryText);

                Node importedFLE = qtimetadataField.getOwnerDocument().importNode(fieldlabelElement, true);
                Node importedFEE = qtimetadataField.getOwnerDocument().importNode(fieldentryElement, true);
                qtimetadataField.appendChild(importedFLE);
                qtimetadataField.appendChild(importedFEE);
                Node importedField = qtimetadataNode.getOwnerDocument().importNode(qtimetadataField, true);
                qtimetadataNode.appendChild(importedField);
            }
        } catch (ParserConfigurationException pce) {
            log.error("Exception thrown from createFieldentry()" + pce.getMessage(), pce);
            pce.printStackTrace();
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }

    /**
     * Methods shared by Assessment and Section only
     *
     * @param basePath
     *
     * @return
     */
    /**
     *
     *
     * @param basePath
     *
     * @return
     */
    protected List getAllSections(String basePath) {
        if (log.isDebugEnabled()) {
            log.debug("getAllSections(String " + basePath + ")");
        }

        String xpath = basePath + "/" + QTIConstantStrings.SECTION;
        List nodes = this.selectNodes(xpath);
        List clonedList = new ArrayList();
        int size = nodes.size();
        for (int i = 0; i < size; i++) {
            Node clonedNode = ((Node) nodes.get(i)).cloneNode(true);
            clonedList.add(clonedNode);
        }

        return clonedList;
    }

    /**
     *
     *
     * @param basePath
     */
    protected void removeSections(String basePath) {
        if (log.isDebugEnabled()) {
            log.debug("removeSections(String " + basePath + ")");
        }

        String xpath = basePath + "/" + QTIConstantStrings.SECTION;
        this.removeElement(xpath);
    }

    /**
     *
     *
     * @param basePath
     * not used for now, commenting it out
     *
     * @return
     */

    /*
    protected ArrayList selectSections(String basePath)
    {
      if(log.isDebugEnabled())
      {
        log.debug("selectSections(String " + basePath + ")");
        log.debug("After Remove Section: " + this.stringValue());
      }
        
      ArrayList sections = new ArrayList();
      try
      {
        String xpath =
    basePath + "/" + QTIConstantStrings.SELECTION_ORDERING + "/";
        String selectionXPath = xpath + QTIConstantStrings.SELECTION;
        
        List selectNodes = this.selectNodes(selectionXPath);
        
        int selectNodeSize = selectNodes.size();
        for(int i = 0; i < selectNodeSize; i++)
        {
    Element selectElement = (Element) selectNodes.get(i);
    sections.addAll(processSelectElement(basePath, selectElement));
        }
        
        if(selectNodeSize == 0)
        {
    // no select element, then select all items
    sections.addAll(this.getAllSections(basePath));
        }
      }
      catch(Exception ex)
      {
        log.error(ex.getMessage(), ex);
      }
        
      removeSections(basePath);
        
      return sections;
    }
        
    */

    /**
     *
     *
     * @param basePath
     * @param selectElement
     *
     * not used, commenting it out for now
     * @return
     */
    /*
    protected List processSelectElement(String basePath, Element selectElement)
    {
      if(log.isDebugEnabled())
      {
        log.debug(
    "processSelectElement(String " + basePath + ", Element" +
    selectElement + ")");
      }
        
      int selectNumber = -1;
      String sourceBankId = null;
        
      // there is no select number and sourceBank_ref
      // then select all items within this section.
      if((selectNumber == -1) && (sourceBankId == null))
      {
        return getAllSections(basePath);
      }
        
      // there is select number but no sourceBank_ref
      // then select number of items within this section.
      if((selectNumber > 0) && (sourceBankId == null))
      {
        return getNumOfSections(basePath, selectNumber);
      }
        
      // We are not supporting object bank for sections at this time.
      return null;
    }
    */

    /**
     *
     *
     * @param basePath
     * @param selectNumber
     *
     * @return
     */
    protected List getNumOfSections(String basePath, int selectNumber) {
        if (log.isDebugEnabled()) {
            log.debug("getNumOfSections(String " + basePath + ", int " + selectNumber + ")");
        }

        List list = new ArrayList();
        List clonedList = new ArrayList();
        List allSections = getAllSections(basePath);
        long seed = System.currentTimeMillis();
        int allItemSize = allSections.size();
        Random random = new Random(seed);
        while (list.size() < selectNumber) {
            int randomNum = random.nextInt(allItemSize);
            Object item = allSections.get(randomNum);
            if (!list.contains(item)) {
                list.add(item);
            }
        }

        for (int i = 0; i < selectNumber; i++) {
            Node clonedNode = ((Node) list.get(i)).cloneNode(true);
            clonedList.add(clonedNode);
        }

        return clonedList;
    }

    //  /**
    //   *
    //   *
    //   * @param basePath
    //   * @param sections
    //   */
    //  protected void orderSections(String basePath, ArrayList sections, int qtiVersion)
    //  {
    //    if(log.isDebugEnabled())
    //    {
    //      log.debug(
    //        "orderSections(String " + basePath + ", ArrayList " + sections + ")");
    //    }
    //
    //    try
    //    {
    //      String xpath =
    //        basePath + "/" + QTIConstantStrings.SELECTION_ORDERING + "/";
    //      String orderingXPath = xpath + QTIConstantStrings.ORDER;
    //      List orderNodes = this.selectNodes(orderingXPath);
    //      if((orderNodes != null) && (orderNodes.size() > 0))
    //      {
    //        Element order = (Element) orderNodes.get(0);
    //        String orderType = order.getAttribute(QTIConstantStrings.ORDER_TYPE);
    //        if("Random".equalsIgnoreCase(orderType))
    //        {
    //          //Randomly order items.
    //          long seed = System.currentTimeMillis();
    //          Random rand = new Random(seed);
    //          int size = sections.size();
    //          for(int i = 0; i < size; i++)
    //          {
    //            int randomNum = rand.nextInt(size);
    //            Object temp = sections.get(i);
    //            sections.set(i, sections.get(randomNum));
    //            sections.set(randomNum, temp);
    //          }
    //        }
    //      }
    //    }
    //    catch(Exception ex)
    //    {
    //      log.error(ex.getMessage(), ex);
    //    }
    //
    //    addSections(basePath, sections, qtiVersion);
    //  }

    //  /**
    //   *
    //   *
    //   * @param basePath
    //   * @param sections
    //   */
    //  protected void addSections(String basePath, ArrayList sections, int qtiVersion)
    //  {
    //    if(log.isDebugEnabled())
    //    {
    //      log.debug(
    //        "addSections(String " + basePath + ", ArrayList " + sections + ")");
    //    }
    //
    //    try
    //    {
    //      String xpath = basePath;
    //      for(int i = 0; i < sections.size(); i++)
    //      {
    //        Element sectionElement = (Element) sections.get(i);
    //        Document sectionDoc = XmlUtil.createDocument();
    //        Node newNode = sectionDoc.importNode(sectionElement, true);
    //        sectionDoc.appendChild(newNode);
    //        Section section = new Section(sectionDoc, qtiVersion);
    //
    //        //Shuffle Section if specified within Item.
    //        section.selectAndOrder();
    //        sectionElement = (Element) section.getDocument().getFirstChild();
    //
    //        this.addElement(xpath, sectionElement);
    //      }
    //    }
    //    catch(ParserConfigurationException e)
    //    {
    //      log.error(e.getMessage(), e);
    //    }
    //    catch(SAXException e)
    //    {
    //      log.error(e.getMessage(), e);
    //    }
    //    catch(IOException e)
    //    {
    //      log.error(e.getMessage(), e);
    //    }
    //  }

    protected void wrappingMattext() {
        log.debug("wrappingMattext()");

        try {
            NodeList list = this.getDocument().getElementsByTagName(QTIConstantStrings.MATTEXT);
            int size = list.getLength();
            for (int i = 0; i < size; i++) {
                Node node = list.item(i);
                Node childNode = node.getFirstChild();
                if ((childNode != null) && childNode instanceof CharacterData) {
                    CharacterData cdi = (CharacterData) childNode;
                    String data = cdi.getData();

                    //modify this string;
                    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                    DocumentBuilder db = dbf.newDocumentBuilder();
                    Document doc = db.newDocument();
                    Comment comment = doc.createComment(data);
                    node.appendChild(node.getOwnerDocument().importNode(comment, true));
                    cdi.setData("");
                }
            }
        } catch (ParserConfigurationException e) {
            log.error(e.getMessage(), e);
        } catch (SAXException e) {
            log.error(e.getMessage(), e);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

    public String getIdString() {
        return idString;
    }

    public void setIdString(String idString) {
        this.idString = idString;
    }
}