Register

How to redirect Viewlet statistics to your own server

General Tips & Tricks
Site Admin
User avatar
Posts: 223
Joined: Fri May 26, 2006 1:51 pm
Location: Rochester, NY

How to redirect Viewlet statistics to your own server

Postby Andrew » Fri May 04, 2007 1:38 pm

(Note: For ViewletBuilder6.2.8 or ViewletQuiz 3.2.8, please skip to the last posting in this topic)

This post describes how to capture the reporting results from a Viewlet and redirect it to your server using ViewletQuiz 2 or 3 and ViewletBuilder5 or 6. This allows you to have full control over the collection and analysis of your Viewlets.

If a Viewlet was published with reporting set to “Qarbon Email Reporting System”, it will send XML data to our server that describes the user’s interactions. To redirect the results to your sever, you will need to edit some javascript and specify the server that will process the data.

The difficult part is writing the backend program to process the XML and write it to your database. This program could be written in Java, PHP, Python, Perl or any other language used for processing web pages.

Redirect Results to your Server:

Publish your Viewlet to a local folder. My Viewlets for example.

On the reporting options page of the publishing wizard, select Qarbon Email Reporting System.

When the publish wizard completes, click the Browse button to open up the folder where your Viewlet was published.

Open the xxx_viewlet_swf.html file with notepad (Where xxx is the name of your Viewlet)

You will see the following name=value pair in a block of javascript that loads the flash file.

rp=http://services.qarbon.com/client/statsmailer

Replace the url to the Qarbon statsmailer program to a URL to a program on your server that can process the XML results.

For example it will look something like this:


