/** @author Scott Marshall @author University of Glasgow, MSc IT Project 2001 @author Building an OnLine Course in Computing Fundamentals Multiple Choice Questions */ package ukacgla_HTMLMulti; import ukacgla_HTMLMulti.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.JApplet; import java.io.*; import java.util.*; import java.net.*; /** TestEngine holds ALL the the questions for a session. It reads the input file at testURL, and while inStream is not null, uses a StringTokenizer to read the file. It then creates a new question URL from testURL plus txt read from inStream (relative URL construction). It then creates a new answer URL from testURL plus txt read from inStream (relative URL construction). It then creates a new TestItem and adds it to the Vector testVector. Test vector is then cloned to currVector to prevent a concurrent access exception. The cloned Vector currVector is then randomised to ensure options are presented in different order each time. */ public class TestEngine { Vector testVector = new Vector(); //holds all Strings read from input file Vector currVector = new Vector(); Iterator it ; int numQuestions; URL questionURL, answerURL; public TestEngine(URL testURL, int numQuestions){ this.numQuestions = numQuestions; try { //open a stream to read the test file InputStream inStream = testURL.openStream(); BufferedReader dataStream = new BufferedReader(new InputStreamReader(inStream)); String inLine = null; while ((inLine = dataStream.readLine())!=null){ //use a String tokenizer to read the txt file. StringTokenizer t = new StringTokenizer(inLine,"$*"); //use this to make URL of the question while (t.hasMoreTokens()){ try { questionURL = new URL(testURL,new String(t.nextToken())); } catch (MalformedURLException e) { System.out.println("Invalid Test URL read from file : " + questionURL); } //then make the URL of the answers. This file will be read later by TestItem try { answerURL = new URL(testURL,new String(t.nextToken())); } catch (MalformedURLException e) { System.out.println("Invalid Answer URL read from file : " + answerURL); } testVector.add(new TestItem(questionURL, answerURL)); }//ends hasMoreTokens }//ends readLine /** Returns a clone of this vector. The copy contains a reference to a clone of the internal data array, not a reference to the original internal data array of this Vector object. */ currVector = (Vector) testVector.clone(); /** Mix up the order of the questions, to the number specified The result is answerList may contain less than the total number of questions written. The number of questions is specified in the HTML file as the numQuestions parameter */ TestRandomiser random = new TestRandomiser(numQuestions); currVector = random.randomise(currVector); } catch(IOException e){ } } //------------------ ACCESSORS ------------------------------------------ /** Returns TestItem at specified index. Throws IndexOutOfBounds exception if argument exceeds Vector size. */ protected TestItem getNextTest(int n){ if (n>=currVector.size()) throw new IndexOutOfBoundsException("No questions exist at this index"); else return (TestItem) currVector.get(n); } /** Return number of TestItems in this TestItem */ protected int getNumQuestions(){ return currVector.size(); } }//ends class