|
From: <bar...@us...> - 2010-04-09 17:09:17
|
Revision: 2447
http://qtitools.svn.sourceforge.net/qtitools/?rev=2447&view=rev
Author: bartnagel
Date: 2010-04-09 17:09:10 +0000 (Fri, 09 Apr 2010)
Log Message:
-----------
added Rest API (written by Pei Zhang)
Added Paths:
-----------
trunk/projects/QTIEngine/docs_api/
trunk/projects/QTIEngine/docs_api/Deployment.pdf
trunk/projects/QTIEngine/docs_api/Known_Issues.pdf
trunk/projects/QTIEngine/docs_api/playItem.pdf
trunk/projects/QTIEngine/docs_api/playItem.xml
trunk/projects/QTIEngine/docs_api/playItemPost.txt
trunk/projects/QTIEngine/docs_api/playTest.pdf
trunk/projects/QTIEngine/docs_api/playTest.xml
trunk/projects/QTIEngine/docs_api/playTestFinished.xml
trunk/projects/QTIEngine/docs_api/playTestPost.txt
trunk/projects/QTIEngine/docs_api/report.xml
trunk/projects/QTIEngine/docs_api/reportPost.txt
trunk/projects/QTIEngine/docs_api/upload.xml
trunk/projects/QTIEngine/docs_api/uploadPost.txt
trunk/projects/QTIEngine/docs_api/webFramwork.pdf
trunk/projects/QTIEngine/grails-app/controllers/RestController.groovy
trunk/projects/QTIEngine/grails-app/services/RestService.groovy
trunk/projects/QTIEngine/grails-app/views/rest/
trunk/projects/QTIEngine/src/groovy/org/qtitools/qtiengine/RestApiException.groovy
trunk/projects/QTIEngine/test/integration/RestControllerTests.groovy
trunk/projects/QTIEngine/test/integration/RestServiceTests.groovy
Added: trunk/projects/QTIEngine/docs_api/Deployment.pdf
===================================================================
(Binary files differ)
Property changes on: trunk/projects/QTIEngine/docs_api/Deployment.pdf
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: trunk/projects/QTIEngine/docs_api/Known_Issues.pdf
===================================================================
(Binary files differ)
Property changes on: trunk/projects/QTIEngine/docs_api/Known_Issues.pdf
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: trunk/projects/QTIEngine/docs_api/playItem.pdf
===================================================================
(Binary files differ)
Property changes on: trunk/projects/QTIEngine/docs_api/playItem.pdf
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: trunk/projects/QTIEngine/docs_api/playItem.xml
===================================================================
--- trunk/projects/QTIEngine/docs_api/playItem.xml (rev 0)
+++ trunk/projects/QTIEngine/docs_api/playItem.xml 2010-04-09 17:09:10 UTC (rev 2447)
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<root>
+ <status>0</status>
+ <page>
+ <html xmlns='http://www.w3.org/1999/xhtml'>
+ <head><link href='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/content/internal//style/style.css' type='text/css' rel='stylesheet'></link><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/QTIV2JSCRIPT.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/prototype.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/builder.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/effects.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/dragdrop.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/controls.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/slider.js'> </script><link href='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/css/r2q2.css' type='text/css' rel='stylesheet' media='screen'></link><title> :: Getting Started</title>
+ </head>
+ <body>
+ <div id='navbar'></div><h1>Getting Started</h1><div id='body'><div id='body-container'><form action='http://localhost:51237/Question/PlayItem/21' autocomplete='off' enctype='multipart/form-data' onreset='doReset();' onsubmit='return doSubmit();' name='QuestionForm' method='post' id='QuestionForm'><input value='1' type='hidden' name='questionId'></input><div class='outer-box'><span class='box-title'>Question</span><div class='inner-box'><p><b> Question 8</b><br clear='none'></br><br clear='none'></br> Identify the missing words in the following passage.</p><blockquote><p> In order to view your homepage in a web browser through the Internet, you need to upload the page into the folder on the web server that was distinguished in the previous question of this test. This folder needs to be situated in the home directory and has to be <select name='RESPONSE1'><option value='ChoiceC'></option><option value='ChoiceA'> in upper case</option><option value='ChoiceB' selected='selected'> in lower case</option></select>, with the words being separated by the <select name='RESPONSE2'><option value='Choice4'></option><option value='Choice1'> dash (-)</option><option value='Choice2' selected='selected'> underline (_)</option><option value='Choice3'> full stop (.)</option></select> symbol.</p></blockquote><table id='controls'><tr><td width='100%' align='center' colspan='1' rowspan='1'><input value='RESET' type='reset'></input><input value='SUBMIT ANSWER' type='submit' name='submit' id='submit_button'></input></td></tr></table></div></div><div class='spacer'> </div></form></div></div><hr></hr><h2>Internal State</h2><hr></hr><h3>Response vars</h3>numAttempts :
+ 1<br clear='none'></br>RESPONSE1 :
+ ChoiceB<br clear='none'></br>RESPONSE2 :
+ Choice2<br clear='none'></br>duration :
+ 373.327<br clear='none'></br><hr></hr><h3>Outcome vars</h3>completionStatus :
+ unknown<br clear='none'></br>SCORE :
+ 2<br clear='none'></br>
+ </body>
+ </html>
+ </page>
+ <vars>
+ <ResponseVars>
+ <param identifier='numAttempts'>1</param>
+ <param identifier='RESPONSE1'>ChoiceB</param>
+ <param identifier='RESPONSE2'>Choice2</param>
+ <param identifier='duration'>374.155</param>
+ </ResponseVars>
+ <OutcomeVars>
+ <param identifier='completionStatus'>unknown</param>
+ <param identifier='SCORE'>2</param>
+ </OutcomeVars>
+ </vars>
+</root>
\ No newline at end of file
Added: trunk/projects/QTIEngine/docs_api/playItemPost.txt
===================================================================
--- trunk/projects/QTIEngine/docs_api/playItemPost.txt (rev 0)
+++ trunk/projects/QTIEngine/docs_api/playItemPost.txt 2010-04-09 17:09:10 UTC (rev 2447)
@@ -0,0 +1,24 @@
+Content-Type: multipart/form-data; boundary=--------------------------8cc5d9a0d600df8
+Content-Length: 619
+
+-----------------------------8cc5d9a0d600df8
+Content-Disposition: form-data; name="questionId"
+
+1
+-----------------------------8cc5d9a0d600df8
+Content-Disposition: form-data; name="RESPONSE1"
+
+ChoiceA
+-----------------------------8cc5d9a0d600df8
+Content-Disposition: form-data; name="RESPONSE2"
+
+Choice1
+-----------------------------8cc5d9a0d600df8
+Content-Disposition: form-data; name="submit"
+
+SUBMIT ANSWER
+-----------------------------8cc5d9a0d600df8
+Content-Disposition: form-data; name="actionUrl"
+
+http://localhost:51237/Question/PlayItem/21
+-----------------------------8cc5d9a0d600df8--
Added: trunk/projects/QTIEngine/docs_api/playTest.pdf
===================================================================
(Binary files differ)
Property changes on: trunk/projects/QTIEngine/docs_api/playTest.pdf
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: trunk/projects/QTIEngine/docs_api/playTest.xml
===================================================================
--- trunk/projects/QTIEngine/docs_api/playTest.xml (rev 0)
+++ trunk/projects/QTIEngine/docs_api/playTest.xml 2010-04-09 17:09:10 UTC (rev 2447)
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<root>
+ <status>0</status>
+ <page>
+ <html xmlns='http://www.w3.org/1999/xhtml'>
+ <head><link href='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/content/uploads/11CEB576867F85AB13D7895E1589063F//style/style.css' type='text/css' rel='stylesheet'></link><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/QTIV2JSCRIPT.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/prototype.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/builder.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/effects.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/dragdrop.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/controls.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/slider.js'> </script><link href='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/css/r2q2.css' type='text/css' rel='stylesheet' media='screen'></link><link href='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/css/asdel.css' type='text/css' rel='stylesheet' media='screen'></link><title>Web Developer Website :: Getting Started</title>
+ </head>
+ <body><div id='navbar'></div><h1>Getting Started</h1><div id='body'><div id='body-container'><h1>Web Developer Website</h1><h2>Electronics and Computer Science<br></br></h2><form action='http://localhost:51237/Question/PlayTest/19' autocomplete='off' enctype='multipart/form-data' onreset='doReset();' onsubmit='return doSubmit();' name='QuestionForm' method='post' id='QuestionForm'><input value='question2' type='hidden' name='questionId'></input><div class='outer-box'><span class='box-title'>Question</span><div class='inner-box'><p><b> Question 2</b></p><table class='choice_interaction' id='choiceInteraction-RESPONSE'><tr class='prompt'><td colspan='2' rowspan='1'> What is the notation required to create a link to another page? <br clear='none'></br><br clear='none'></br></td></tr><tr class='choice_interaction'><td class='choice_interaction' colspan='1' rowspan='1'> <a = "myimage.html">Link to my page</a></td><td class='control' colspan='1' rowspan='1'><input value='ChoiceB' type='radio' name='RESPONSE'></input></td></tr><tr class='choice_interaction'><td class='choice_interaction' colspan='1' rowspan='1'> <a href = "myimage.html"></td><td class='control' colspan='1' rowspan='1'><input value='ChoiceC' type='radio' name='RESPONSE'></input></td></tr><tr class='choice_interaction'><td class='choice_interaction' colspan='1' rowspan='1'> <a href = Link to my page</a></td><td class='control' colspan='1' rowspan='1'><input value='ChoiceD' type='radio' name='RESPONSE'></input></td></tr><tr class='choice_interaction'><td class='choice_interaction' colspan='1' rowspan='1'> <a href = "myimage.html">Link to my page</a></td><td class='control' colspan='1' rowspan='1'><input value='ChoiceA' type='radio' name='RESPONSE'></input></td></tr></table></div></div><div class='spacer'> </div><div class='outer-box'><span class='box-title'>Controls</span><div class='inner-box'><table width='100%'><tr><td width='25%' align='left'></td><td width='50%' align='center'><input value='Clear' type='reset'></input><input value='Skip' type='submit' name='skip' id='Skip'></input><input value='Submit answer' type='submit' name='submit' id='submit_button'></input></td><td align='right'></td></tr><tr><td align='left'><input value='Backward' type='submit' name='backward' id='backward'></input></td><td align='center'><input value='Exit test' type='submit' onclick='return confirm('Are you sure you want to end this test? All progress will be lost.')' name='exit' id='exit'></input><input value='View report' type='button' onclick='window.open("?report", "report");'></input></td><td align='right'></td></tr></table></div></div></form></div></div>
+ </body>
+ </html>
+ </page>
+</root>
\ No newline at end of file
Added: trunk/projects/QTIEngine/docs_api/playTestFinished.xml
===================================================================
--- trunk/projects/QTIEngine/docs_api/playTestFinished.xml (rev 0)
+++ trunk/projects/QTIEngine/docs_api/playTestFinished.xml 2010-04-09 17:09:10 UTC (rev 2447)
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<root>
+ <status>1</status>
+ <finished>
+ <html xmlns='http://www.w3.org/1999/xhtml'>
+ <head><link href='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/content/uploads/2EBCF34FFDB3C55EFBBD16DF58D618A1//style/style.css' type='text/css' rel='stylesheet'></link><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/QTIV2JSCRIPT.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/prototype.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/builder.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/effects.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/dragdrop.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/controls.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/slider.js'> </script><link href='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/css/r2q2.css' type='text/css' rel='stylesheet' media='screen'></link><link href='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/css/asdel.css' type='text/css' rel='stylesheet' media='screen'></link><title>Scenario :: </title>
+ </head>
+ <body><div id='navbar'></div><h1></h1><div id='body'><div id='body-container'><h1>Scenario</h1><div>This assessment is now complete.</div><br></br><div><a href='#' onclick='window.open('?report', 'report');'>Click here to view the test report</a></div><br></br><div><a href='?exit'>Click here to return to the main page</a></div></div></div>
+ </body>
+ </html>
+ </finished>
+ <report>
+ <assessmentResult xsi:schemaLocation='http://www.imsglobal.org/xsd/imsqti_v2p1 imsqti_v2p1.xsd' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://www.imsglobal.org/xsd/imsqti_v2p1'>
+ <testResult datestamp='2010-01-06T17:06:53' identifier='SCENARIO'>
+ <outcomeVariable cardinality='single' identifier='duration' baseType='duration'>
+ <value>23.001</value>
+ </outcomeVariable>
+ <outcomeVariable cardinality='single' identifier='part1.duration' baseType='duration'>
+ <value>23.001</value>
+ </outcomeVariable>
+ <outcomeVariable cardinality='single' identifier='sectionA.duration' baseType='duration'>
+ <value>23.001</value>
+ </outcomeVariable>
+ </testResult>
+ <itemResult sequenceIndex='1' datestamp='2010-01-06T17:06:53' identifier='item1'>
+ <outcomeVariable cardinality='single' identifier='outcome' baseType='identifier'>
+ <value>C</value>
+ </outcomeVariable>
+ <outcomeVariable cardinality='single' identifier='completionStatus' baseType='string'>
+ <value>unknown</value>
+ </outcomeVariable>
+ <responseVariable cardinality='single' identifier='RESPONSE' baseType='identifier'>
+ <correctResponse>
+ <value>C</value>
+ </correctResponse>
+ <candidateResponse>
+ <value>C</value>
+ </candidateResponse>
+ </responseVariable>
+ <responseVariable cardinality='single' identifier='numAttempts' baseType='integer'>
+ <candidateResponse>
+ <value>1</value>
+ </candidateResponse>
+ </responseVariable>
+ <responseVariable cardinality='single' identifier='duration' baseType='float'>
+ <candidateResponse>
+ <value>13.704</value>
+ </candidateResponse>
+ </responseVariable>
+ </itemResult>
+ <itemResult sequenceIndex='2' datestamp='2010-01-06T17:06:53' identifier='item2_1'>
+ <outcomeVariable cardinality='single' identifier='outcome' baseType='identifier'>
+ </outcomeVariable>
+ <outcomeVariable cardinality='single' identifier='completionStatus' baseType='identifier'><value>not_attempted</value></outcomeVariable><responseVariable cardinality='single' identifier='RESPONSE' baseType='identifier'><correctResponse><value>B</value></correctResponse><candidateResponse></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='numAttempts' baseType='integer'><candidateResponse><value>0</value></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='duration' baseType='float'><candidateResponse><value>0.0</value></candidateResponse></responseVariable></itemResult><itemResult sequenceIndex='3' datestamp='2010-01-06T17:06:53' identifier='item2_2'><outcomeVariable cardinality='single' identifier='outcome' baseType='identifier'></outcomeVariable><outcomeVariable cardinality='single' identifier='completionStatus' baseType='string'><value>unknown</value></outcomeVariable><responseVariable cardinality='multiple' identifier='RESPONSE' baseType='identifier'><correctResponse><value>A</value><value>C</value></correctResponse><candidateResponse><value>A</value></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='numAttempts' baseType='integer'><candidateResponse><value>1</value></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='duration' baseType='float'><candidateResponse><value>9.297</value></candidateResponse></responseVariable>
+ </itemResult>
+ </assessmentResult>
+ </report>
+</root>
\ No newline at end of file
Added: trunk/projects/QTIEngine/docs_api/playTestPost.txt
===================================================================
--- trunk/projects/QTIEngine/docs_api/playTestPost.txt (rev 0)
+++ trunk/projects/QTIEngine/docs_api/playTestPost.txt 2010-04-09 17:09:10 UTC (rev 2447)
@@ -0,0 +1,20 @@
+Content-Type: multipart/form-data; boundary=---------------------------8cc5d9700585e12
+Content-Length: 519
+
+-----------------------------8cc5d9700585e12
+Content-Disposition: form-data; name="questionId"
+
+question2
+-----------------------------8cc5d9700585e12
+Content-Disposition: form-data; name="RESPONSE"
+
+ChoiceD
+-----------------------------8cc5d9700585e12
+Content-Disposition: form-data; name="submit"
+
+Submit answer
+-----------------------------8cc5d9700585e12
+Content-Disposition: form-data; name="actionUrl"
+
+http://localhost:51237/Question/PlayTest/19
+-----------------------------8cc5d9700585e12--
Added: trunk/projects/QTIEngine/docs_api/report.xml
===================================================================
--- trunk/projects/QTIEngine/docs_api/report.xml (rev 0)
+++ trunk/projects/QTIEngine/docs_api/report.xml 2010-04-09 17:09:10 UTC (rev 2447)
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<root>
+ <status>3</status>
+ <report>
+ <assessmentResult xsi:schemaLocation='http://www.imsglobal.org/xsd/imsqti_v2p1 imsqti_v2p1.xsd' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://www.imsglobal.org/xsd/imsqti_v2p1'>
+ <testResult datestamp='2010-01-06T17:15:34' identifier='TEST'>
+ <outcomeVariable cardinality='single' identifier='SCORE' baseType='float'>
+ </outcomeVariable>
+ <outcomeVariable cardinality='single' identifier='outcomeIdentifier' baseType='identifier'>
+ </outcomeVariable>
+ <outcomeVariable cardinality='single' identifier='duration' baseType='duration'>
+ <value>21.391</value>
+ </outcomeVariable><outcomeVariable cardinality='single' identifier='part1.duration' baseType='duration'><value>21.391</value></outcomeVariable><outcomeVariable cardinality='single' identifier='sectionquestion1.duration' baseType='duration'><value>21.391</value></outcomeVariable></testResult><itemResult sequenceIndex='1' datestamp='2010-01-06T17:15:34' identifier='question1'><outcomeVariable cardinality='single' identifier='SCORE' baseType='integer'><value>0</value></outcomeVariable><outcomeVariable cardinality='single' identifier='completionStatus' baseType='string'><value>unknown</value></outcomeVariable><responseVariable choiceSequence='ChoiceA ChoiceB ChoiceC' cardinality='single' identifier='RESPONSE' baseType='identifier'><correctResponse><value>ChoiceC</value></correctResponse><candidateResponse><value>ChoiceB</value></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='numAttempts' baseType='integer'><candidateResponse><value>1</value></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='duration' baseType='float'><candidateResponse><value>10.36</value></candidateResponse></responseVariable></itemResult><itemResult sequenceIndex='2' datestamp='2010-01-06T17:15:34' identifier='question2'><outcomeVariable cardinality='single' identifier='SCORE' baseType='integer'><value>0</value></outcomeVariable><outcomeVariable cardinality='single' identifier='completionStatus' baseType='string'><value>unknown</value></outcomeVariable><responseVariable choiceSequence='ChoiceA ChoiceD ChoiceB ChoiceC' cardinality='single' identifier='RESPONSE' baseType='identifier'><correctResponse><value>ChoiceA</value></correctResponse><candidateResponse><value>ChoiceB</value></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='numAttempts' baseType='integer'><candidateResponse><value>1</value></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='duration' baseType='float'><candidateResponse><value>5.219</value></candidateResponse></responseVariable></itemResult><itemResult sequenceIndex='3' datestamp='2010-01-06T17:15:34' identifier='question3'><outcomeVariable cardinality='single' identifier='SCORE' baseType='integer'><value>0</value></outcomeVariable><outcomeVariable cardinality='single' identifier='completionStatus' baseType='string'><value>unknown</value></outcomeVariable><responseVariable choiceSequence='ChoiceB ChoiceD ChoiceC ChoiceA' cardinality='single' identifier='RESPONSE' baseType='identifier'><correctResponse><value>ChoiceC</value></correctResponse><candidateResponse></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='numAttempts' baseType='integer'><candidateResponse><value>0</value></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='duration' baseType='float'><candidateResponse><value>5.781</value></candidateResponse></responseVariable></itemResult><itemResult sequenceIndex='4' datestamp='2010-01-06T17:15:34' identifier='question4'><outcomeVariable cardinality='single' identifier='SCORE' baseType='integer'><value>0</value></outcomeVariable><outcomeVariable cardinality='single' identifier='completionStatus' baseType='identifier'><value>not_attempted</value></outcomeVariable><responseVariable choiceSequence='ChoiceA ChoiceB ChoiceC ChoiceD' cardinality='single' identifier='RESPONSE' baseType='identifier'><correctResponse><value>ChoiceD</value></correctResponse><candidateResponse></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='numAttempts' baseType='integer'><candidateResponse><value>0</value></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='duration' baseType='float'><candidateResponse><value>0.0</value></candidateResponse></responseVariable></itemResult><itemResult sequenceIndex='5' datestamp='2010-01-06T17:15:34' identifier='question5'><outcomeVariable cardinality='single' identifier='SCORE' baseType='float'><value>0.0</value></outcomeVariable><outcomeVariable cardinality='single' identifier='completionStatus' baseType='identifier'><value>not_attempted</value></outcomeVariable><responseVariable choiceSequence='ChoiceA ChoiceB ChoiceC ChoiceD ChoiceE' cardinality='multiple' identifier='RESPONSE' baseType='identifier'><correctResponse><value>ChoiceB</value><value>ChoiceE</value></correctResponse><candidateResponse></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='numAttempts' baseType='integer'><candidateResponse><value>0</value></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='duration' baseType='float'><candidateResponse><value>0.0</value></candidateResponse></responseVariable></itemResult><itemResult sequenceIndex='6' datestamp='2010-01-06T17:15:34' identifier='question6'><outcomeVariable cardinality='single' identifier='SCORE' baseType='integer'><value>0</value></outcomeVariable><outcomeVariable cardinality='single' identifier='completionStatus' baseType='identifier'><value>not_attempted</value></outcomeVariable><responseVariable choiceSequence='ChoiceA ChoiceB ChoiceC ChoiceD' cardinality='single' identifier='RESPONSE' baseType='identifier'><correctResponse><value>ChoiceD</value></correctResponse><candidateResponse></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='numAttempts' baseType='integer'><candidateResponse><value>0</value></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='duration' baseType='float'><candidateResponse><value>0.0</value></candidateResponse></responseVariable></itemResult><itemResult sequenceIndex='7' datestamp='2010-01-06T17:15:34' identifier='question7'><outcomeVariable cardinality='single' identifier='SCORE' baseType='integer'><value>0</value></outcomeVariable><outcomeVariable cardinality='single' identifier='completionStatus' baseType='identifier'><value>not_attempted</value></outcomeVariable><responseVariable choiceSequence='ChoiceA ChoiceB ChoiceC ChoiceD' cardinality='single' identifier='RESPONSE' baseType='identifier'><correctResponse><value>ChoiceA</value></correctResponse><candidateResponse></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='numAttempts' baseType='integer'><candidateResponse><value>0</value></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='duration' baseType='float'><candidateResponse><value>0.0</value></candidateResponse></responseVariable></itemResult><itemResult sequenceIndex='8' datestamp='2010-01-06T17:15:34' identifier='question8'><outcomeVariable cardinality='single' identifier='SCORE' baseType='integer'></outcomeVariable><outcomeVariable cardinality='single' identifier='completionStatus' baseType='identifier'><value>not_attempted</value></outcomeVariable><responseVariable cardinality='single' identifier='numAttempts' baseType='integer'><candidateResponse><value>0</value></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='RESPONSE1' baseType='identifier'><correctResponse><value>ChoiceB</value></correctResponse><candidateResponse></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='RESPONSE2' baseType='identifier'><correctResponse><value>Choice2</value></correctResponse><candidateResponse></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='duration' baseType='float'><candidateResponse><value>0.0</value></candidateResponse></responseVariable></itemResult><itemResult sequenceIndex='9' datestamp='2010-01-06T17:15:34' identifier='question9'><outcomeVariable cardinality='single' identifier='SCORE' baseType='float'><value>0.0</value></outcomeVariable><outcomeVariable cardinality='single' identifier='completionStatus' baseType='identifier'><value>not_attempted</value></outcomeVariable><responseVariable choiceSequence='ChoiceA ChoiceB ChoiceC ChoiceD' cardinality='multiple' identifier='RESPONSE' baseType='identifier'><correctResponse><value>ChoiceA</value><value>ChoiceB</value></correctResponse><candidateResponse></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='numAttempts' baseType='integer'><candidateResponse><value>0</value></candidateResponse></responseVariable><responseVariable cardinality='single' identifier='duration' baseType='float'><candidateResponse><value>0.0</value></candidateResponse></responseVariable>
+ </itemResult>
+ </assessmentResult>
+ </report>
+</root>
\ No newline at end of file
Added: trunk/projects/QTIEngine/docs_api/reportPost.txt
===================================================================
--- trunk/projects/QTIEngine/docs_api/reportPost.txt (rev 0)
+++ trunk/projects/QTIEngine/docs_api/reportPost.txt 2010-04-09 17:09:10 UTC (rev 2447)
@@ -0,0 +1,13 @@
+Content-Type: multipart/form-data; boundary=---------------------------8cc5d988d97a322
+Content-Length: 293
+
+
+-----------------------------8cc5d988d97a322
+Content-Disposition: form-data; name="report"
+
+report
+-----------------------------8cc5d988d97a322
+Content-Disposition: form-data; name="actionUrl"
+
+http://localhost:51237/Question/PlayTest
+-----------------------------8cc5d988d97a322--
Added: trunk/projects/QTIEngine/docs_api/upload.xml
===================================================================
--- trunk/projects/QTIEngine/docs_api/upload.xml (rev 0)
+++ trunk/projects/QTIEngine/docs_api/upload.xml 2010-04-09 17:09:10 UTC (rev 2447)
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<root>
+ <status>0</status>
+ <page>
+ <html xmlns='http://www.w3.org/1999/xhtml'>
+ <head><link href='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/content/internal//style/style.css' type='text/css' rel='stylesheet'></link><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/QTIV2JSCRIPT.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/prototype.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/builder.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/effects.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/dragdrop.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/controls.js'> </script><script type='text/javascript' src='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/Jscript/slider.js'> </script><link href='http://lslvm-pz3.ecs.soton.ac.uk:8080/QTIEngine/css/r2q2.css' type='text/css' rel='stylesheet' media='screen'></link><title> :: Getting Started</title></head>
+ <body><div id='navbar'></div><h1>Getting Started</h1><div id='body'><div id='body-container'><form action='http://localhost:51237/Question/PlayItem/21' autocomplete='off' enctype='multipart/form-data' onreset='doReset();' onsubmit='return doSubmit();' name='QuestionForm' method='post' id='QuestionForm'><input value='1' type='hidden' name='questionId'></input><div class='outer-box'><span class='box-title'>Question</span><div class='inner-box'><p><b> Question 8</b><br clear='none'></br><br clear='none'></br> Identify the missing words in the following passage.</p><blockquote><p> In order to view your homepage in a web browser through the Internet, you need to upload the page into the folder on the web server that was distinguished in the previous question of this test. This folder needs to be situated in the home directory and has to be <select name='RESPONSE1'><option value='ChoiceC'></option><option value='ChoiceA'> in upper case</option><option value='ChoiceB'> in lower case</option></select>, with the words being separated by the <select name='RESPONSE2'><option value='Choice4'></option><option value='Choice1'> dash (-)</option><option value='Choice2'> underline (_)</option><option value='Choice3'> full stop (.)</option></select> symbol.</p></blockquote><table id='controls'><tr><td width='100%' align='center' colspan='1' rowspan='1'><input value='RESET' type='reset'></input><input value='SUBMIT ANSWER' type='submit' name='submit' id='submit_button'></input></td></tr></table></div></div><div class='spacer'> </div></form></div></div><hr></hr><h2>Internal State</h2><hr></hr><h3>Response vars</h3>numAttempts :
+ 0<br clear='none'></br>RESPONSE1 :
+ <br clear='none'></br>RESPONSE2 :
+ <br clear='none'></br>duration :
+ 0.016<br clear='none'></br><hr></hr><h3>Outcome vars</h3>completionStatus :
+ unknown<br clear='none'></br>SCORE :
+ <br clear='none'></br>
+ </body>
+ </html>
+ </page>
+</root>
\ No newline at end of file
Added: trunk/projects/QTIEngine/docs_api/uploadPost.txt
===================================================================
--- trunk/projects/QTIEngine/docs_api/uploadPost.txt (rev 0)
+++ trunk/projects/QTIEngine/docs_api/uploadPost.txt 2010-04-09 17:09:10 UTC (rev 2447)
@@ -0,0 +1,9 @@
+Content-Type: multipart/form-data; boundary=---------------------------41184676334
+Content-Length: 10088
+
+-----------------------------41184676334
+Content-Disposition: form-data; name="uploadedContent"; filename="devtest.zip"
+Content-Type: application/zip
+
+filecontent....
+-----------------------------41184676334--
Added: trunk/projects/QTIEngine/docs_api/webFramwork.pdf
===================================================================
(Binary files differ)
Property changes on: trunk/projects/QTIEngine/docs_api/webFramwork.pdf
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: trunk/projects/QTIEngine/grails-app/controllers/RestController.groovy
===================================================================
--- trunk/projects/QTIEngine/grails-app/controllers/RestController.groovy (rev 0)
+++ trunk/projects/QTIEngine/grails-app/controllers/RestController.groovy 2010-04-09 17:09:10 UTC (rev 2447)
@@ -0,0 +1,326 @@
+import org.qtitools.qti.node.XmlNode;
+import org.qtitools.qti.node.item.AssessmentItem;
+import org.qtitools.qti.node.test.*;
+import org.qtitools.qti.validation.ValidationResult;
+import org.qtitools.util.*;
+import org.qtitools.qti.rendering.Renderer;
+import org.qtitools.qti.rendering.utils.ExtensibleXSLTSource;
+import grails.converters.*;
+import groovy.xml.*;
+import org.qtitools.qtiengine.RestApiException;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.servlet.ServletContext;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.XMLConstants;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.qtitools.qti.controller.TestCoordinator;
+
+class RestController {
+
+ def applicationService
+ def testService
+ def utilitiesService
+ def restService
+
+ def index = { }
+
+ def newSession = {
+ render session.getId()
+ }
+ def upload= {
+ //What we need....
+ //<sessionId>
+ //<status>
+ //<message>
+ //<code>
+
+ println "sessionid:"+request.getSession().getId()
+ if (!params.uploadedContent)
+ {
+ render restService.createErrorResponse("44","uploadedContent failed!") //change it to xml later
+ return
+ }
+
+ if(!params.actionUrl)
+ {
+ render restService.createErrorResponse("44","Please specify your url to pass the request. For example, http://playr_server:playr_port/path_to_playr/api/play")
+ return
+ }
+ //println "actionUrl:"+params.actionUrl
+ if(params.imagesUrl)
+ println "imagesUrl:"+params.imagesUrl
+ //Pei: not support for google chrome, getContentType() may return something unexpected
+ def type = params.uploadedContent.getContentType()
+
+ if (type.contains("zip")) {
+ ContentPackage content = applicationService.handleZip(params.uploadedContent.getInputStream())
+ if (!content) {
+ render restService.createErrorResponse("44","Zip file is not valid!")
+ } else {
+ if (session.test) session.test = null
+ if (session?.tests?.containsKey("0")) session.tests.remove("0")
+ if (session?.renderer?.containsKey("internal")) session.renderer.remove("internal")
+ def assessmentTestPath
+ try
+ {
+ assessmentTestPath = content.getTest()
+ }
+ catch(ContentPackageException e)
+ {
+ File atfile = new File(content.getDestination(), "___assessmentTest___.xml")
+
+ AssessmentTest test = new AssessmentTest();
+ test.setIdentifier("default_test_identifier")
+ test.setTitle(" ")
+ TestPart tp = new TestPart(test);
+ tp.setIdentifier("default_part_identifier")
+ tp.setNavigationMode(NavigationMode.NONLINEAR)
+ tp.setSubmissionMode(SubmissionMode.SIMULTANEOUS)
+ test.getTestParts().add(tp);
+ AssessmentSection section = new AssessmentSection(tp);
+ section.setIdentifier("default_section_identifier")
+ section.setTitle("Section 1")
+ section.setVisible(false)
+ tp.getAssessmentSections().add(section);
+ content.getItems().eachWithIndex
+ {
+ item, i ->
+ AssessmentItemRef air = new AssessmentItemRef(section);
+ air.setIdentifier("item$i")
+ section.getChildren().add(air);
+
+ String itm = item.getAbsolutePath().substring(item.getAbsolutePath().lastIndexOf(File.separator)+1)
+
+ air.setHref(itm)
+ }
+ atfile << test.toXmlString()
+ //System.out.println(test.validate());
+ assessmentTestPath = atfile
+ }
+
+ params.remove("uploadedContent")
+ session.test = new Test(testFolderPath:"internal")
+ session.test.getAssessmentTestPath = {return assessmentTestPath}
+
+ redirect(action:"playTest", params:params, id:0)
+ }
+ } else if (type.contains("xml")) {
+ XmlNode node = applicationService.handleXml(params.uploadedContent.getInputStream())
+ if (!node) {
+ render restService.createErrorResponse("44","xmlNode failed!") //change it to xml later
+ return
+ } else {
+
+ ValidationResult report = node.validate()
+ boolean canContinue = false
+
+ if (node instanceof AssessmentItem && report.getErrors().size() == 0)
+ {
+ if (session.item) session.item = null
+ if (session?.items?.containsKey("0")) session.items.remove("0")
+ if (session?.renderer?.containsKey("internal")) session.renderer.remove("internal")
+
+ def assessmentItem = node
+
+ params.remove("uploadedContent")
+ session.item = new Item(itemFolderPath:"internal")
+ session.item.getAssessmentItem = {return assessmentItem}
+ redirect(action:"playItem", params:params,id:"0")
+ }
+ else
+ {
+ render restService.createErrorResponse("44","Some of the tags in xml is not valid!")
+ return
+ }
+ }
+ } else {
+ flash.message=g.message(code:"file.wrongtype", args:[type])
+ render(view:"uploadError")
+ }
+ }
+
+ def playItem = {
+
+ if (!params.id || params.id != "0")
+ {
+ render restService.createErrorResponse("44","Id is not correct")
+ return
+ }
+ def item = session.item
+ if (!session.renderer) session.renderer = [:];
+ if (!session.renderer[item.itemFolderPath]) {
+ ExtensibleXSLTSource assessmentSource = new ExtensibleXSLTSource();
+ if (request.getHeader('User-Agent').contains("Mozilla")
+ && !request.getHeader('User-Agent').contains("Safari")
+ && !request.getHeader('User-Agent').contains("MSIE")
+ && !request.getHeader('User-Agent').contains("Opera"))
+ {
+ assessmentSource.getExtensionIncludes().add("/org/qtitools/qti/rendering/mathml/mathmlc2p.xsl"); // for FF
+ }
+ assessmentSource.getExtensionIncludes().addAll(Renderer.DEFAULT_ASSESSMENT_XSLT_SOURCE.getExtensionIncludes());
+
+ ExtensibleXSLTSource itemSource = new ExtensibleXSLTSource();
+ itemSource.getExtensionIncludes().add("/org/qtitools/mathassess/MathInteraction.xsl");
+ itemSource.getExtensionIncludes().addAll(Renderer.DEFAULT_ITEM_XSLT_SOURCE.getExtensionIncludes());
+
+ session.renderer[item.itemFolderPath] = new Renderer("../../content/"+item.itemFolderPath+"/",
+ itemSource.getSource(),
+ assessmentSource.getSource()
+ );
+ }
+
+ if (!session.items) session.items = [:]
+
+ boolean isResponded = false
+ AssessmentItem assessmentItem
+ def validation = null;
+ if (!session.items[params.id]) {
+ assessmentItem = item.getAssessmentItem();
+ assessmentItem.initialize(null);
+
+ session.items[params.id] = assessmentItem
+
+ if(assessmentItem.validate().getAllItems().size() != 0) {
+ validation = assessmentItem.validate().toString()
+ }
+
+ assessmentItem.setTimeRecord(new SimpleItemTimeRecord());
+
+ session.rec = assessmentItem.getTimeRecord()
+ } else {
+ assessmentItem = session.items[params.id]
+
+ assessmentItem.setResponses(utilitiesService.convertMap(request.getParameterMap(), params));
+ assessmentItem.processResponses();
+ println "Response:"+assessmentItem.getResponseValues()
+ println "Outcome:"+assessmentItem.getOutcomeValues()
+ isResponded = true;
+
+ if(assessmentItem.validate().getAllItems().size() != 0) {
+ validation = assessmentItem.validate().toString()
+ }
+ }
+
+ Map itemParams = new HashMap();
+ itemParams.put("showInternalState", true);
+ itemParams.put("displayTitle", true);
+ itemParams.put("appletCodebase", grailsApplication.config.server.url.toString()+"/applets");
+ if (validation) itemParams.put("validation", validation)
+
+ Map assessmentParams = new HashMap();
+ assessmentParams.put("useAssessmentStylesheet", false)
+
+ String text = session.renderer[item.itemFolderPath].renderPage(assessmentItem, isResponded, assessmentItem.getResponseValues(), assessmentParams, itemParams)
+ try
+ {
+ String xml = restService.createNormalResponse(text, assessmentItem, isResponded, params)
+
+ render xml
+ }
+ catch(RestApiException raex)
+ {
+ render restService.createErrorResponse("44","I caught an error!")
+ }
+ }
+
+ def playTest = {
+
+ if (!params.id || params.id != "0")
+ {
+ render restService.createErrorResponse("44","Id is not correct")
+ return
+ }
+
+ if(!params.actionUrl)
+ {
+ render restService.createErrorResponse("44","actionUrl is missing!")
+ return
+ }
+ //no active test
+ if (params.containsKey("report"))
+ {
+ redirect(action:report, id:params.id) //show report
+ return
+ }
+
+ if (params.containsKey("exit"))
+ {
+ reset(params)
+ String xml = restService.createExitResponse("You exit.").toString()
+ println "exit:"+xml
+ render xml
+ return
+ }
+
+ String text = testService.getRenderedPage(params, request)//.getBytes("UTF-8");
+ TestCoordinator coordinator = session.tests[params.id]
+ if(coordinator != null)
+ {
+ if(coordinator.getTestController().isTestComplete())
+ {
+ def xml = restService.createFinishedResponse(text,session.tests[params.id].getReport(),params)
+ println "finish:"+xml.toString()
+ render xml.toString()
+ return
+ }
+ }
+
+ try
+ {
+ //String xml = restService.createResponse(text, assessmentItem, isResponded, params)
+ def xml = restService.createNormalResponse(text, null, false, params)
+ println "xml:"+xml.toString()
+ render xml.toString()
+ return
+ }
+ catch(RestApiException raex)
+ {
+ render restService.createErrorResponse("44","I caught an error!")
+ return
+ }
+ }
+
+ def report = {
+ if (session?.tests && session?.tests[params.id])
+ {
+ //render session.tests[params.id].getReport()
+ String xml = restService.createReportResponse(session.tests[params.id].getReport())
+ render xml
+ return
+ }
+ else
+ {
+ render restService.createErrorResponse("44","cannot view report of test that hasn't been taken")
+ return
+ }
+ }
+
+ def reset =
+ {
+ if (!params.id) {
+ if (session.renderer) session.renderer.clear()
+ if (session.tests) session.tests.clear()
+ } else {
+ def test = Test.get( params.id )
+ if (test)
+ {
+ if (session.tests) session.tests.remove(params.id)
+ if (session.renderer) session.renderer.remove(test.testFolderPath)
+ }
+ }
+ }
+}
Added: trunk/projects/QTIEngine/grails-app/services/RestService.groovy
===================================================================
--- trunk/projects/QTIEngine/grails-app/services/RestService.groovy (rev 0)
+++ trunk/projects/QTIEngine/grails-app/services/RestService.groovy 2010-04-09 17:09:10 UTC (rev 2447)
@@ -0,0 +1,236 @@
+import grails.converters.*;
+import groovy.xml.*;
+import org.qtitools.qtiengine.RestApiException;
+import org.qtitools.qti.node.item.AssessmentItem;
+
+import org.xml.sax.SAXException
+
+import javax.xml.parsers.ParserConfigurationException;
+
+class RestService {
+
+ boolean transactional = true
+ static scope = "session"
+
+ def grailsApplication
+
+ /*status:
+ * 0: test is on the run
+ * 1: test finished
+ * 2: text exit
+ * 44: something wrong
+ * <root>
+ * <status>0</status>
+ * <page>
+ * xhtml code
+ * </page>
+ * <vars>
+ * <ResponseVars>
+ * <param identifier="RESPONSE">ChoiceB</param>
+ * <param identifier="numAttempts">1</param>
+ * ...
+ * </ResponseVars>
+ * <OutcomeVars>
+ * <param identifier="SCORE">1.0</param>
+ * ....
+ * </OutcomeVars>
+ * </vars>
+ * <error>
+ * <message>some messages</message>
+ * </error>
+ * </root>
+ */
+ def createNormalResponse(String xhtml, AssessmentItem item, boolean isResponded, params)
+ {
+ def builder = new StreamingMarkupBuilder()
+ def xml = localize(xhtml, params.actionUrl, params.imagesUrl)
+
+ def response = builder.bind{
+ mkp.xmlDeclaration()
+ root{
+ status "0"
+ page{
+ mkp.declareNamespace("": "http://www.w3.org/1999/xhtml")
+ mkp.yield xml
+ }
+ if(isResponded && item!=null)
+ {
+ vars
+ {
+ ResponseVars
+ {
+ item.getResponseValues().each{k,v->
+ param identifier:k, v.toString()
+ }
+ }
+ OutcomeVars
+ {
+ item.getOutcomeValues().each{k,v ->
+ param identifier:k, v.toString()
+ }
+ }
+ }
+ }
+ }
+ }
+ println "isResponded:"+isResponded
+ println "response:"+response
+ return response
+ }
+
+ def localize(String xhtml, String actionUrl, String imagesUrl) throws RestApiException, ParserConfigurationException, SAXException
+ {
+ def xmlSlurper = new XmlSlurper()
+ xmlSlurper.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false)
+ def xml = xmlSlurper.parseText(xhtml)
+
+ //change script src
+ xml.head.script.each {
+ it.@src = it...@sr...().replaceAll("\\.\\./\\.\\.", grailsApplication.config.server.url.toString())
+ }
+
+ //change link href
+ xml.head.link.each {
+ it.@href = it...@hr...().replaceAll("\\.\\./\\.\\.", grailsApplication.config.server.url.toString())
+ }
+
+ //We may also need javascript later
+
+ //change image url
+ if(imagesUrl)
+ {
+ xml.body.'**'.findAll{it.name() == "img"}.each {
+ println "img"
+ String oldUrl = it...@sr...()
+ String[] paths = oldUrl.split("/")
+ String filename = paths[paths.length-1]
+ it.@src=imagesUrl+filename
+ }
+
+ //Images in java applet
+ xml.body.'**'.findAll{it.name()=="applet"}.each{applet->
+ applet.'**'.findAll{it.name() == "param"}.each{param->
+ //println "param.@value:"+pa...@va...()
+ if(pa...@va...().contains(".."))
+ {
+ String oldUrl = pa...@va...()
+ String[] paths = oldUrl.split("/")
+ String filename = paths[paths.length-1]
+ param.@value=imagesUrl+filename
+ println "applet img"
+ }
+ }
+ }
+ }
+ else
+ {
+ xml.body.'**'.findAll{it.name() == "img"}.each {
+ println "img"
+ it.@sr...@sr...().replaceAll("\\.\\./\\.\\.", grailsApplication.config.server.url.toString())
+ }
+ }
+
+ //change form action
+ xml.body.'**'.findAll{it.name() == "form"}.each{
+ println "form:"+it.name
+ it.@action = actionUrl
+ }
+
+ //change java applet codedbase
+ xml.body.'**'.findAll{it.name() == "applet"}.each{ applet->
+ applet.@codebase = ap...@co...().replaceAll("\\.\\./\\.\\.", grailsApplication.config.server.url.toString())
+ applet.'**'.findAll{it.name() == "param"}.each{ param->
+ //replace .. with server url, this might now be correct in some cases
+ param.@value = pa...@va...().replaceAll("\\.\\.", grailsApplication.config.server.url.toString())
+ }
+ }
+ return xml
+ }
+
+ //status:
+ //0: test is on the run
+ //1: test finished
+ //2: text exit
+ //3: send report
+ //44: something wrong
+ def createErrorResponse(String code, String errMessage)
+ {
+ def builder = new StreamingMarkupBuilder()
+ def response = builder.bind{
+ mkp.xmlDeclaration()
+ root{
+ status code
+ error
+ {
+ message errMessage
+ }
+ }
+ }
+ return response
+ }
+
+ def createFinishedResponse(String finishMessage, String reportStr,params)
+ {
+ def builder = new StreamingMarkupBuilder()
+ def xml = localize(finishMessage, params.actionUrl, params.imagesUrl)
+
+ def xmlSlurper = new XmlSlurper()
+ def reportXml = xmlSlurper.parseText(reportStr)
+
+ def response = builder.bind{
+ mkp.xmlDeclaration()
+ root{
+ status "1"
+ finished
+ {
+ mkp.declareNamespace("": "http://www.w3.org/1999/xhtml")
+ mkp.yield xml
+ }
+ report
+ {
+ mkp.declareNamespace("": "http://www.imsglobal.org/xsd/imsqti_v2p1")
+ mkp.yield reportXml
+ }
+ }
+ }
+ return response
+ }
+
+ def createExitResponse(String exitMessage)
+ {
+ def builder = new StreamingMarkupBuilder()
+ def response = builder.bind{
+ mkp.xmlDeclaration()
+ root{
+ status "2"
+ exit
+ {
+ message exitMessage
+ }
+ }
+ }
+ return response
+ }
+
+ def createReportResponse(String reportStr)
+ {
+ println "report:"
+ def xmlSlurper = new XmlSlurper()
+ def xml = xmlSlurper.parseText(reportStr)
+
+ def builder = new StreamingMarkupBuilder()
+ def response = builder.bind{
+ mkp.xmlDeclaration()
+ root{
+ status "3"
+ report
+ {
+ mkp.declareNamespace("": "http://www.imsglobal.org/xsd/imsqti_v2p1")
+ mkp.yield xml
+ }
+ }
+ }
+ println "report:"+response.toString();
+ return response
+ }
+}
Added: trunk/projects/QTIEngine/src/groovy/org/qtitools/qtiengine/RestApiException.groovy
===================================================================
--- trunk/projects/QTIEngine/src/groovy/org/qtitools/qtiengine/RestApiException.groovy (rev 0)
+++ trunk/projects/QTIEngine/src/groovy/org/qtitools/qtiengine/RestApiException.groovy 2010-04-09 17:09:10 UTC (rev 2447)
@@ -0,0 +1,16 @@
+/**
+ *
+ */
+package org.qtitools.qtiengine
+
+/**
+ * @author pei
+ *
+ */
+public class RestApiException extends RuntimeException
+{
+ public RestApiException(String message)
+ {
+ super(message);
+ }
+}
Added: trunk/projects/QTIEngine/test/integration/RestControllerTests.groovy
===================================================================
--- trunk/projects/QTIEngine/test/integration/RestControllerTests.groovy (rev 0)
+++ trunk/projects/QTIEngine/test/integration/RestControllerTests.groovy 2010-04-09 17:09:10 UTC (rev 2447)
@@ -0,0 +1,6 @@
+class RestControllerTests extends GroovyTestCase {
+
+ void testSomething() {
+
+ }
+}
Added: trunk/projects/QTIEngine/test/integration/RestServiceTests.groovy
===================================================================
--- trunk/projects/QTIEngine/test/integration/RestServiceTests.groovy (rev 0)
+++ trunk/projects/QTIEngine/test/integration/RestServiceTests.groovy 2010-04-09 17:09:10 UTC (rev 2447)
@@ -0,0 +1,6 @@
+class RestServiceTests extends GroovyTestCase {
+
+ void testSomething() {
+
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|