private void processReturnFile( AssessableCourseNode courseNode, BulkAssessmentRow row, UserCourseEnvironment uce, File assessedFolder) { String assessedId = row.getAssessedId(); Identity identity = uce.getIdentityEnvironment().getIdentity(); VFSContainer returnBox = getReturnBox(uce, courseNode, identity); if (returnBox != null) { for (String returnFilename : row.getReturnFiles()) { File returnFile = new File(assessedFolder, returnFilename); VFSItem currentReturnLeaf = returnBox.resolve(returnFilename); if (currentReturnLeaf != null) { // remove the current file (delete make a version if it is enabled) currentReturnLeaf.delete(); } VFSLeaf returnLeaf = returnBox.createChildLeaf(returnFilename); if (returnFile.exists()) { try { InputStream inStream = new FileInputStream(returnFile); VFSManager.copyContent(inStream, returnLeaf); } catch (FileNotFoundException e) { log.error("Cannot copy return file " + returnFilename + " from " + assessedId, e); } } } } }
private void doProcess(List<BulkAssessmentFeedback> feedbacks) { final DB dbInstance = DBFactory.getInstance(); final BaseSecurity securityManager = CoreSpringFactory.getImpl(BaseSecurity.class); final Identity coachIdentity = securityManager.loadIdentityByKey(coachedIdentity); final ICourse course = CourseFactory.loadCourse(courseRes); final AssessableCourseNode courseNode = getCourseNode(); final Roles studentRoles = new Roles(false, false, false, false, false, false, false, false); final boolean hasUserComment = courseNode.hasCommentConfigured(); final boolean hasScore = courseNode.hasScoreConfigured(); final boolean hasPassed = courseNode.hasPassedConfigured(); final boolean hasReturnFiles = (StringHelper.containsNonWhitespace(datas.getReturnFiles()) && (courseNode instanceof TACourseNode || courseNode instanceof GTACourseNode)); if (hasReturnFiles) { try { OlatRootFileImpl returnFilesZipped = new OlatRootFileImpl(datas.getReturnFiles(), null); String tmp = FolderConfig.getCanonicalTmpDir(); unzipped = new File(tmp, UUID.randomUUID().toString() + File.separatorChar); unzipped.mkdirs(); ZipUtil.unzip(returnFilesZipped.getBasefile(), unzipped); } catch (Exception e) { log.error("Cannot unzip the return files during bulk assessment", e); } } Float min = null; Float max = null; Float cut = null; if (hasScore) { min = courseNode.getMinScoreConfiguration(); max = courseNode.getMaxScoreConfiguration(); } if (hasPassed) { cut = courseNode.getCutValueConfiguration(); } int count = 0; List<BulkAssessmentRow> rows = datas.getRows(); for (BulkAssessmentRow row : rows) { Long identityKey = row.getIdentityKey(); if (identityKey == null) { feedbacks.add(new BulkAssessmentFeedback("bulk.action.no.such.user", row.getAssessedId())); continue; // nothing to do } Identity identity = securityManager.loadIdentityByKey(identityKey); IdentityEnvironment ienv = new IdentityEnvironment(identity, studentRoles); UserCourseEnvironment uce = new UserCourseEnvironmentImpl(ienv, course.getCourseEnvironment()); // update comment, empty string will reset comment String userComment = row.getComment(); if (hasUserComment && userComment != null) { // Update userComment in db courseNode.updateUserUserComment(userComment, uce, coachIdentity); // LD: why do we have to update the efficiency statement? // EfficiencyStatementManager esm = EfficiencyStatementManager.getInstance(); // esm.updateUserEfficiencyStatement(uce); } // update score Float score = row.getScore(); if (hasScore && score != null) { // score < minimum score if ((min != null && score.floatValue() < min.floatValue()) || (score.floatValue() < AssessmentHelper.MIN_SCORE_SUPPORTED)) { // "bulk.action.lessThanMin"; } // score > maximum score else if ((max != null && score.floatValue() > max.floatValue()) || (score.floatValue() > AssessmentHelper.MAX_SCORE_SUPPORTED)) { // "bulk.action.greaterThanMax"; } else { // score between minimum and maximum score ScoreEvaluation se; if (hasPassed && cut != null) { Boolean passed = (score.floatValue() >= cut.floatValue()) ? Boolean.TRUE : Boolean.FALSE; se = new ScoreEvaluation(score, passed); } else { se = new ScoreEvaluation(score, null); } // Update score,passed properties in db, and the user's efficiency statement courseNode.updateUserScoreEvaluation(se, uce, coachIdentity, false); } } Boolean passed = row.getPassed(); if (hasPassed && passed != null && cut == null) { // Configuration of manual assessment --> Display passed/not passed: yes, // Type of display: Manual by tutor ScoreEvaluation seOld = courseNode.getUserScoreEvaluation(uce); Float oldScore = seOld.getScore(); ScoreEvaluation se = new ScoreEvaluation(oldScore, passed); // Update score,passed properties in db, and the user's efficiency statement boolean incrementAttempts = false; courseNode.updateUserScoreEvaluation(se, uce, coachIdentity, incrementAttempts); } boolean identityHasReturnFile = false; if (hasReturnFiles && row.getReturnFiles() != null && row.getReturnFiles().size() > 0) { String assessedId = row.getAssessedId(); File assessedFolder = new File(unzipped, assessedId); identityHasReturnFile = assessedFolder.exists(); if (identityHasReturnFile) { processReturnFile(courseNode, row, uce, assessedFolder); } } if (courseNode instanceof GTACourseNode) { // push the state further GTACourseNode gtaNode = (GTACourseNode) courseNode; if ((hasScore && score != null) || (hasPassed && passed != null)) { // pushed to graded updateTasksState(gtaNode, uce, TaskProcess.grading); } else if (hasReturnFiles) { // push to revised updateTasksState(gtaNode, uce, TaskProcess.correction); } } if (count++ % 5 == 0) { dbInstance.commitAndCloseSession(); } else { dbInstance.commit(); } } }