package uk.co.bytemark.vm.enigma.inquisition.questions;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdom.Document;
import org.jdom.Element;
import uk.co.bytemark.vm.enigma.inquisition.questions.xml.XmlQuestionSetParser;
/**
* Importer for the native file format
*
*/
public class NativeQuestionSetImporter extends AbstractQuestionSetImporter {
private static final Logger LOGGER = Logger.getLogger( NativeQuestionSetImporter.class.getName() );
/**
* Constructs a new <tt>QuestionSet</tt> from a JDOM Document
*
* @param doc
* the JDOM document element to parse.
* @throws ParseException
* if any vital information can't be found.
*/
@Override
public QuestionSet processDocument( Document doc ) throws ParseException {
Element root = doc.getRootElement();
if ( !root.getName().equalsIgnoreCase( "QuestionSet" ) )
throw new ParseException( "QuestionSet: Root not <QuestionSet>", 0 );
// Check version number
String versionString = root.getAttributeValue( "version" );
if ( versionString == null ) {
LOGGER.warning( "No `version' attribute on <QuestionSet> element" );
} else {
try {
int version = Integer.parseInt( versionString );
if ( version == 1 || version == 2 || version == 3 ) {
LOGGER.warning( "QuestionSet version " + version + " is no longer " + "supported: proceeding anyway, but errors may be present." );
} else if ( version == 4 ) {
// Supported, do nothing
} else {
// Unsupported, give warning
LOGGER.warning( "QuestionSet format version (" + version + ") is newer than this software and may not be handled correctly." );
}
} catch ( NumberFormatException e ) {
LOGGER.log( Level.WARNING, "Cannot parse version number: " + versionString, e );
}
}
List<?> topElements = root.getChildren();
// Loop over the top-level elements
String name = null;
String description = null;
int recommendedTimePerQuestion = -1;
String category = "";
List<Question> questions = new ArrayList<Question>();
for ( Object object : topElements ) {
Element topElement = (Element) object;
String tagName = topElement.getName();
if ( tagName.equalsIgnoreCase( "Name" ) ) {
name = topElement.getText();
} else if ( tagName.equalsIgnoreCase( "Description" ) ) {
description = topElement.getText();
} else if ( tagName.equalsIgnoreCase( "RecommendedTimePerQuestion" ) ) {
recommendedTimePerQuestion = Integer.parseInt( topElement.getText() );
} else if ( tagName.equalsIgnoreCase( "Category" ) ) {
category = topElement.getText();
} else if ( tagName.equalsIgnoreCase( "Questions" ) ) {
// Loop over each question
for ( Object object2 : topElement.getChildren() ) {
Element questionElement = (Element) object2;
String name2 = questionElement.getName();
try {
if ( name2.equalsIgnoreCase( "MultipleChoiceQuestion" ) ) {
questions.add( new XmlQuestionSetParser().parseMultipleChoiceQuestion( questionElement, new ParsingProblemRecorder() ) );
} else if ( name2.equalsIgnoreCase( "DragAndDropQuestion" ) ) {
questions.add( new DragAndDropQuestion( questionElement ) );
} else {
LOGGER.warning( "Unrecognised tag: " + name2 );
}
} catch ( ParseException e ) {
LOGGER.log( Level.WARNING, "Error parsing Question, skipping", e );
continue;
}
}
} else {
LOGGER.warning( "Unrecognised tag: " + tagName );
}
}
if ( questions.size() == 0 )
throw new ParseException( "No valid questions found in QuestionSet", 0 );
if ( name == null ) {
LOGGER.warning( "no <Name> provided" );
name = "No name given";
}
if ( recommendedTimePerQuestion == -1 ) {
LOGGER.warning( "no <RecommendedTimePerQuestion> provided" );
recommendedTimePerQuestion = 120; // default two minutes per question
}
if ( category == "" ) {
LOGGER.warning( "No category listed for this question set" );
}
if ( description == null ) {
LOGGER.warning( "no <Description> provided" );
description = "No description given";
}
return new QuestionSet( name, description, recommendedTimePerQuestion, category, questions );
}
}