/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/sam/trunk/samigo-app/src/java/org/sakaiproject/tool/assessment/ui/bean/qti/XMLController.java $
* $Id: XMLController.java 106463 2012-04-02 12:20:09Z david.horwitz@uct.ac.za $
***********************************************************************************
*
* Copyright (c) 2004, 2005, 2006, 2008 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.ui.bean.qti;
import java.io.InputStream;
import java.io.Serializable;
import java.util.StringTokenizer;
//import javax.faces.context.FacesContext;
import org.w3c.dom.Document;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.tool.assessment.qti.constants.QTIVersion;
//import org.sakaiproject.tool.assessment.qti.helper.AuthoringHelper;
import org.sakaiproject.tool.assessment.qti.helper.AuthoringXml;
import org.sakaiproject.tool.assessment.services.qti.QTIService;
import org.sakaiproject.tool.assessment.qti.util.XmlUtil;
/**
* <p>Bean for QTI XML or XML fragments and descriptive information. </p>
* <p>Used to maintain information or to dump XML to client.</p>
* <p>Copyright: Copyright (c) 2004 Sakai</p>
* @author Ed Smiley esmiley@stanford.edu
* @version $Id: XMLController.java 106463 2012-04-02 12:20:09Z david.horwitz@uct.ac.za $
*/
public class XMLController implements Serializable
{
/**
*
*/
private static final long serialVersionUID = 7064783681056628447L;
private static Log log = LogFactory.getLog(XMLController.class);
private static final String XML_DECL =
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + "\n";
private XMLDisplay xmlBean;
private String documentType;
private String id;
private int qtiVersion;
public XMLController()
{
qtiVersion = QTIVersion.VERSION_1_2; //default
}
public XMLDisplay getXmlBean()
{
return xmlBean;
}
public void setXmlBean(XMLDisplay xmlBean)
{
this.xmlBean = xmlBean;
}
/**
* sets needed info in xml display bean when id set to assessment id
* @return
*/
public String displayAssessmentXml()
{
log.debug(
"XMLController debug getQtiVersion(): " + this.getQtiVersion());
documentType = AuthoringXml.ASSESSMENT;
return display();
}
public String displaySectionXmlTemplate()
{
documentType = AuthoringXml.SECTION;
return display();
}
public String displayItemXml()
{
documentType = AuthoringXml.ITEM_MCSC; // this is just a default, we will override
item();
return "xmlDisplay";
}
public String displayItemBankXml()
{
this.itemBank();
return "xmlDisplay";
}
public String display()
{
AuthoringXml ax = getAuthoringXml();
try
{
if (ax.isAssessment(documentType))
{
assessment();
}
else if (ax.isSection(documentType))
{
section();
}
else if (ax.isItem(documentType))
{
log.debug("item type detected");
item();
}
else if (ax.isSurveyFragment(documentType))
{
frag();
}
}
catch (Exception ex)
{
setUpXmlNoDecl("<error-report>" + "\n" +
ex.toString() + "\n" +
"</error-report>" + "\n");
xmlBean.setDescription(ex.toString());
xmlBean.setName("error");
xmlBean.setId("");
ex.printStackTrace();
}
return "xmlDisplay";
}
public String getDocumentType()
{
return documentType;
}
public void setDocumentType(String documentType)
{
this.documentType = documentType;
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
private void assessment()
{
xmlBean.setId(id);
xmlBean.setName(documentType);
if (id != null && id.length() > 0) // return populated xml from template
{
QTIService qtiService = new QTIService();
log.debug("XMLController.assessment() assessment " +
"qtiService.getExportedAssessment(id=" + id +
", qtiVersion=" +
qtiVersion + ")");
Document doc = qtiService.getExportedAssessment(id, qtiVersion);
xmlBean.setDescription(
"Exported QTI XML produced by Sakai's Tests and Quizzes tool (Samigo)");
xmlBean.setName("assessment " + id);
setUpXmlNoDecl(XmlUtil.getDOMString(doc));
}
else // return xml template, for testing
{
xmlBean.setDescription("assessment template");
//AuthoringHelper authHelper = new AuthoringHelper(qtiVersion);
AuthoringXml ax = getAuthoringXml();
String xml =
ax.getTemplateAsString(
ax.getTemplateInputStream(AuthoringXml.ASSESSMENT));
setUpXmlNoDecl(xml);
}
}
/**
* A utility method to set xml string in xml bean.
* @param xml the XML string
*/
private void setUpXmlNoDecl(String xml)
{
setUpXml(xml, false);
}
/**
* Logic for set xml string in xml bean with or without xml declaration.
* @param xml the XML string
* @param includeXmlDecl include "<?xml version... ? true or false?
*/
private void setUpXml(String xml, boolean includeXmlDecl)
{
boolean hasXmlDecl = false;
String startDecl = "<?xml version";
String endDecl = "?>";
int endDeclLength = endDecl.length();
if (xml.startsWith(startDecl))
{
hasXmlDecl = true;
}
// if we want a decl add it if it doesn't have one
// if we don't want decl remove it if it is there
if (includeXmlDecl)
{
if (!hasXmlDecl)
{
xml = XML_DECL + xml;
}
}
else
{
if (hasXmlDecl)
{
int declEndIndex = xml.indexOf(endDecl);
xml = xml.substring(declEndIndex + endDeclLength);
}
}
xmlBean.setXml(xml);
}
/**
* @todo add code to populate from SectionHelper
*/
private void section()
{
xmlBean.setId(id);
AuthoringXml ax = getAuthoringXml();
if (id != null && id.length() > 0)
{
xmlBean.setDescription("section fragment id=" + id);
xmlBean.setName(documentType); // get from document later
InputStream is = ax.getTemplateInputStream(AuthoringXml.SECTION);
setUpXmlNoDecl(ax.getTemplateAsString(is));
}
else
{
xmlBean.setDescription("section template");
xmlBean.setName(documentType); // get from document later
InputStream is = ax.getTemplateInputStream(AuthoringXml.SECTION);
setUpXmlNoDecl(ax.getTemplateAsString(is));
}
}
/**
* read in XML from item or item template
*/
private void item()
{
xmlBean.setId(id);
if (id != null && id.length() > 0)
{
QTIService qtiService = new QTIService();
Document doc = qtiService.getExportedItem(id, qtiVersion);
xmlBean.setDescription(
"Exported QTI XML produced by Sakai's Tests and Quizzes tool (Samigo)");
xmlBean.setName("item " + id); // get from document later
setUpXmlNoDecl(XmlUtil.getDOMString(doc));
}
else // for testing
{
//AuthoringHelper ah = new AuthoringHelper(qtiVersion);
AuthoringXml ax = getAuthoringXml();
xmlBean.setDescription("item template");
xmlBean.setName(documentType); // get from document later
InputStream is = ax.getTemplateInputStream(documentType);
setUpXmlNoDecl(ax.getTemplateAsString(is));
}
}
/**
* read in XML from item list (comma separated id string)
*/
private void itemBank()
{
xmlBean.setId(id); // this will be an item list
if (id != null && id.length() > 0)
{
QTIService qtiService = new QTIService();
StringTokenizer st = new StringTokenizer(id, ",");
int tokens = st.countTokens();
String[] ids = new String[tokens];
for (int i = 0; st.hasMoreTokens(); i++)
{
ids[i] = st.nextToken();
}
Document doc = qtiService.getExportedItemBank(ids, qtiVersion);
xmlBean.setDescription(
"Exported QTI XML produced by Sakai's Tests and Quizzes tool (Samigo)");
xmlBean.setName("object bank for items " + id); // get from document later
setUpXmlNoDecl(XmlUtil.getDOMString(doc));
}
else
{
log.debug("object bank empty");
}
}
private void frag()
{
xmlBean.setDescription("survey item fragment template");
xmlBean.setName(documentType); // get from document later
InputStream is = getAuthoringXml().getTemplateInputStream(documentType);
setUpXmlNoDecl(getAuthoringXml().getTemplateAsString(is));
}
// /**
// * derived property, uses String value of qtiVersion
// * @return String value of qtiVersion
// */
// public String getVersion()
// {
// return "" + getQtiVersion();
// }
// /**
// * derived property, uses String value of qtiVersion
// * if invalid will not set it
// * @param version String value of qtiVersion
// */
// public void setVersion(String version)
// {
//
// try {
// int v = Integer.parseInt(version);
// setQtiVersion(v);
// }
// catch (NumberFormatException ex) {
// // leave value alone
// }
// }
/**
* Always returns a valid QTI version.
* @return
*/
public int getQtiVersion()
{
if (!QTIVersion.isValid(qtiVersion))
{
qtiVersion = QTIVersion.VERSION_1_2; // default
}
log.debug("xml controller getQtiVersion()=" + qtiVersion);
return qtiVersion;
}
/**
* Only accepts valid QTI version.
* @param qtiVersion
*/
public void setQtiVersion(int qtiVersion)
{
if (!QTIVersion.isValid(qtiVersion))
{
throw new IllegalArgumentException("NOT Legal Qti Version.");
}
this.qtiVersion = qtiVersion;
log.debug("xml controller setQtiVersion()=" + qtiVersion);
}
public AuthoringXml getAuthoringXml()
{
return new AuthoringXml(getQtiVersion());
}
}