📄 testmanagerbean.java
字号:
{ test.removeQuestion(ques); test.setLastModifiedMillis(System.currentTimeMillis()); } catch (Exception ex) { getSessionContext().setRollbackOnly(); throw new SchoolException("Error removing Question with ID "+quesId+" from Test with ID "+testId, ex); } } /** * Gets list of summary data for questions belonging to a test. * * @ejb.interface-method * @ejb.transaction type="Required" * * @param testId Test ID. * @param count Maximum number of resources to retrieve. * @return Array of ResourceListData instances. * @throws SchoolException if test is missing. */ public ResourceListData[] getQuestionsSummaryDataForTest( Integer testId, int count) throws SchoolException { LocalTest test = null; try { test = s_testHome.findByPrimaryKey(testId); } catch (FinderException fex) { throw new SchoolException(SchoolException.TEST_NOT_FOUND, "Cannot find Test with ID "+testId, fex); } ResourceListData[] resources = null; try { List resourceList = test.getQuestions(count); resources = new ResourceListData[ resourceList.size() ]; Iterator resourceIter = resourceList.iterator(); for (int ridx=0; resourceIter.hasNext() && (ridx<resources.length); ridx++) { LocalQuestion ques = (LocalQuestion)resourceIter.next(); resources[ridx] = new ResourceListData( ques.getId(), ques.getName()); resources[ridx].getProperties().put("description", StringUtils.truncate(ques.getContent(),30) ); resources[ridx].getProperties().put("score", new Integer(ques.getScore()) ); } } catch (Exception ex) { throw new SchoolException("Error getting data for Questions in Test with ID "+testId, ex); } return resources; } /** * Gets data of a test. * * @ejb.interface-method * @ejb.transaction type="Required" * * @param id Test ID. * @return TestData instance storing the test's data. * @throws SchoolException if test is missing. */ public TestData getTestData(Integer id) throws SchoolException { LocalTest test = null; try { test = s_testHome.findByPrimaryKey(id); } catch (FinderException fex) { throw new SchoolException(SchoolException.TEST_NOT_FOUND, "Cannot find Test with ID "+id, fex); } TestData data = null; try { data = getDataFromTest(test); } catch (Exception ex) { throw new SchoolException("Error getting data for Test with ID "+id, ex); } return data; } /** * Updates the data of an existing test. * * @ejb.interface-method * @ejb.transaction type="Required" * * @param id Test ID. * @param data TestData instance with the test's data. * @throws EJBException if test is missing * @throws SchoolException if there is a problem updating the test. */ public void setTestData(Integer id, TestData data) throws SchoolException { LocalTest test = null; try { test = s_testHome.findByPrimaryKey(id); } catch (FinderException fex) { throw new SchoolException(SchoolException.TEST_NOT_FOUND, "Cannot find Test with ID "+id, fex); } try { test.setName( data.getName() ); test.setOwnerHierarchyId( data.getOwnerHierId() ); test.setPassPercentage(data.getPassPercentage()); test.setMultiQuestionsMode( data.isMultiQuestionsMode()); test.setSuppressQuestionFeedback(data.isSuppressQuestionFeedback()); test.setSuppressTestEndFeedback(data.isSuppressTestEndFeedback()); test.setTimeLimitSeconds( data.getTimeLimitSeconds()); test.setLastModifiedMillis(System.currentTimeMillis()); Integer[] resIdsToRemove = data.getResourceIdsToRemove(); for (int r=0; r<resIdsToRemove.length; r++) { removeQuestionFromTest(id, resIdsToRemove[r]); } Integer[] resIdsToAdd = data.getResourceIdsToAdd(); for (int r=0; r<resIdsToAdd.length; r++) { addQuestionToTest(id, resIdsToAdd[r]); } } catch (Exception ex) { getSessionContext().setRollbackOnly(); throw new SchoolException("Error setting data for Test with ID "+id, ex); } } /** * Checks the user's answers for a contiguous block of questions. * The user is awarded a score for each correctly answered question. * These scores are added together and returned in an AnswerStatus instance. * This method also creates an AnswerHistoryRecordBean instance * for each of the answers to log this answer and the awarded score. * This method is intended to be used by a client that * evaluates multiple questions at a time. * * @ejb.interface-method * @ejb.transaction type="Required" * * @param testId Test ID * @param quesIds Array of Question IDs * @param userId User ID * @param offset Offset of the first question in quesIds relative to the first question within the test. * @param userAnswers Array of user's answer, format depends on question type, array length must equal that of quesIds. * @param testSecs Amount of time in seconds the user took to complete the test (applicable only if testSecs is larger than 0, endOfTest is true and multiQuestionsMode is enabled). * @param endOfTest true if this is the last block of questions in the test, false if there are following blocks. * @return The resultant status of the answers. * @throws SchoolException if the test or a question is missing, or some other error. */ public AnswerStatus checkMultiQuestionAnswers(Integer testId, Integer[] quesIds, Integer userId, int offset, String[] userAnswers, int testSecs, boolean endOfTest) throws SchoolException { if (quesIds.length != userAnswers.length) { throw new SchoolException(SchoolException.UNSPECIFIED, "Number of answers ("+userAnswers.length+") does not match number fo questions ("+quesIds.length+")"); } int status = AnswerStatus.WRONG; int scoreToAdd = 0; for (int q=0; q<quesIds.length; q++) { final boolean lastQuesInTest = endOfTest && (q==quesIds.length-1); AnswerStatus quesStatus = checkQuestionAnswer(testId, quesIds[q], userId, offset+q, userAnswers[q], testSecs, 0, lastQuesInTest ); scoreToAdd += quesStatus.getScore(); if (status == AnswerStatus.CORRECT) { // Correct status can be overriden by all other statuses status = quesStatus.getStatus(); } else if (status == AnswerStatus.WRONG) { // Wrong status can be overriden by only test timed out status if (quesStatus.getStatus() == AnswerStatus.TEST_TIMED_OUT) { status = AnswerStatus.TEST_TIMED_OUT; } } // Timed out status cannot be overridden. } return new AnswerStatus(status, scoreToAdd); } /** * Checks the user's answer for a question. The user is * awarded a score if the answer is correct. This method also * creates an AnswerHistoryRecordBean instance to log this answer * and the awarded score. * This method is intended to be used by a client that * evaluates one question at a time. * * @ejb.interface-method * @ejb.transaction type="Required" * * @param testId Test ID * @param quesId Question ID * @param userId User ID * @param quesIndex Index of the question within the test. * @param userAnswer User's answer, format depends on question type. * @param testSecs Amount of time in seconds the user took to complete the test (applicable only if testSecs is larger than 0, endOfTest is true and multiQuestionsMode is enabled). * @param quesSecs Amount of time in seconds the user took to answer this question (applicable only if quesSecs is larger than 0 and multiQuestionsMode is disabled). * @param endOfTest true if this is the last question in the test, false if there are following questions. * @return The resultant status of the answer. * @throws SchoolException if the test or question is missing, or some other error. */ public AnswerStatus checkQuestionAnswer(Integer testId, Integer quesId, Integer userId, int quesIndex, String userAnswer, int testSecs, int quesSecs, boolean endOfTest) throws SchoolException { LocalTest test = null; try { test = s_testHome.findByPrimaryKey(testId); } catch (FinderException fex) { throw new SchoolException(SchoolException.TEST_NOT_FOUND, "Cannot find Test with ID "+testId, fex); } LocalQuestion ques = null; try { ques = s_quesHome.findByPrimaryKey(quesId); } catch (FinderException fex) { throw new SchoolException(SchoolException.QUESTION_NOT_FOUND, "Cannot find Question with ID "+quesId, fex); } int status = AnswerStatus.WRONG; boolean exceedTestTime = false; boolean exceedQuesTime = false; int quesScore = 0; String quesAnswer = null; Integer quesType = ques.getType(); int scoreToAdd = 0; boolean answerCorrect = false; try { double result = ques.checkResponse(userAnswer); // Use 0.5 as a threshold for determining whether the answer is correct or not. // For some question type, correctness has no real meaning, but its no harm setting it anyway since it'll just be ignore by the client. answerCorrect = (result>0.5); status = answerCorrect ? AnswerStatus.CORRECT : AnswerStatus.WRONG; quesScore = ques.getScore(); quesAnswer = ques.getAnswer(); quesType = ques.getType(); // Score to add depends on the question type if (IQuestionType.SINGLE_CHOICE_TYPE.equals(quesType) || IQuestionType.MULTIPLE_CHOICE_TYPE.equals(quesType)) { scoreToAdd = (status == AnswerStatus.CORRECT) ? quesScore : 0; } else if (IQuestionType.KEYWORDS_TYPE.equals(quesType)) { if (ques.isMustMatchAllKeywords()) { scoreToAdd = (status == AnswerStatus.CORRECT) ? quesScore : 0; } else { scoreToAdd = (int)(result * quesScore); } } if (test.isMultiQuestionsMode()) { if (endOfTest && (testSecs>0) && (test.getTimeLimitSeconds()>0)) { exceedTestTime = (testSecs > test.getTimeLimitSeconds()); status = exceedTestTime ? AnswerStatus.TEST_TIMED_OUT : status; scoreToAdd = 0; } } else { if ((quesSecs>0) && (ques.getTimeLimitSeconds()>0)) { exceedQuesTime = (quesSecs > ques.getTimeLimitSeconds()); status = exceedQuesTime ? AnswerStatus.QUESTION_TIMED_OUT : status; scoreToAdd = 0; } } } catch (Exception ex) { throw new SchoolException("Error checking answer for Question with ID "+quesId, ex); } try { s_logger.fine("Adding score "+scoreToAdd+" for test "+testId+", question "+quesId+" to user "+userId); LocalUserTestAssoc assoc = findTestUserAssoc(testId, userId); if (assoc==null) { assoc = s_userTestAssocHome.create(testId, userId); } assoc.addScore(scoreToAdd, quesScore); if (endOfTest) { assoc.setTestCompleted(true); } if (exceedTestTime) { assoc.exceededTestTime(); } } catch (CreateException cex) { getSessionContext().setRollbackOnly(); throw new SchoolException("Error creating Score for Test ID="+testId+", User ID="+userId, cex); } catch (Exception ex) { getSessionContext().setRollbackOnly(); throw new SchoolException("Error adding score for Test ID="+testId+", User ID="+userId, ex); } try { s_answerHistoryRecordHome.create(testId, quesId, userId, quesType, quesIndex, quesScore, scoreToAdd, userAnswer, quesAnswer, answerCorrect, exceedQuesTime); } catch (CreateException cex) { getSessionContext().setRollbackOnly(); throw new SchoolException("Error creating history record for Test ID="+testId+", Question ID="+quesId+", User ID="+userId, cex); } catch (Exception ex) { getSessionContext().setRollbackOnly(); throw new SchoolException("Error creating history record for Test ID="+testId+", Question ID="+quesId+", User ID="+userId, ex); } return new AnswerStatus(status, scoreToAdd); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -