Coverage Report - fr.paris.lutece.plugins.quiz.web.QuizApp
 
Classes in this File Line Coverage Branch Coverage Complexity
QuizApp
0 %
0/193
0 %
0/80
4,538
 
 1  
 /*
 2  
  * Copyright (c) 2002-2014, Mairie de Paris
 3  
  * All rights reserved.
 4  
  *
 5  
  * Redistribution and use in source and binary forms, with or without
 6  
  * modification, are permitted provided that the following conditions
 7  
  * are met:
 8  
  *
 9  
  *  1. Redistributions of source code must retain the above copyright notice
 10  
  *     and the following disclaimer.
 11  
  *
 12  
  *  2. Redistributions in binary form must reproduce the above copyright notice
 13  
  *     and the following disclaimer in the documentation and/or other materials
 14  
  *     provided with the distribution.
 15  
  *
 16  
  *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
 17  
  *     contributors may be used to endorse or promote products derived from
 18  
  *     this software without specific prior written permission.
 19  
  *
 20  
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 21  
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 22  
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 23  
  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
 24  
  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 25  
  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 26  
  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 27  
  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 28  
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 29  
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 30  
  * POSSIBILITY OF SUCH DAMAGE.
 31  
  *
 32  
  * License 1.0
 33  
  */
 34  
 package fr.paris.lutece.plugins.quiz.web;
 35  
 
 36  
 import fr.paris.lutece.plugins.quiz.business.QuestionGroup;
 37  
 import fr.paris.lutece.plugins.quiz.business.QuestionGroupHome;
 38  
 import fr.paris.lutece.plugins.quiz.business.Quiz;
 39  
 import fr.paris.lutece.plugins.quiz.business.images.QuizImage;
 40  
 import fr.paris.lutece.plugins.quiz.business.images.QuizImageHome;
 41  
 import fr.paris.lutece.plugins.quiz.service.QuizService;
 42  
 import fr.paris.lutece.portal.service.i18n.I18nService;
 43  
 import fr.paris.lutece.portal.service.message.SiteMessageException;
 44  
 import fr.paris.lutece.portal.service.plugin.Plugin;
 45  
 import fr.paris.lutece.portal.service.plugin.PluginService;
 46  
 import fr.paris.lutece.portal.service.spring.SpringContextService;
 47  
 import fr.paris.lutece.portal.service.template.AppTemplateService;
 48  
 import fr.paris.lutece.portal.service.util.AppLogService;
 49  
 import fr.paris.lutece.portal.web.xpages.XPage;
 50  
 import fr.paris.lutece.portal.web.xpages.XPageApplication;
 51  
 import fr.paris.lutece.util.html.HtmlTemplate;
 52  
 
 53  
 import java.io.IOException;
 54  
 import java.io.OutputStream;
 55  
 import java.text.MessageFormat;
 56  
 import java.util.HashMap;
 57  
 import java.util.Locale;
 58  
 import java.util.Map;
 59  
 
 60  
 import javax.servlet.http.HttpServletRequest;
 61  
 import javax.servlet.http.HttpServletResponse;
 62  
 import javax.servlet.http.HttpSession;
 63  
 
 64  
 import org.apache.commons.lang.StringUtils;
 65  
 
 66  
 
 67  
 /**
 68  
  * This class manages Quiz page.
 69  
  */
 70  0
 public class QuizApp implements XPageApplication
 71  
 {
 72  
     private static final String TEMPLATE_QUIZ_LIST = "skin/plugins/quiz/quiz_list.html";
 73  
     private static final String TEMPLATE_QUIZ_RESULTS = "skin/plugins/quiz/quiz_results.html";
 74  
     private static final String TEMPLATE_QUIZ_RESULTS_STEP = "skin/plugins/quiz/quiz_results_step.html";
 75  
     private static final String TEMPLATE_QUIZ_ERROR = "skin/plugins/quiz/quiz_error.html";
 76  
     private static final String TEMPLATE_QUESTIONS_LIST = "skin/plugins/quiz/quiz.html";
 77  
     private static final String TEMPLATE_QUESTIONS_LIST_STEP = "skin/plugins/quiz/quiz_step.html";
 78  
 
 79  
     private static final String PROPERTY_QUIZ_LIST_PAGE_PATH = "quiz.xpage.pageQuizListPath";
 80  
     private static final String PROPERTY_QUIZ_LIST_PAGE_TITLE = "quiz.xpage.pageQuizListTitle";
 81  
     private static final String PROPERTY_QUIZ_PAGE_PATH = "quiz.xpage.pageQuizPath";
 82  
     private static final String PROPERTY_QUIZ_PAGE_TITLE = "quiz.xpage.pageQuizTitle";
 83  
     private static final String PROPERTY_QUIZ_RESULTS_PAGE_PATH = "quiz.xpage.pageQuizResultsPath";
 84  
     private static final String PROPERTY_QUIZ_RESULTS_PAGE_TITLE = "quiz.xpage.pageQuizResultsTitle";
 85  
     private static final String PROPERTY_QUIZ_ERROR_PAGE_PATH = "quiz.xpage.pageQuizErrorPath";
 86  
     private static final String PROPERTY_QUIZ_ERROR_PAGE_TITLE = "quiz.xpage.pageQuizErrorTitle";
 87  
     private static final String PROPERTY_MSG_MANY_GOOD_ANSWERS = "quiz.message.results.manyGoodAnswers";
 88  
     private static final String PROPERTY_MSG_ONE_GOOD_ANSWER = "quiz.message.results.oneGoodAnswer";
 89  
     private static final String PROPERTY_MSG_NO_GOOD_ANSWER = "quiz.message.results.noGoodAnswer";
 90  
 
 91  
     private static final String PARAMETER_RESULTS = "results";
 92  
     private static final String PARAMETER_ID_QUIZ = "quiz_id";
 93  
     private static final String PARAMETER_OLD_STEP = "old_step";
 94  
     private static final String PARAMETER_ID_IMAGE = "id_image";
 95  
     private static final String ACTION_NEXT_STEP = "nextStep";
 96  
     private static final String ACTION_BACK_FROM_ERROR = "backFromError";
 97  
 
 98  
     private static final String SESSION_KEY_QUIZ_STEP = "quiz.savedQuizResult";
 99  
 
 100  
     private static final String MARK_ERROR = "error";
 101  
     private static final String MARK_ID_QUIZ = "quiz_id";
 102  
     private static final String MARK_HAS_NEXT_STEP = "hasNextStep";
 103  
     private static final String MARK_SCORE = "score";
 104  
     private static final String MARK_QUESTIONS_COUNT = "questions_count";
 105  
     private static final String MARK_SCORE_MESSAGE = "score_message";
 106  
     private static final String MARK_GROUP = "group";
 107  
     private static final String MARK_IS_LAST_GROUP = "is_last_group";
 108  
 
 109  0
     private QuizService _quizService = SpringContextService.getBean( QuizService.BEAN_QUIZ_SERVICE );
 110  
 
 111  
     /**
 112  
      * Do download a quiz image
 113  
      * @param request The request
 114  
      * @param response The response
 115  
      */
 116  
     public static void doDownloadQuizImage( HttpServletRequest request, HttpServletResponse response )
 117  
     {
 118  0
         String strIdImage = request.getParameter( PARAMETER_ID_IMAGE );
 119  0
         if ( StringUtils.isNotEmpty( strIdImage ) && StringUtils.isNumeric( strIdImage ) )
 120  
         {
 121  0
             OutputStream out = null;
 122  
             try
 123  
             {
 124  0
                 Plugin plugin = PluginService.getPlugin( QuizService.PLUGIN_NAME );
 125  0
                 int nIdImage = Integer.parseInt( strIdImage );
 126  0
                 byte[] bArrayResult = {};
 127  0
                 String strContentType = StringUtils.EMPTY;
 128  0
                 QuizImage quizImage = QuizImageHome.getImage( nIdImage, plugin );
 129  
 
 130  0
                 if ( quizImage != null && quizImage.getContent( ) != null )
 131  
                 {
 132  0
                     bArrayResult = quizImage.getContent( );
 133  0
                     strContentType = quizImage.getContentType( );
 134  
                 }
 135  
                 // Add Cache Control HTTP header
 136  0
                 response.setHeader( "Cache-Control", "no-cache" ); // HTTP 1.1
 137  0
                 response.setDateHeader( "Expires", 0 ); // HTTP 1.0
 138  0
                 response.setContentLength( bArrayResult.length );
 139  0
                 response.setContentType( strContentType );
 140  
 
 141  
                 // Write the resource content
 142  0
                 out = response.getOutputStream( );
 143  0
                 out.write( bArrayResult );
 144  
             }
 145  0
             catch ( IOException e )
 146  
             {
 147  0
                 AppLogService.error( e.getMessage( ), e );
 148  
             }
 149  
             finally
 150  
             {
 151  0
                 if ( out != null )
 152  
                 {
 153  
                     try
 154  
                     {
 155  0
                         out.flush( );
 156  0
                         out.close( );
 157  
                     }
 158  0
                     catch ( IOException e )
 159  
                     {
 160  0
                         AppLogService.error( e.getMessage( ), e );
 161  0
                     }
 162  
                 }
 163  
             }
 164  
         }
 165  0
     }
 166  
 
 167  
     /**
 168  
      * Returns the Quiz XPage content depending on the request parameters and
 169  
      * the current mode.
 170  
      * 
 171  
      * @param request The HTTP request.
 172  
      * @param nMode The current mode.
 173  
      * @param plugin The Plugin
 174  
      * @throws fr.paris.lutece.portal.service.message.SiteMessageException
 175  
      *             Message displayed if an exception occures
 176  
      * @return The page content.
 177  
      */
 178  
     @SuppressWarnings( "unchecked" )
 179  
     public XPage getPage( HttpServletRequest request, int nMode, Plugin plugin ) throws SiteMessageException
 180  
     {
 181  0
         String strIdQuiz = request.getParameter( PARAMETER_ID_QUIZ );
 182  0
         String strAction = request.getParameter( QuizService.PARAMETER_ACTION );
 183  0
         XPage page = null;
 184  
 
 185  0
         if ( StringUtils.isNotEmpty( strIdQuiz ) && StringUtils.isNumeric( strIdQuiz ) )
 186  
         {
 187  0
             int nIdQuiz = Integer.parseInt( strIdQuiz );
 188  
 
 189  0
             Quiz quiz = _quizService.findQuizById( nIdQuiz );
 190  0
             if ( !quiz.isEnabled( ) )
 191  
             {
 192  0
                 return getQuizList( request.getLocale( ) );
 193  
             }
 194  
 
 195  0
             if ( quiz.getDisplayStepByStep( ) )
 196  
             {
 197  
                 // We get the position of the old step
 198  0
                 String strOldStep = request.getParameter( PARAMETER_OLD_STEP );
 199  
                 int nOldStepId;
 200  0
                 if ( StringUtils.isNotEmpty( strOldStep ) && StringUtils.isNumeric( strOldStep ) )
 201  
                 {
 202  0
                     nOldStepId = Integer.parseInt( strOldStep );
 203  
                 }
 204  
                 else
 205  
                 {
 206  0
                     request.getSession( ).setAttribute( MARK_SCORE, 0 );
 207  0
                     request.getSession( ).setAttribute( MARK_QUESTIONS_COUNT, 0 );
 208  
 
 209  0
                     nOldStepId = 0;
 210  
                 }
 211  
 
 212  0
                 if ( !StringUtils.equals( ACTION_BACK_FROM_ERROR, strAction ) )
 213  
                 {
 214  0
                     if ( nOldStepId > 0 )
 215  
                     {
 216  
                         // We get responses of the user, and save them into the session
 217  0
                         Map<String, String[]> mapResponsesCurrentStep = null;
 218  0
                         if ( !StringUtils.equals( ACTION_NEXT_STEP, strAction ) )
 219  
                         {
 220  0
                             mapResponsesCurrentStep = saveAndValidateQuizAnswers( quiz, nOldStepId,
 221  0
                                     request.getParameterMap( ), request.getLocale( ), plugin, request.getSession( true ) );
 222  
                             // We check that the map does not contain errors
 223  0
                             String[] strError = mapResponsesCurrentStep.get( QuizService.KEY_ERROR );
 224  
 
 225  0
                             if ( strError != null && strError.length > 0 )
 226  
                             {
 227  0
                                 return getErrorPage( quiz.getIdQuiz( ), strError[0], nOldStepId, request.getLocale( ) );
 228  
                             }
 229  
                         }
 230  
 
 231  
                         // If we must display the result of the current step
 232  0
                         if ( quiz.getDisplayResultAfterEachStep( ) && StringUtils.equals( strAction, PARAMETER_RESULTS ) )
 233  
                         {
 234  0
                             page = getQuizStepResults( quiz, nOldStepId, request.getLocale( ), mapResponsesCurrentStep,
 235  0
                                     request.getSession( ), plugin );
 236  
                         }
 237  0
                     }
 238  
                     else
 239  
                     {
 240  
                         // this is the first step of the quiz, so we remove any answers to quiz made by the user
 241  0
                         resetUserAnswers( request.getSession( ) );
 242  
                     }
 243  
                 }
 244  
 
 245  0
                 if ( page == null )
 246  
                 {
 247  
                     // Otherwise, we display the next step
 248  0
                     page = getQuizNextStep( quiz, nOldStepId, request );
 249  0
                     if ( page == null )
 250  
                     {
 251  0
                         page = getQuizResults( quiz, request.getLocale( ), getUserAnswers( request.getSession( ) ),
 252  
                                 plugin );
 253  
                     }
 254  
                 }
 255  0
             }
 256  
             else
 257  
             {
 258  0
                 if ( strAction != null && strAction.equals( PARAMETER_RESULTS ) )
 259  
                 {
 260  0
                     page = getQuizResults( quiz, request.getLocale( ), request.getParameterMap( ), plugin );
 261  
                 }
 262  
                 else
 263  
                 {
 264  0
                     page = getQuizPage( nIdQuiz, request.getLocale( ) );
 265  
                 }
 266  
             }
 267  0
         }
 268  
         else
 269  
         {
 270  0
             page = getQuizList( request.getLocale( ) );
 271  
         }
 272  
 
 273  0
         return page;
 274  
     }
 275  
 
 276  
     /**
 277  
      * Get the quiz list
 278  
      * @param locale The locale
 279  
      * @return The XPage
 280  
      */
 281  
     protected XPage getQuizList( Locale locale )
 282  
     {
 283  0
         XPage page = new XPage( );
 284  0
         Map<String, Object> model = _quizService.getQuizList( );
 285  0
         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_QUIZ_LIST, locale, model );
 286  0
         page.setContent( template.getHtml( ) );
 287  0
         page.setTitle( I18nService.getLocalizedString( PROPERTY_QUIZ_LIST_PAGE_TITLE, locale ) );
 288  0
         page.setPathLabel( I18nService.getLocalizedString( PROPERTY_QUIZ_LIST_PAGE_PATH, locale ) );
 289  
 
 290  0
         return page;
 291  
     }
 292  
 
 293  
     /**
 294  
      * Gets the quiz page
 295  
      * @param nQuizId The quiz Id
 296  
      * @param locale The current locale
 297  
      * @return The XPage
 298  
      */
 299  
     protected XPage getQuizPage( int nQuizId, Locale locale )
 300  
     {
 301  0
         XPage page = new XPage( );
 302  0
         Map<String, Object> model = _quizService.getQuiz( nQuizId );
 303  0
         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_QUESTIONS_LIST, locale, model );
 304  0
         page.setContent( template.getHtml( ) );
 305  
 
 306  0
         setQuizProperties( (Quiz) model.get( QuizService.KEY_QUIZ ), page, model, locale );
 307  
 
 308  0
         return page;
 309  
     }
 310  
 
 311  
     /**
 312  
      * Get the next step of the quiz
 313  
      * @param quiz The quiz to display
 314  
      * @param nOldStepId The id of the last displayed step of the quiz, or 0 if
 315  
      *            no step was displayed
 316  
      * @param request The request
 317  
      * @return The XPage to display
 318  
      */
 319  
     protected XPage getQuizNextStep( Quiz quiz, int nOldStepId, HttpServletRequest request )
 320  
     {
 321  0
         XPage page = new XPage( );
 322  0
         Map<String, Object> model = _quizService.getQuizNextStep( quiz, nOldStepId );
 323  
         // If the model is null, then there is no more step to display
 324  0
         if ( model == null )
 325  
         {
 326  0
             return null;
 327  
         }
 328  
 
 329  0
         Quiz quizModel = (Quiz) ( _quizService.getQuiz( quiz.getIdQuiz( ) ).get( QuizService.KEY_QUIZ ) );
 330  
 
 331  0
         QuestionGroup group = (QuestionGroup) model.get( MARK_GROUP );
 332  
 
 333  0
         boolean bDisplayScore = group.getDisplayScore( );
 334  0
         Plugin plugin = PluginService.getPlugin( QuizService.PLUGIN_NAME );
 335  0
         int nTotalQuestion = (Integer) request.getSession( ).getAttribute( MARK_QUESTIONS_COUNT );
 336  0
         int nIdLastQuizGroup = QuestionGroupHome.findLastByQuiz( quiz.getIdQuiz( ), plugin );
 337  0
         if ( !bDisplayScore )
 338  
         {
 339  
             // If there is no group that will display the result, then the last group must display it
 340  0
             if ( !QuestionGroupHome.hasGroupDisplayScore( group.getIdQuiz( ), plugin ) )
 341  
             {
 342  0
                 int nSizeQuiz = quizModel.getQuestions( ).size( );
 343  0
                 bDisplayScore = nTotalQuestion == nSizeQuiz && nIdLastQuizGroup == group.getIdGroup( );
 344  
             }
 345  
         }
 346  
 
 347  0
         if ( bDisplayScore )
 348  
         {
 349  
             // The quiz is over
 350  0
             int nScore = (Integer) request.getSession( ).getAttribute( MARK_SCORE );
 351  
 
 352  0
             String strMessage = I18nService.getLocalizedString( PROPERTY_MSG_MANY_GOOD_ANSWERS, request.getLocale( ) );
 353  
 
 354  0
             switch ( nScore )
 355  
             {
 356  
             case 0:
 357  0
                 strMessage = I18nService.getLocalizedString( PROPERTY_MSG_NO_GOOD_ANSWER, request.getLocale( ) );
 358  
 
 359  0
                 break;
 360  
 
 361  
             case 1:
 362  0
                 strMessage = I18nService.getLocalizedString( PROPERTY_MSG_ONE_GOOD_ANSWER, request.getLocale( ) );
 363  
 
 364  0
                 break;
 365  
 
 366  
             default:
 367  
                 break;
 368  
             }
 369  
 
 370  0
             Object[] args = { nScore, nTotalQuestion };
 371  0
             String strScoreMessage = MessageFormat.format( strMessage, args );
 372  0
             model.put( MARK_SCORE_MESSAGE, strScoreMessage );
 373  0
             _quizService.processEndOfQuiz( quiz, "" + nScore, getUserAnswers( request.getSession( ) ) );
 374  0
             resetUserAnswers( request.getSession( ) );
 375  
         }
 376  
 
 377  0
         model.put( MARK_IS_LAST_GROUP, nIdLastQuizGroup == group.getIdGroup( ) );
 378  
 
 379  0
         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_QUESTIONS_LIST_STEP, request.getLocale( ),
 380  
                 model );
 381  0
         page.setContent( template.getHtml( ) );
 382  
 
 383  0
         setQuizProperties( quiz, page, model, request.getLocale( ) );
 384  
 
 385  0
         return page;
 386  
     }
 387  
 
 388  
     /**
 389  
      * Return The Answers list
 390  
      * @param quiz The quiz
 391  
      * @param locale The current locale
 392  
      * @param mapParameters request parameters as a map
 393  
      * @param plugin the plugin
 394  
      * @return The XPage
 395  
      */
 396  
     protected XPage getQuizResults( Quiz quiz, Locale locale, Map<String, String[]> mapParameters, Plugin plugin )
 397  
     {
 398  0
         XPage page = new XPage( );
 399  
 
 400  
         Map<String, Object> model;
 401  
 
 402  0
         if ( "PROFIL".equals( quiz.getTypeQuiz( ) ) )
 403  
         {
 404  0
             model = _quizService.calculateQuizProfile( quiz.getIdQuiz( ), mapParameters, locale );
 405  
         }
 406  
         else
 407  
         {
 408  0
             model = _quizService.getResults( quiz.getIdQuiz( ), mapParameters, locale );
 409  
         }
 410  
 
 411  0
         String strError = (String) model.get( QuizService.KEY_ERROR );
 412  
 
 413  0
         if ( strError != null )
 414  
         {
 415  0
             return getErrorPage( quiz.getIdQuiz( ), strError, 0, locale );
 416  
         }
 417  
 
 418  0
         _quizService.processEndOfQuiz( quiz, "" + model.get( MARK_SCORE ), mapParameters );
 419  
 
 420  0
         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_QUIZ_RESULTS, locale, model );
 421  
 
 422  0
         page.setContent( template.getHtml( ) );
 423  
 
 424  0
         setQuizResultProperties( quiz, page, model, locale );
 425  
 
 426  0
         return page;
 427  
     }
 428  
 
 429  
     /**
 430  
      * Return The Answers list for the given step
 431  
      * @param quiz The quiz
 432  
      * @param nIdStep The id of the submitted step
 433  
      * @param locale The current locale
 434  
      * @param mapResponsesCurrentStep Responses of the current step
 435  
      * @param session The session
 436  
      * @param plugin the plugin
 437  
      * @return The XPage
 438  
      */
 439  
     protected XPage getQuizStepResults( Quiz quiz, int nIdStep, Locale locale,
 440  
             Map<String, String[]> mapResponsesCurrentStep, HttpSession session, Plugin plugin )
 441  
     {
 442  0
         XPage page = new XPage( );
 443  
 
 444  
         Map<String, Object> model;
 445  0
         if ( "PROFIL".equals( quiz.getTypeQuiz( ) ) )
 446  
         {
 447  0
             model = _quizService.calculateQuizStepProfile( quiz, nIdStep, mapResponsesCurrentStep, locale, plugin );
 448  
         }
 449  
         else
 450  
         {
 451  0
             model = _quizService.getStepResults( quiz, nIdStep, mapResponsesCurrentStep, locale, plugin );
 452  
 
 453  0
             if ( model != null )
 454  
             {
 455  0
                 int nNewScore = (Integer) model.get( MARK_SCORE );
 456  0
                 int nOldScore = (Integer) session.getAttribute( MARK_SCORE );
 457  0
                 int nScore = nNewScore + nOldScore;
 458  
 
 459  0
                 int nTotalNewQuestion = (Integer) model.get( MARK_QUESTIONS_COUNT );
 460  0
                 int nTotalOldQuestion = (Integer) session.getAttribute( MARK_QUESTIONS_COUNT );
 461  0
                 int nTotalQuestion = nTotalNewQuestion + nTotalOldQuestion;
 462  
 
 463  0
                 session.setAttribute( MARK_SCORE, nScore );
 464  0
                 session.setAttribute( MARK_QUESTIONS_COUNT, nTotalQuestion );
 465  
 
 466  0
                 String strMessage = I18nService.getLocalizedString( PROPERTY_MSG_MANY_GOOD_ANSWERS, locale );
 467  
 
 468  0
                 switch ( nScore )
 469  
                 {
 470  
                 case 0:
 471  0
                     strMessage = I18nService.getLocalizedString( PROPERTY_MSG_NO_GOOD_ANSWER, locale );
 472  
 
 473  0
                     break;
 474  
 
 475  
                 case 1:
 476  0
                     strMessage = I18nService.getLocalizedString( PROPERTY_MSG_ONE_GOOD_ANSWER, locale );
 477  
 
 478  0
                     break;
 479  
 
 480  
                 default:
 481  
                     break;
 482  
                 }
 483  
 
 484  0
                 Object[] args = { nScore, nTotalQuestion };
 485  0
                 String strScoreMessage = MessageFormat.format( strMessage, args );
 486  0
                 model.put( MARK_SCORE, nScore );
 487  0
                 model.put( MARK_SCORE_MESSAGE, strScoreMessage );
 488  
 
 489  
             }
 490  
         }
 491  
 
 492  0
         if ( model == null )
 493  
         {
 494  0
             return null;
 495  
         }
 496  
 
 497  0
         model.put( PARAMETER_OLD_STEP, nIdStep );
 498  
 
 499  
         // If there is no next step
 500  0
         if ( QuestionGroupHome.getGroupByPosition( quiz.getIdQuiz( ), nIdStep + 1, plugin ) == null )
 501  
         {
 502  0
             model.put( MARK_HAS_NEXT_STEP, Boolean.FALSE );
 503  0
             _quizService.processEndOfQuiz( quiz, "" + model.get( MARK_SCORE ), getUserAnswers( session ) );
 504  
         }
 505  
         else
 506  
         {
 507  0
             model.put( MARK_HAS_NEXT_STEP, Boolean.TRUE );
 508  
         }
 509  
 
 510  0
         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_QUIZ_RESULTS_STEP, locale, model );
 511  
 
 512  0
         page.setContent( template.getHtml( ) );
 513  
 
 514  0
         setQuizResultProperties( quiz, page, model, locale );
 515  
 
 516  0
         return page;
 517  
     }
 518  
 
 519  
     /**
 520  
      * Returns an error page
 521  
      * @param nIdQuiz The id of the quiz
 522  
      * @param strError The error message
 523  
      * @param nStepToRedirect The id of the step to redirect the user to, or 0
 524  
      *            to redirect the user to the start of the quiz
 525  
      * @param locale The current locale
 526  
      * @return The XPage
 527  
      */
 528  
     protected XPage getErrorPage( int nIdQuiz, String strError, int nStepToRedirect, Locale locale )
 529  
     {
 530  0
         XPage page = new XPage( );
 531  0
         Map<String, Object> model = new HashMap<String, Object>( );
 532  0
         model.put( MARK_ERROR, strError );
 533  0
         model.put( MARK_ID_QUIZ, Integer.toString( nIdQuiz ) );
 534  0
         if ( nStepToRedirect > 1 )
 535  
         {
 536  0
             model.put( PARAMETER_OLD_STEP, nStepToRedirect - 1 );
 537  
         }
 538  
 
 539  0
         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_QUIZ_ERROR, locale, model );
 540  
 
 541  0
         page.setContent( template.getHtml( ) );
 542  
 
 543  0
         String strPath = I18nService.getLocalizedString( PROPERTY_QUIZ_ERROR_PAGE_PATH, locale );
 544  0
         String strTitle = I18nService.getLocalizedString( PROPERTY_QUIZ_ERROR_PAGE_TITLE, locale );
 545  0
         page.setPathLabel( strPath );
 546  0
         page.setTitle( strTitle );
 547  
 
 548  0
         return page;
 549  
     }
 550  
 
 551  
     /**
 552  
      * Save answers of a given step of a quiz into the session. If an answer is
 553  
      * missing, then return an error message in the result map
 554  
      * @param quiz The quiz
 555  
      * @param nIdStep The id of the step to validate
 556  
      * @param mapParameters The map of HTTP parameters
 557  
      * @param locale The locale
 558  
      * @param plugin The plugin
 559  
      * @param session the session
 560  
      * @return A map containing associations between question keys and answers
 561  
      */
 562  
     @SuppressWarnings( "unchecked" )
 563  
     private Map<String, String[]> saveAndValidateQuizAnswers( Quiz quiz, int nIdStep,
 564  
             Map<String, String[]> mapParameters, Locale locale, Plugin plugin, HttpSession session )
 565  
     {
 566  0
         Map<String, String[]> mapUserAnswers = _quizService.getUserAnswersForGroup( quiz.getIdQuiz( ), nIdStep,
 567  
                 mapParameters, locale, plugin );
 568  0
         Map<String, String[]> mapOldAnswers = (Map<String, String[]>) session.getAttribute( SESSION_KEY_QUIZ_STEP );
 569  0
         if ( mapOldAnswers != null )
 570  
         {
 571  0
             mapOldAnswers.putAll( mapUserAnswers );
 572  
         }
 573  
         else
 574  
         {
 575  0
             session.setAttribute( SESSION_KEY_QUIZ_STEP, mapUserAnswers );
 576  
         }
 577  0
         return mapUserAnswers;
 578  
     }
 579  
 
 580  
     /**
 581  
      * Get the answers of a user stored in session
 582  
      * @param session The session
 583  
      * @return A map containing answers to questions of a quiz
 584  
      */
 585  
     @SuppressWarnings( "unchecked" )
 586  
     private Map<String, String[]> getUserAnswers( HttpSession session )
 587  
     {
 588  0
         return (Map<String, String[]>) session.getAttribute( SESSION_KEY_QUIZ_STEP );
 589  
     }
 590  
 
 591  
     /**
 592  
      * Set the properties of the XPage to display a quiz
 593  
      * @param quiz The quiz displayed by the XPage
 594  
      * @param page The XPage to display
 595  
      * @param model The model
 596  
      * @param locale The locale
 597  
      */
 598  
     private void setQuizProperties( Quiz quiz, XPage page, Map<String, Object> model, Locale locale )
 599  
     {
 600  0
         String strPath = I18nService.getLocalizedString( PROPERTY_QUIZ_PAGE_PATH, locale );
 601  0
         String strTitle = I18nService.getLocalizedString( PROPERTY_QUIZ_PAGE_TITLE, locale );
 602  0
         Object[] args = { quiz.getName( ) };
 603  0
         page.setPathLabel( MessageFormat.format( strPath, args ) );
 604  0
         page.setTitle( MessageFormat.format( strTitle, args ) );
 605  0
     }
 606  
 
 607  
     /**
 608  
      * Remove any answers of quiz made by the user
 609  
      * @param session The session
 610  
      */
 611  
     private void resetUserAnswers( HttpSession session )
 612  
     {
 613  0
         session.removeAttribute( SESSION_KEY_QUIZ_STEP );
 614  0
     }
 615  
 
 616  
     /**
 617  
      * Set the properties of the XPage to display a quiz result
 618  
      * @param quiz The quiz displayed by the XPage
 619  
      * @param page The XPage to display
 620  
      * @param model The model
 621  
      * @param locale The locale
 622  
      */
 623  
     private void setQuizResultProperties( Quiz quiz, XPage page, Map<String, Object> model, Locale locale )
 624  
     {
 625  0
         String strPath = I18nService.getLocalizedString( PROPERTY_QUIZ_RESULTS_PAGE_PATH, locale );
 626  0
         String strTitle = I18nService.getLocalizedString( PROPERTY_QUIZ_RESULTS_PAGE_TITLE, locale );
 627  0
         Object[] args = { quiz.getName( ) };
 628  0
         page.setPathLabel( MessageFormat.format( strPath, args ) );
 629  0
         page.setTitle( MessageFormat.format( strTitle, args ) );
 630  0
     }
 631  
 }