Index: lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/dto/GBActivityGridRowDTO.java =================================================================== diff -u -ra3549eb5e124fddc99947655db5cc3656f33449e -r352e16d0ad309caa12c5422fddebfc221c83714b --- lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/dto/GBActivityGridRowDTO.java (.../GBActivityGridRowDTO.java) (revision a3549eb5e124fddc99947655db5cc3656f33449e) +++ lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/dto/GBActivityGridRowDTO.java (.../GBActivityGridRowDTO.java) (revision 352e16d0ad309caa12c5422fddebfc221c83714b) @@ -56,19 +56,37 @@ this.groupId = groupId; } - public GBActivityGridRowDTO(Activity activity, String groupName, Long groupId) { + /** The Spring htmlEscape method escapes Greek letters (https://jira.spring.io/browse/SPR-9293) + * so when the escaping is done for the Excel Exports, any Greek activity names are escaped. + * So we default to escaping (works fine sent to the browser) and then we have XSS protection for the + * web pages. But do not escape when it will be saved in an Excel file. This issue will be resolved + * when we upgrade Spring to v4.1.2 and then we can go back to one single creator method. + */ + public GBActivityGridRowDTO(Activity activity, String groupName, Long groupId) { + this(activity, groupName, groupId, true); + } + public GBActivityGridRowDTO(Activity activity, String groupName, Long groupId, boolean escapeTitles) { + if (groupName != null && groupId != null) { // Need to make the id unique, so appending the group id for this row this.id = activity.getActivityId().toString() + "_" + groupId.toString(); this.groupId = groupId; // If grouped acitivty, append group name - this.rowName = HtmlUtils.htmlEscape(activity.getTitle()) + " (" + groupName + ")"; + if ( escapeTitles ) { + this.rowName = HtmlUtils.htmlEscape(activity.getTitle()) + " (" + groupName + ")"; + } else { + this.rowName = activity.getTitle() + " (" + groupName + ")"; + } } else { this.id = activity.getActivityId().toString(); - this.rowName = HtmlUtils.htmlEscape(activity.getTitle()); + if ( escapeTitles ) { + this.rowName = HtmlUtils.htmlEscape(activity.getTitle()); + } else { + this.rowName = activity.getTitle(); + } } String competenceMappingsStr = ""; Index: lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/GradebookService.java =================================================================== diff -u -reeb8faaea5372ccf5445d7172f726931e9f26098 -r352e16d0ad309caa12c5422fddebfc221c83714b --- lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/GradebookService.java (.../GradebookService.java) (revision eeb8faaea5372ccf5445d7172f726931e9f26098) +++ lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/GradebookService.java (.../GradebookService.java) (revision 352e16d0ad309caa12c5422fddebfc221c83714b) @@ -232,7 +232,7 @@ } @Override - public List getGBActivityRowsForLesson(Long lessonId, TimeZone userTimezone) { + public List getGBActivityRowsForLesson(Long lessonId, TimeZone userTimezone, boolean escapeTitles) { GradebookService.logger.debug("Getting gradebook data for lesson: " + lessonId); Lesson lesson = lessonService.getLesson(lessonId); @@ -249,13 +249,13 @@ for (Group group : groups) { GBActivityGridRowDTO activityDTO = getGradebookActivityDTO(activity, lesson, - group.getGroupName(), group.getGroupId()); + group.getGroupName(), group.getGroupId(), escapeTitles); gradebookActivityDTOs.add(activityDTO); } } } else { - GBActivityGridRowDTO activityDTO = getGradebookActivityDTO(activity, lesson, null, null); + GBActivityGridRowDTO activityDTO = getGradebookActivityDTO(activity, lesson, null, null, escapeTitles); gradebookActivityDTOs.add(activityDTO); } } @@ -996,7 +996,7 @@ rowList.add(GradebookService.EMPTY_ROW); // Adding the activity average data to the summary - List activityRows = getGBActivityRowsForLesson(lesson.getLessonId(), null); + List activityRows = getGBActivityRowsForLesson(lesson.getLessonId(), null, false); ExcelCell[] activityAverageTitle = new ExcelCell[1]; activityAverageTitle[0] = new ExcelCell(getMessage("gradebook.export.activities"), true); rowList.add(activityAverageTitle); @@ -1016,7 +1016,7 @@ GBActivityGridRowDTO activityRow = (GBActivityGridRowDTO) it.next(); // Add the activity average data ExcelCell[] activityDataRow = new ExcelCell[6]; - activityDataRow[0] = new ExcelCell(activityRow.getRowName(), false); + activityDataRow[0] = new ExcelCell(activityRow.getRowName(), false); // this is the problem entry activityDataRow[1] = new ExcelCell(activityRow.getCompetences(), false); activityDataRow[2] = new ExcelCell(activityRow.getMedianTimeTakenSeconds(), false); activityDataRow[3] = new ExcelCell(activityRow.getAverageMark(), false); @@ -1079,7 +1079,7 @@ headerRow = new ExcelCell[3 + filteredActivityToUserDTOMap.keySet().size()]; int count = 3; for (Activity activity : filteredActivityToUserDTOMap.keySet()) { - headerRow[count++] = new ExcelCell(activity.getTitle(), true); + headerRow[count++] = new ExcelCell(activity.getTitle(), true); // this one works } rowList.add(headerRow); headerRow = new ExcelCell[4 + filteredActivityToUserDTOMap.keySet().size()]; @@ -1988,16 +1988,17 @@ } /** - * Gets the GBActivityGridRowDTO fro a given activity and lesson + * Gets the GBActivityGridRowDTO fro a given activity and lesson. Only set escapeTitles to false if the + * output is *not* going to a webpage, but is instead going to a spreadsheet. * * @param activity * @param lesson * @return */ private GBActivityGridRowDTO getGradebookActivityDTO(ToolActivity activity, Lesson lesson, String groupName, - Long groupId) { + Long groupId, boolean escapeTitles) { - GBActivityGridRowDTO activityDTO = new GBActivityGridRowDTO(activity, groupName, groupId); + GBActivityGridRowDTO activityDTO = new GBActivityGridRowDTO(activity, groupName, groupId, escapeTitles); if ((groupName != null) && (groupId != null)) { // Setting averages for group Index: lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/IGradebookService.java =================================================================== diff -u -rc3db10fe6622ab0bb74375275547f75608241c65 -r352e16d0ad309caa12c5422fddebfc221c83714b --- lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/IGradebookService.java (.../IGradebookService.java) (revision c3db10fe6622ab0bb74375275547f75608241c65) +++ lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/IGradebookService.java (.../IGradebookService.java) (revision 352e16d0ad309caa12c5422fddebfc221c83714b) @@ -45,12 +45,12 @@ /** * Gets all the activity rows for a lesson, with the mark for each activity being the average for all users in the - * lesson + * lesson. Only set escapeTitles to false if the output is *not* going to a webpage, but is instead going to a spreadsheet. * * @param lesson * @return */ - List getGBActivityRowsForLesson(Long lessonId, TimeZone userTimezone); + List getGBActivityRowsForLesson(Long lessonId, TimeZone userTimezone, boolean escapeTitles); /** * Gets all the activity rows for a user, with the mark for the activity being the user's individual mark Index: lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/web/action/GradebookAction.java =================================================================== diff -u -r275ec50583146c85babb11a02f33890e5e83bb09 -r352e16d0ad309caa12c5422fddebfc221c83714b --- lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/web/action/GradebookAction.java (.../GradebookAction.java) (revision 275ec50583146c85babb11a02f33890e5e83bb09) +++ lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/web/action/GradebookAction.java (.../GradebookAction.java) (revision 352e16d0ad309caa12c5422fddebfc221c83714b) @@ -144,7 +144,7 @@ currentUserDTO.getTimeZone()); } else if (view == GBGridView.MON_ACTIVITY) { gradebookActivityDTOs = getGradebookService().getGBActivityRowsForLesson(lessonID, - currentUserDTO.getTimeZone()); + currentUserDTO.getTimeZone(), true); } if ((sortBy == null) || sortBy.equals("")) {