<script language="JavaScript">
<!--
var flashTag = new FlashTag("emalreporttest.swf", "644", "542");
flashTag.setId("emalreporttest"); flashTag.setFlashvars("jsfgid="+jsfgid+"&__variables__="+getParameters()+"&
rp=http://www.mycompany.com/servlet/processviewlet");
flashTag.write(document);
//-->
</script>


You may want to also pass a student id along with this Viewlet. For example suppose you have an authenticated website from which the Viewlets are served. You may want to pass the authenticated user’s id along with their results. Simply add the argument student_id= with the student id to your URL. It will then be passed in the XML data.

For example: rp=http://www.mycompany.com/servlet/processviewlet&student_id=1234

Alternatively, if you compiled the Viewlet with the "Require Viewers to Login" checkbox selected in the publishing wizard, then the username entered here will be passed in the XML data.

Process the Results on your Server:

The Viewlet will send the results, for each user, as a series of XML HTTP posts to the specified server. It sends a summary XML report at the beginning and one for each question or interactive zone in the Viewlet. Breaking the results into a series of reports rather than a single report allows us to capture partial results from a user. With surveys it is not uncommon for a user to answer a few questions and then give up and close the browser. This information can be very useful to capture.

The series of XML reports makes the processing the results a little more challenging. We recommend using a cookie to group all the reports and then process it when the last report is received.

Each XML report has root tag of <report>

Here is a sample of what the first report looks like. It is identified by having a <begin> tag. Comments added.
Code: Select all
  <report>
  <!-- The begin tag lets you know this is the first report from a viewlet -->
  <begin
  user="andrew">  <!-- This is the user entered from the student_id param or if a login panel was enabled -->
 
      <!-- This section describes meta information about the Viewlet -->
      <content
        manifestVersion="2"
        id="-1"
        language="en"
        name="email-quiz-test.vie"
        author=""
        description=""
        title=""
        application="ViewletACE 2006"
        applicationVersion="1.0.0"
        width="852"
        height="542"
        slideCount="10"
        flash="6"
        passingGrade="65"
        timeLimit="0"
        htmlFile="emailquiztest_viewlet_swf.html"
        swfFile="emailquiztest.swf">

         <!-- The email address to send the response back to -->
         <emailTo value="awbranch@qarbon.com" />

         <!-- An example of a short answer question with a text field -->         
         <shortAnswerQuestion
            id="1"
            name="Enter Question Here"
            points="1"
            timeLimit="0"
            attempts="3"
            survey="false"
            question="Enter Question Here">
            <textField id="3" caseSensitive="false">
               <answer id="1" value="aaa" />
            </textField>
         </shortAnswerQuestion>
         
         <!-- An example of a short answer question with a combo box -->         
         <shortAnswerQuestion
            id="9"
            name="Enter Question Here"
            points="1"
            timeLimit="0"
            attempts="3"
            survey="false"
            question="Enter Question Here">
            <comboBox id="11">
               <answer id="1" value="aaa" correct="false" />
               <answer id="2" value="bbb" correct="true" />
               <answer id="3" value="ccc" correct="false" />
            </comboBox>
         </shortAnswerQuestion>
         
         
         <!-- An example of a short answer question with a rating -->         
         <shortAnswerQuestion
            id="17"
            name="Enter Question Here"
            points="1"
            timeLimit="0"
            attempts="3"
            survey="false"
            question="Enter Question Here">
            <rating id="19" maximum="5" correct="3" />
         </shortAnswerQuestion>
         
         <!-- An example of multiple choice question with a radio button -->         
         <multipleChoiceQuestion
            id="25"
            name="Enter Question Here"
            points="1"
            timeLimit="0"
            attempts="3"
            survey="false"
            question="Enter Question Here">
            <radioButton id="27" correct="false" value="Choice 1" />
            <radioButton id="29" correct="true" value="Choice 2" />
            <radioButton id="31" correct="false" value="Choice 3" />
         </multipleChoiceQuestion>
         
         <!-- An example of multiple choice question with a check box -->         
         <multipleChoiceQuestion
            id="38"
            name="Enter Question Here"
            points="1"
            timeLimit="0"
            attempts="3"
            survey="false"
            question="Enter Question Here">
            <checkBox id="40" correct="false" value="Choice 1" />
            <checkBox id="42" correct="true" value="Choice 2" />
            <checkBox id="44" correct="false" value="Choice 3" />
         </multipleChoiceQuestion>
         
         <!-- An example of multiple choice question with text fields -->         
         <multipleChoiceQuestion
            id="51"
            name="Enter Question Here"
            points="1"
            timeLimit="0"
            attempts="3"
            survey="false"
            question="Enter Question Here">
            <textField id="53" caseSensitive="false" value="Choice 1">
               <answer id="1" value="aaa" />
            </textField>
            <textField id="55" caseSensitive="false" value="Choice 2">
               <answer id="1" value="aaa" />
            </textField>
            <textField id="57" caseSensitive="false" value="Choice 3">
               <answer id="1" value="aaa" />
            </textField>
         </multipleChoiceQuestion>
         
         <!-- An example of multiple choice question with combo boxes -->         
         <multipleChoiceQuestion
            id="64"
            name="Enter Question Here"
            points="1"
            timeLimit="0"
            attempts="3"
            survey="false"
            question="Enter Question Here">
            <comboBox id="66" value="Choice 1">
               <answer id="1" value="aaa" correct="false" />
               <answer id="2" value="bbb" correct="true" />
               <answer id="3" value="ccc" correct="false" />
            </comboBox>
            <comboBox id="68" value="Choice 2">
               <answer id="1" value="aaa" correct="false" />
               <answer id="2" value="bbb" correct="true" />
               <answer id="3" value="ccc" correct="false" />
            </comboBox>
            <comboBox id="70" value="Choice 3">
               <answer id="1" value="aaa" correct="false" />
               <answer id="2" value="bbb" correct="true" />
               <answer id="3" value="ccc" correct="false" />
            </comboBox>
         </multipleChoiceQuestion>

         <!-- An example of multiple choice question with ratings -->         
         <multipleChoiceQuestion
            id="77"
            name="Enter Question Here"
            points="1"
            timeLimit="0"
            attempts="3"
            survey="false"
            question="Enter Question Here">
            <rating id="79" maximum="5" correct="3" value="Choice 1" />
            <rating id="81" maximum="5" correct="3" value="Choice 2" />
            <rating id="83" maximum="5" correct="3" value="Choice 3" />
         </multipleChoiceQuestion>
         
         <!-- An example of multiple choice question - true false -->         
         <multipleChoiceQuestion
            id="90"
            name="Enter Question Here"
            points="1"
            timeLimit="0"
            attempts="3"
            survey="false"
            question="Enter Question Here">
            <radioButton id="92" correct="true" value="True" />
            <radioButton id="94" correct="false" value="False" />
         </multipleChoiceQuestion>
 
         <!-- An example of a likert question -->         
         <likertQuestion
            id="101"
            name="Enter Question Here"
            points="1"
            timeLimit="0"
            attempts="3"
            survey="false"
            question="Enter Question Here">
            <column id="1" value="Strongly Disagree" />
            <column id="2" value="Disagree" />
            <column id="3" value="Undecided" />
            <column id="4" value="Agree" />
            <column id="5" value="Strongly Agree" />
            <row id="1" value="Choice 1">
               <radioButton id="109" correct="false" />
               <radioButton id="110" correct="false" />
               <radioButton id="111" correct="true" />
               <radioButton id="112" correct="false" />
               <radioButton id="113" correct="false" />
            </row>
            <row id="2" value="Choice 2">
               <radioButton id="115" correct="false" />
               <radioButton id="116" correct="false" />
               <radioButton id="117" correct="true" />
               <radioButton id="118" correct="false" />
               <radioButton id="119" correct="false" />
            </row>
            <row id="3" value="Choice 3">
               <radioButton id="121" correct="false" />
               <radioButton id="122" correct="false" />
               <radioButton id="123" correct="true" />
               <radioButton id="124" correct="false" />
               <radioButton id="125" correct="false" />
            </row>
         </likertQuestion>
      </content>
  </begin>
 </report>


After the begin tag, reports come for each question answered. They look like this.

Code: Select all
 <report>
  <question id="1" correct="true" attempts="2" time="10000" timedOut="false" survey="false" points="1">
      <answer status="incorrect">
          <textField id="3" value="fff" correct="false" />
      </answer>
      <answer status="correct">
          <textField id="3" value="aaa" correct="true" />
      </answer>
  </question>
 </report>

 <report>
  <question id="9" correct="true" attempts="1" time="10000" timedOut="false" survey="false" points="1">
      <answer status="correct">
          <comboBox id="11" correct="true">
              <answer correct="true" answer="bbb" index="1" />
          </comboBox>
      </answer>
  </question>
 </report>

 <report>
  <question id="17" correct="true" attempts="2" time="10000" timedOut="false" survey="false" points="1">
      <answer status="incorrect">
          <rating id="19" value="2" correct="false" />
      </answer>
      <answer status="correct">
          <rating id="19" value="3" correct="true" />
      </answer>
  </question>
 </report>

 <report>
  <question id="25" correct="true" attempts="2" time="10000" timedOut="false" survey="false" points="1">
      <answer status="incorrect">
          <radioButton id="27" value="true" correct="false" />
          <radioButton id="29" value="false" correct="false" />
          <radioButton id="31" value="false" correct="false" />
      </answer>
      <answer status="correct">
          <radioButton id="27" value="false" correct="false" />
          <radioButton id="29" value="true" correct="true" />
          <radioButton id="31" value="false" correct="false" />
      </answer>
  </question>
 </report>

 <report>
  <question id="38" correct="true" attempts="1" time="10000" timedOut="false" survey="false" points="1">
      <answer status="correct">
          <checkBox id="40" value="false" correct="false" />
          <checkBox id="42" value="true" correct="true" />
          <checkBox id="44" value="false" correct="false" />
      </answer>
  </question>
 </report>

 <report>
  <question id="51" correct="true" attempts="1" time="10000" timedOut="false" survey="false" points="1">
      <answer status="correct">
          <textField id="53" value="aaa" correct="true" />
          <textField id="55" value="aaa" correct="true" />
          <textField id="57" value="aaa" correct="true" />
      </answer>
  </question>
 </report>

 <report>
  <question id="64" correct="true" attempts="1" time="10000" timedOut="false" survey="false" points="1">
      <answer status="correct">
          <comboBox id="66" correct="true">
              <answer correct="true" index="1" />
          </comboBox>
          <comboBox id="68" correct="true">
              <answer correct="true" index="1" />
          </comboBox>
          <comboBox id="70" correct="true">
              <answer correct="true" index="1" />
          </comboBox>
      </answer>
  </question>
 </report>

 <report>
  <question id="77" correct="true" attempts="1" time="10000" timedOut="false" survey="false" points="1">
      <answer status="correct">
          <rating id="79" value="3" correct="true" />
          <rating id="81" value="3" correct="true" />
          <rating id="83" value="3" correct="true" />
      </answer>
  </question>
 </report>

 <report>
  <question id="90" correct="true" attempts="1" time="10000" timedOut="false" survey="false" points="1">
      <answer status="correct">
          <radioButton id="92" value="true" correct="true" />
          <radioButton id="94" value="false" correct="true" />
      </answer>
  </question>
 </report>


The last report has an additional <end/> tag to notify that the viewlet has ended. It also provides the total time, completed and a flag if they timed out.

Code: Select all
 <report>
  <question id="101" correct="true" attempts="1" time="10000" timedOut="false" survey="false" points="1">
      <answer status="correct">
           <radioButton id="109" value="false" correct="true" />
           <radioButton id="110" value="false" correct="true" />
           <radioButton id="111" value="true" correct="true" />
           <radioButton id="112" value="false" correct="true" />
           <radioButton id="113" value="false" correct="true" />
 
           <radioButton id="115" value="false" correct="true" />
           <radioButton id="116" value="false" correct="true" />
           <radioButton id="117" value="true"  correct="true" />
           <radioButton id="118" value="false" correct="true" />
           <radioButton id="119" value="false" correct="true" />
 
           <radioButton id="121" value="false" correct="true" />
           <radioButton id="122" value="false" correct="true" />
           <radioButton id="123" value="true"  correct="true" />
           <radioButton id="124" value="false" correct="true" />
           <radioButton id="125" value="false" correct="true" />
 
      </answer>
  </question>
  <end time="time" completed="true" timedOut="false" />
 </report>


Sample Code

Here is some sample Java Servlet code that will collect the XML reports from a Viewlet into an array of XML documents.

Code: Select all
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.Document;
import org.jdom.input.SAXBuilder;

import com.qarbon.bristol.util.QStringUtilities;

public class ViewletStatsServlet extends HttpServlet
{
    private final Log log = LogFactory.getLog(ViewletStatsServlet.class);
   
    protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException
    {
        // Read in the message sent from the client.
        // This is an XML file submitted from a Viewlet.
        // Need to do the parsing here, rather than calling request.getParameters
        // because we want to read the stream as a single blob of text (for xml parsing)

        // Get all the data sent. This is a blob of XML posted from a Viewlet
        BufferedReader in = new BufferedReader(request.getReader());
        StringBuffer buf = new StringBuffer();
        String line = in.readLine();
        while(line != null)
        {
            buf.append(line);
            buf.append("\n");
            line = in.readLine();
        }
       
        String xml = buf.toString();

        Document report;
       
        try
        {
            StringReader xin = new StringReader(xml);
            SAXBuilder builder = new SAXBuilder();
            report = builder.build(xin);
        }
        catch (Exception e)
        {
            log.error("Error Processing Report: ", e);
            return;
        }

        boolean firstReport = report.getRootElement().getChild("begin") != null;
        boolean lastReport = report.getRootElement().getChild("end") != null;

        HttpSession session = request.getSession();
       
        if(firstReport)
            session.removeAttribute("reportCount");
       
        // Stuff the report into a session variable until the end report is reached.
        int reportCount = QStringUtilities.parseInt((String) session.getAttribute("reportCount"), 0);
        session.setAttribute("report" + reportCount, report);
        reportCount++;
        session.setAttribute("reportCount", String.valueOf(reportCount));

        if(lastReport)
        {
            // Gather all the reports
            ArrayList<Document> reports = new ArrayList<Document>();
            for (int i = 0; i < reportCount; i++)
                reports.add((Document) session.getAttribute("report" + i));
   
            // Clear the session
            if(!session.isNew())
                session.invalidate();
   
            // Process the reports
            processReports(reports);
        }
   
        // Return response
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<html><body><head>");
        out.println("<title>");
        out.println("Processed Report");
        out.println("</title>");
        out.println("</head>");
        out.println("<body><pre>");
        out.println("Processed Report");
        out.println("<pre></body></html>");
    }

    /**
     * This methods job is to tally up all the xml blobs sent from the user.
     * @param reports
     */
    private void processReports(ArrayList<Document> reports)
    {
        // TODO:
    }
   
}
Andrew Branch

Site Admin
User avatar
Posts: 223
Joined: Fri May 26, 2006 1:51 pm
Location: Rochester, NY

Re: How to redirect Viewlet statistics to your own server

Postby Andrew » Fri May 21, 2010 2:10 pm

This has been updated for ViewletBuidler 6.2.8 and above. Please see our wiki for details:
http://fuz.qarbon.com/default.php?W150
Andrew Branch

Return to FAQs - ViewletQuiz4 (and prior versions)

Who is online

Users browsing this forum: No registered users and 1 guest