Index: lams_build/common.properties =================================================================== diff -u -r6b5535a4520eb8752339926611267145beb6b23e -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_build/common.properties (.../common.properties) (revision 6b5535a4520eb8752339926611267145beb6b23e) +++ lams_build/common.properties (.../common.properties) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -18,7 +18,7 @@ # http://www.gnu.org/licenses/gpl.txt # put into EAR MANIFEST.MF file -project.version=3.0 +project.version=3.1 # is HTTPS in use? if so, set it to true, so JSESSIONID cookie is secured secure.cookie=false Index: lams_build/lib/lams/lams.jar =================================================================== diff -u -r55d325641da6f4f7d5149c9368d47ed70cf8d7d5 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 Binary files differ Index: lams_build/unix.properties =================================================================== diff -u -r6b5535a4520eb8752339926611267145beb6b23e -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_build/unix.properties (.../unix.properties) (revision 6b5535a4520eb8752339926611267145beb6b23e) +++ lams_build/unix.properties (.../unix.properties) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -33,7 +33,7 @@ contentrepository.base=/var/opt/lams #JBoss deploy directory (Unix) -server.home=/usr/local/wildfly-8.2/ +server.home=/usr/local/wildfly-10.1/ #Sass executable. sass_exec_file=/usr/local/bin/sass Index: lams_common/src/java/org/lamsfoundation/lams/rating/service/RatingService.java =================================================================== diff -u -r8e090b3ddf269cdffececa4bc55a9333da5b0858 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_common/src/java/org/lamsfoundation/lams/rating/service/RatingService.java (.../RatingService.java) (revision 8e090b3ddf269cdffececa4bc55a9333da5b0858) +++ lams_common/src/java/org/lamsfoundation/lams/rating/service/RatingService.java (.../RatingService.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -21,8 +21,6 @@ * **************************************************************** */ - - package org.lamsfoundation.lams.rating.service; import java.math.BigInteger; @@ -39,9 +37,6 @@ import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.rating.RatingException; import org.lamsfoundation.lams.rating.dao.IRatingCommentDAO; import org.lamsfoundation.lams.rating.dao.IRatingCriteriaDAO; @@ -51,16 +46,21 @@ import org.lamsfoundation.lams.rating.dto.RatingCommentDTO; import org.lamsfoundation.lams.rating.dto.StyledCriteriaRatingDTO; import org.lamsfoundation.lams.rating.dto.StyledRatingDTO; -import org.lamsfoundation.lams.rating.model.AuthoredItemRatingCriteria; import org.lamsfoundation.lams.rating.model.LearnerItemRatingCriteria; import org.lamsfoundation.lams.rating.model.Rating; import org.lamsfoundation.lams.rating.model.RatingComment; import org.lamsfoundation.lams.rating.model.RatingCriteria; import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; +import org.lamsfoundation.lams.util.JsonUtil; import org.lamsfoundation.lams.util.MessageService; import org.lamsfoundation.lams.util.WebUtil; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + public class RatingService implements IRatingService { private static Logger log = Logger.getLogger(RatingService.class); @@ -94,29 +94,29 @@ public int getCountItemsRatedByUserByCriteria(final Long criteriaId, final Integer userId) { return ratingDAO.getCountItemsRatedByUserByCriteria(criteriaId, userId); } - + @Override public void removeUserCommitsByContent(final Long contentId, final Integer userId) { List ratings = ratingDAO.getRatingsByUser(contentId, userId); for (Rating rating : ratings) { ratingDAO.delete(rating); } - + List comments = ratingCommentDAO.getCommentsByContentAndUser(contentId, userId); for (RatingComment comment : comments) { ratingDAO.delete(comment); } } - + @Override - public Map countUsersRatedEachItem(final Long contentId, final Long toolSessionId, final Collection itemIds, - Integer excludeUserId) { + public Map countUsersRatedEachItem(final Long contentId, final Long toolSessionId, + final Collection itemIds, Integer excludeUserId) { return ratingDAO.countUsersRatedEachItem(contentId, toolSessionId, itemIds, excludeUserId); } @Override - public Map countUsersRatedEachItemByCriteria(final Long criteriaId, final Long toolSessionId, final Collection itemIds, - Integer excludeUserId) { + public Map countUsersRatedEachItemByCriteria(final Long criteriaId, final Long toolSessionId, + final Collection itemIds, Integer excludeUserId) { return ratingDAO.countUsersRatedEachItemByCriteria(criteriaId, toolSessionId, itemIds, excludeUserId); } @@ -126,8 +126,8 @@ } @Override - public ItemRatingCriteriaDTO rateItem(RatingCriteria ratingCriteria, Long toolSessionId, Integer userId, Long itemId, - float ratingFloat) { + public ItemRatingCriteriaDTO rateItem(RatingCriteria ratingCriteria, Long toolSessionId, Integer userId, + Long itemId, float ratingFloat) { Long ratingCriteriaId = ratingCriteria.getRatingCriteriaId(); Rating rating = ratingDAO.getRating(ratingCriteriaId, userId, itemId); @@ -152,25 +152,26 @@ } @Override - public int rateItems(RatingCriteria ratingCriteria, Long toolSessionId, Integer userId, Map newRatings) { + public int rateItems(RatingCriteria ratingCriteria, Long toolSessionId, Integer userId, + Map newRatings) { User learner = (User) userManagementService.findById(User.class, userId); int numRatings = 0; - + List dbRatings = ratingDAO.getRatingsByUserCriteria(ratingCriteria.getRatingCriteriaId(), userId); - for ( Rating rating: dbRatings ) { + for (Rating rating : dbRatings) { Long itemId = rating.getItemId(); Float newRating = newRatings.get(itemId); - if ( newRating != null ) { + if (newRating != null) { rating.setRating(newRating); newRatings.remove(itemId); numRatings++; ratingDAO.saveOrUpdate(rating); } else { - rating.setRating((Float)null); + rating.setRating((Float) null); } } - for ( Map.Entry entry : newRatings.entrySet() ) { + for (Map.Entry entry : newRatings.entrySet()) { Rating rating = new Rating(); rating.setItemId(entry.getKey()); rating.setLearner(learner); @@ -180,12 +181,13 @@ ratingDAO.saveOrUpdate(rating); numRatings++; } - + return numRatings; } - + @Override - public void commentItem(RatingCriteria ratingCriteria, Long toolSessionId, Integer userId, Long itemId, String comment) { + public void commentItem(RatingCriteria ratingCriteria, Long toolSessionId, Integer userId, Long itemId, + String comment) { RatingComment ratingComment = ratingCommentDAO.getComment(ratingCriteria.getRatingCriteriaId(), userId, itemId); // persist MessageRating changes in DB @@ -209,8 +211,8 @@ boolean isCommentsByOtherUsersRequired, Long userId) { // fail safe - if there are no items, don't try to look anything up! LDEV-4094 - if ( itemIds == null || itemIds.isEmpty() ) { - return new LinkedList(); + if (itemIds == null || itemIds.isEmpty()) { + return new LinkedList<>(); } //initial preparations @@ -221,8 +223,8 @@ Long singleItemId = isSingleItem ? itemIds.iterator().next() : null; //handle comments criteria - List itemDtos = handleCommentsCriteria(criterias, toolSessionId, itemIds, isCommentsByOtherUsersRequired, - userId); + List itemDtos = handleCommentsCriteria(criterias, toolSessionId, itemIds, + isCommentsByOtherUsersRequired, userId); //get all data from DB List userRatings = ratingDAO.getRatingsByUser(contentId, userId.intValue()); @@ -238,7 +240,7 @@ //handle all criterias except for comments' one for (ItemRatingDTO itemDto : itemDtos) { Long itemId = itemDto.getItemId(); - List criteriaDtos = new LinkedList(); + List criteriaDtos = new LinkedList<>(); itemDto.setCriteriaDtos(criteriaDtos); for (RatingCriteria criteria : criterias) { @@ -274,7 +276,7 @@ } } - if ( itemStatistics != null ) { + if (itemStatistics != null) { Number averageRating = (Number) itemStatistics[2]; criteriaDto.setAverageRating(numberFormat.format(averageRating)); criteriaDto.setAverageRatingAsNumber(averageRating); @@ -297,8 +299,8 @@ /* * Fetches all required comments from the DB. */ - private List handleCommentsCriteria(List criterias, Long toolSessionId, Collection itemIds, - boolean isCommentsByOtherUsersRequired, Long userId) { + private List handleCommentsCriteria(List criterias, Long toolSessionId, + Collection itemIds, boolean isCommentsByOtherUsersRequired, Long userId) { boolean isSingleItem = itemIds.size() == 1; Long singleItemId = isSingleItem ? itemIds.iterator().next() : null; @@ -312,11 +314,13 @@ List commentDtos; if (isSingleItem) { - commentDtos = ratingCommentDAO.getCommentsByCriteriaAndItem(commentCriteriaId, toolSessionId, singleItemId); + commentDtos = ratingCommentDAO.getCommentsByCriteriaAndItem(commentCriteriaId, toolSessionId, + singleItemId); //query DB using itemIds } else if (isCommentsByOtherUsersRequired) { - commentDtos = ratingCommentDAO.getCommentsByCriteriaAndItems(commentCriteriaId, toolSessionId, itemIds); + commentDtos = ratingCommentDAO.getCommentsByCriteriaAndItems(commentCriteriaId, toolSessionId, + itemIds); // get only comments done by the specified user } else { @@ -330,7 +334,7 @@ itemDto.setCommentsMinWordsLimit(criteria.getCommentsMinWordsLimit()); //assign commentDtos by the appropriate items - List commentDtosPerItem = new LinkedList(); + List commentDtosPerItem = new LinkedList<>(); for (RatingCommentDTO commentDto : commentDtos) { if (commentDto.getItemId().equals(itemDto.getItemId())) { commentDtosPerItem.add(commentDto); @@ -354,7 +358,7 @@ private List initializeItemDtos(Collection itemIds) { // initialize itemDtos - List itemDtos = new LinkedList(); + List itemDtos = new LinkedList<>(); for (Long itemId : itemIds) { ItemRatingDTO itemDto = new ItemRatingDTO(); itemDto.setItemId(itemId); @@ -380,9 +384,10 @@ return ratingCriteriaDAO.getByRatingCriteriaId(ratingCriteriaId, clasz); } - - private LearnerItemRatingCriteria updateLearnerItemRatingCriteria(LearnerItemRatingCriteria oldCriteria, Long toolContentId, String title, Integer orderId, int ratingStyle, boolean withComments, int minWordsInComment){ - + private LearnerItemRatingCriteria updateLearnerItemRatingCriteria(LearnerItemRatingCriteria oldCriteria, + Long toolContentId, String title, Integer orderId, int ratingStyle, boolean withComments, + int minWordsInComment) { + LearnerItemRatingCriteria criteria = oldCriteria != null ? oldCriteria : new LearnerItemRatingCriteria(); criteria.setRatingCriteriaTypeId(RatingCriteria.LEARNER_ITEM_CRITERIA_TYPE); criteria.setToolContentId(toolContentId); @@ -393,7 +398,7 @@ criteria.setCommentsMinWordsLimit(minWordsInComment); criteria.setMinimumRates(null); criteria.setMaximumRates(null); - + Integer maxRating = null; switch (ratingStyle) { case RatingCriteria.RATING_STYLE_STAR: @@ -410,28 +415,30 @@ criteria.setMaxRating(maxRating); return criteria; } - + @Override - public LearnerItemRatingCriteria saveLearnerItemRatingCriteria(Long toolContentId, String title, Integer orderId, int ratingStyle, boolean withComments, int minWordsInComment) throws RatingException { + public LearnerItemRatingCriteria saveLearnerItemRatingCriteria(Long toolContentId, String title, Integer orderId, + int ratingStyle, boolean withComments, int minWordsInComment) throws RatingException { List criterias = ratingCriteriaDAO.getByToolContentId(toolContentId); LearnerItemRatingCriteria criteria = null; - if ( criterias.size() > 0 ) { - for ( RatingCriteria c : criterias ) { - if ( c.getOrderId().equals(orderId) ) - if ( ! c.isLearnerItemRatingCriteria() ) { - String msg = new StringBuilder("Wrong type of criteria found - needs to be a AuthoredItemRatingCriteria for toolContentId ") - .append(toolContentId) - .append("criteriaId ") - .append(c.getRatingCriteriaId()) + if (criterias.size() > 0) { + for (RatingCriteria c : criterias) { + if (c.getOrderId().equals(orderId)) { + if (!c.isLearnerItemRatingCriteria()) { + String msg = new StringBuilder( + "Wrong type of criteria found - needs to be a AuthoredItemRatingCriteria for toolContentId ") + .append(toolContentId).append("criteriaId ").append(c.getRatingCriteriaId()) .toString(); log.error(msg); throw new RatingException(msg); } - criteria = (LearnerItemRatingCriteria)c; + } + criteria = (LearnerItemRatingCriteria) c; break; } - } - criteria = updateLearnerItemRatingCriteria(criteria, toolContentId, title, orderId, ratingStyle, withComments, minWordsInComment); + } + criteria = updateLearnerItemRatingCriteria(criteria, toolContentId, title, orderId, ratingStyle, withComments, + minWordsInComment); ratingCriteriaDAO.saveOrUpdate(criteria); return criteria; } @@ -440,7 +447,7 @@ public int deleteAllRatingCriterias(Long toolContentId) { List criterias = ratingCriteriaDAO.getByToolContentId(toolContentId); int count = 0; - for ( RatingCriteria criteria : criterias ) { + for (RatingCriteria criteria : criterias) { ratingCriteriaDAO.deleteRatingCriteria(criteria.getRatingCriteriaId()); count++; } @@ -450,31 +457,32 @@ @Override public void saveRatingCriterias(HttpServletRequest request, Collection oldCriterias, Long toolContentId) { - + // different handling for comments - simple tag sets the isCommentsEnabled flag, // the complex tag sends explicit comment type entry. boolean explicitCommentTypeFound = false; - + // create orderId to RatingCriteria map - Map mapOrderIdToRatingCriteria = new HashMap(); + Map mapOrderIdToRatingCriteria = new HashMap<>(); for (RatingCriteria ratingCriteriaIter : oldCriterias) { mapOrderIdToRatingCriteria.put(ratingCriteriaIter.getOrderId(), ratingCriteriaIter); } - + // for ( Map.Entry entry : request.getParameterMap().entrySet()) { // log.debug("entry: "+entry.getKey()+" "+entry.getValue()); // } - + int criteriaMaxOrderId = WebUtil.readIntParam(request, "criteriaMaxOrderId"); // i is equal to an old orderId for (int i = 1; i <= criteriaMaxOrderId; i++) { String criteriaTitle = WebUtil.readStrParam(request, "criteriaTitle" + i, true); - Integer ratingStyle = WebUtil.readIntParam(request, "ratingStyle" + i, true); - if ( ratingStyle == null ) + Integer ratingStyle = WebUtil.readIntParam(request, "ratingStyle" + i, true); + if (ratingStyle == null) { ratingStyle = RatingCriteria.RATING_STYLE_STAR; - + } + Integer maxRating = WebUtil.readIntParam(request, "maxRating" + i, true); if (maxRating == null) { switch (ratingStyle) { @@ -493,19 +501,21 @@ Integer minRatings = 0; Integer maxRatings = 0; - if ( ratingStyle == RatingCriteria.RATING_STYLE_STAR || ratingStyle == RatingCriteria.RATING_STYLE_COMMENT ) { + if (ratingStyle == RatingCriteria.RATING_STYLE_STAR || ratingStyle == RatingCriteria.RATING_STYLE_COMMENT) { minRatings = WebUtil.readIntParam(request, "minimumRates" + i, true); maxRatings = WebUtil.readIntParam(request, "maximumRates" + i, true); - } - + } - boolean commentsEnabled = ( ratingStyle != RatingCriteria.RATING_STYLE_COMMENT ? WebUtil.readBooleanParam(request, "enableComments" + i, false) : true ); - + boolean commentsEnabled = (ratingStyle != RatingCriteria.RATING_STYLE_COMMENT + ? WebUtil.readBooleanParam(request, "enableComments" + i, false) + : true); + RatingCriteria ratingCriteria = mapOrderIdToRatingCriteria.get(i); - if ( ratingStyle == RatingCriteria.RATING_STYLE_COMMENT || (ratingCriteria != null && ratingCriteria.isCommentRating()) ) { + if (ratingStyle == RatingCriteria.RATING_STYLE_COMMENT + || (ratingCriteria != null && ratingCriteria.isCommentRating())) { explicitCommentTypeFound = true; } - + if (StringUtils.isNotBlank(criteriaTitle)) { int newCriteriaOrderId = WebUtil.readIntParam(request, "criteriaOrderId" + i); @@ -521,17 +531,17 @@ ratingCriteria.setRatingStyle(ratingStyle); ratingCriteria.setMaxRating(maxRating); ratingCriteria.setCommentsEnabled(commentsEnabled); - if ( commentsEnabled ) { + if (commentsEnabled) { Integer commentsMinWordsLimit = WebUtil.readIntParam(request, "commentsMinWordsLimit" + i, true); ratingCriteria.setCommentsMinWordsLimit(commentsMinWordsLimit != null ? commentsMinWordsLimit : 0); } else { ratingCriteria.setCommentsMinWordsLimit(0); } - ratingCriteria.setMinimumRates( minRatings ); - ratingCriteria.setMaximumRates( maxRatings ); - - ratingCriteriaDAO.saveOrUpdate(ratingCriteria); + ratingCriteria.setMinimumRates(minRatings); + ratingCriteria.setMaximumRates(maxRatings); + + ratingCriteriaDAO.saveOrUpdate(ratingCriteria); // !!updatedCriterias.add(ratingCriteria); // delete @@ -542,7 +552,7 @@ } // ==== handle comments criteria - simple tag support ==== - if ( ! explicitCommentTypeFound ) { + if (!explicitCommentTypeFound) { boolean isCommentsEnabled = WebUtil.readBooleanParam(request, "isCommentsEnabled", false); // find comments' responsible RatingCriteria @@ -582,76 +592,79 @@ * Convert the raw data from the database to StyledCriteriaRatingDTO and StyleRatingDTO. The rating service expects * the potential itemId followed by rating.* (its own fields) and the last item in the array to be an item * description (eg formatted user's name) Will go back to the database for the justification comment that would - * apply to hedging. - * + * apply to hedging. + * * If includeCurrentUser == true will include the current users' records (used for SelfReview and Monitoring) * otherwise skips the current user, so they do not rate themselves! - * - * Entries in Object array for comment style: - * tool item id (usually user id), rating.item_id, rating_comment.comment, (tool fields)+ - * Entries in Object array for other styles: - * tool item id (usually user id), rating.item_id, rating_comment.comment, - * rating.rating, calculated.average_rating, calculated.count_vote, (tool fields)+ + * + * Entries in Object array for comment style: + * tool item id (usually user id), rating.item_id, rating_comment.comment, (tool fields)+ + * Entries in Object array for other styles: + * tool item id (usually user id), rating.item_id, rating_comment.comment, + * rating.rating, calculated.average_rating, calculated.count_vote, (tool fields)+ */ @Override - public StyledCriteriaRatingDTO convertToStyledDTO(RatingCriteria ratingCriteria, Long currentUserId, boolean includeCurrentUser, - List rawDataRows) { + public StyledCriteriaRatingDTO convertToStyledDTO(RatingCriteria ratingCriteria, Long currentUserId, + boolean includeCurrentUser, List rawDataRows) { StyledCriteriaRatingDTO criteriaDto = new StyledCriteriaRatingDTO(); criteriaDto.setRatingCriteria(ratingCriteria); - if (ratingCriteria.isHedgeStyleRating() && ratingCriteria.isCommentsEnabled() ) { + if (ratingCriteria.isHedgeStyleRating() && ratingCriteria.isCommentsEnabled()) { RatingComment justification = ratingCommentDAO.getComment(ratingCriteria.getRatingCriteriaId(), currentUserId.intValue(), ratingCriteria.getRatingCriteriaId()); - if (justification != null) + if (justification != null) { criteriaDto.setJustificationComment(justification.getComment()); - } else if ( ratingCriteria.isStarStyleRating() ) { - int ratedCount = getCountItemsRatedByUserByCriteria(ratingCriteria.getRatingCriteriaId(), currentUserId.intValue()); + } + } else if (ratingCriteria.isStarStyleRating()) { + int ratedCount = getCountItemsRatedByUserByCriteria(ratingCriteria.getRatingCriteriaId(), + currentUserId.intValue()); criteriaDto.setCountRatedItems(ratedCount); } boolean isComment = ratingCriteria.isCommentRating(); - if ( rawDataRows != null ) { + if (rawDataRows != null) { - List ratingDtos = new ArrayList(); + List ratingDtos = new ArrayList<>(); criteriaDto.setRatingDtos(ratingDtos); - NumberFormat numberFormat = NumberFormat.getInstance(Locale.US); numberFormat.setMaximumFractionDigits(1); for (Object[] row : rawDataRows) { int numColumns = row.length; - if ( ( isComment && numColumns < 4 ) || ( !isComment && numColumns < 7) ) { + if ((isComment && numColumns < 4) || (!isComment && numColumns < 7)) { StringBuffer buf = new StringBuffer("convertToStyledDTO: ratingCriteria") .append(ratingCriteria.getRatingCriteriaId()).append(" UserId: ").append(currentUserId) .append(" Skipping data row as there are not enough columns. Only ").append(numColumns) .append(" columns. numColumns: ").append(numColumns); - if (numColumns > 0) + if (numColumns > 0) { buf.append(" Data: 0:").append(row[0]); - if (numColumns > 1) + } + if (numColumns > 1) { buf.append(" 1:").append(row[1]); + } log.error(buf.toString()); break; } long itemId = ((BigInteger) row[0]).longValue(); - if ( includeCurrentUser || itemId != currentUserId) { + if (includeCurrentUser || itemId != currentUserId) { - if (row[1] != null && itemId != ((BigInteger) row[0]).longValue() ) { - log.error("convertToStyledDTO: ratingCriteria" + ratingCriteria.getRatingCriteriaId() + " UserId: " - + currentUserId + " Potential issue: expected item id " + row[0] + " does match real item id " - + row[1] + ". Data: 0:" + row[0] + " 1:" + row[1]); + if (row[1] != null && itemId != ((BigInteger) row[0]).longValue()) { + log.error("convertToStyledDTO: ratingCriteria" + ratingCriteria.getRatingCriteriaId() + + " UserId: " + currentUserId + " Potential issue: expected item id " + row[0] + + " does match real item id " + row[1] + ". Data: 0:" + row[0] + " 1:" + row[1]); } - + StyledRatingDTO dto = new StyledRatingDTO(((BigInteger) row[0]).longValue()); dto.setComment((String) row[2]); dto.setItemDescription( row[numColumns - 2] != null ? row[numColumns - 2].toString() : null); dto.setItemDescription2( row[numColumns - 1] != null ? row[numColumns - 1].toString() : null); - if ( ! isComment ) { - dto.setUserRating(row[3] == null ? "" : numberFormat.format((Double) row[3])); - dto.setAverageRating(row[4] == null ? "" : numberFormat.format((Double) row[4])); - dto.setNumberOfVotes(row[5] == null ? "" : numberFormat.format((BigInteger) row[5])); + if (!isComment) { + dto.setUserRating(row[3] == null ? "" : numberFormat.format(row[3])); + dto.setAverageRating(row[4] == null ? "" : numberFormat.format(row[4])); + dto.setNumberOfVotes(row[5] == null ? "" : numberFormat.format(row[5])); } ratingDtos.add(dto); } @@ -662,96 +675,100 @@ } /** - * Convert the raw data from the database to JSON, similar on StyledCriteriaRatingDTO and StyleRatingDTO. + * Convert the raw data from the database to JSON, similar on StyledCriteriaRatingDTO and StyleRatingDTO. * The rating service expects the potential itemId followed by rating.* (its own fields) and the last two items * in the array will be two item descriptions fields (eg formatted user's name, portrait id). Will go back to * the database for the justification comment that would apply to hedging. * * If includeCurrentUser == true will include the current users' records (used for SelfReview and Monitoring) * otherwise skips the current user, so they do not rate themselves! - * + * * toolSessionId is only used to calculate the number of users who have rated an item, so it may be null * if the tool doesn't need to seperate session (Peer Review doesn't need to separate by sessions). - * + * * In JSON for use with tablesorter. - * Entries in Object array for comment style: - * tool item id (usually user id), rating.item_id, rating_comment.comment, (tool fields)+ - * Entries in Object array for other styles: - * tool item id (usually user id), rating.item_id, rating_comment.comment, - * rating.rating, calculated.average_rating, calculated.count_vote, (tool fields)+ - * @throws JSONException + * Entries in Object array for comment style: + * tool item id (usually user id), rating.item_id, rating_comment.comment, (tool fields)+ + * Entries in Object array for other styles: + * tool item id (usually user id), rating.item_id, rating_comment.comment, + * rating.rating, calculated.average_rating, calculated.count_vote, (tool fields)+ + * + * @throws JSONException */ @Override - public JSONArray convertToStyledJSON(RatingCriteria ratingCriteria, Long toolSessionId, Long currentUserId, boolean includeCurrentUser, - List rawDataRows, boolean needRatesPerUser) throws JSONException { + public ArrayNode convertToStyledJSON(RatingCriteria ratingCriteria, Long toolSessionId, Long currentUserId, + boolean includeCurrentUser, List rawDataRows, boolean needRatesPerUser) { - JSONArray rows = new JSONArray(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); boolean isComment = ratingCriteria.isCommentRating(); - if ( rawDataRows != null ) { + if (rawDataRows != null) { - List itemIds = needRatesPerUser ? new ArrayList(rawDataRows.size()) : null; + List itemIds = needRatesPerUser ? new ArrayList<>(rawDataRows.size()) : null; NumberFormat numberFormat = NumberFormat.getInstance(Locale.US); numberFormat.setMaximumFractionDigits(1); for (Object[] row : rawDataRows) { int numColumns = row.length; - if ( ( isComment && numColumns < 4 ) || ( !isComment && numColumns < 7) ) { + if ((isComment && numColumns < 4) || (!isComment && numColumns < 7)) { StringBuffer buf = new StringBuffer("convertToStyledJSON: ratingCriteria") .append(ratingCriteria.getRatingCriteriaId()).append(" UserId: ").append(currentUserId) .append(" Skipping data row as there are not enough columns. Only ").append(numColumns) .append(" columns. numColumns: ").append(numColumns); - if (numColumns > 0) + if (numColumns > 0) { buf.append(" Data: 0:").append(row[0]); - if (numColumns > 1) + } + if (numColumns > 1) { buf.append(" 1:").append(row[1]); + } log.error(buf.toString()); break; } - + Long itemId = ((BigInteger) row[0]).longValue(); - if ( includeCurrentUser || itemId != currentUserId) { + if (includeCurrentUser || itemId != currentUserId) { - if (row[1] != null && itemId.longValue() != ((BigInteger) row[0]).longValue() ) { - log.error("convertToStyledJSON: ratingCriteria" + ratingCriteria.getRatingCriteriaId() + " UserId: " - + currentUserId + " Potential issue: expected item id " + row[0] + " does match real item id " - + row[1] + ". Data: 0:" + row[0] + " 1:" + row[1]); + if (row[1] != null && itemId.longValue() != ((BigInteger) row[0]).longValue()) { + log.error("convertToStyledJSON: ratingCriteria" + ratingCriteria.getRatingCriteriaId() + + " UserId: " + currentUserId + " Potential issue: expected item id " + row[0] + + " does match real item id " + row[1] + ". Data: 0:" + row[0] + " 1:" + row[1]); } - - JSONObject userRow = new JSONObject(); + + ObjectNode userRow = JsonNodeFactory.instance.objectNode(); userRow.put("itemId", itemId); userRow.put("comment", row[2] == null ? "" : (String) row[2]); userRow.put("itemDescription", row[numColumns - 2] == null ? "" : row[numColumns - 2].toString()); userRow.put("itemDescription2", row[numColumns - 1] == null ? "" : row[numColumns - 1].toString()); - if ( ! isComment ) { - userRow.put("userRating", row[3] == null ? "" : numberFormat.format((Double) row[3])); - userRow.put("averageRating", row[4] == null ? "" : numberFormat.format((Double) row[4])); - userRow.put("numberOfVotes", row[5] == null ? "" : numberFormat.format((BigInteger) row[5])); + if (!isComment) { + userRow.put("userRating", row[3] == null ? "" : numberFormat.format(row[3])); + userRow.put("averageRating", row[4] == null ? "" : numberFormat.format(row[4])); + userRow.put("numberOfVotes", row[5] == null ? "" : numberFormat.format(row[5])); } else { // don't have missing entries in JSON or an exception can occur if you try to access them - userRow.put("userRating", ""); - userRow.put("averageRating", ""); - userRow.put("numberOfVotes", ""); + userRow.put("userRating", ""); + userRow.put("averageRating", ""); + userRow.put("numberOfVotes", ""); } - rows.put(userRow); - - if ( needRatesPerUser ) + rows.add(userRow); + + if (needRatesPerUser) { itemIds.add(itemId); + } } } - - if ( needRatesPerUser ) { - Map countUsersRatedEachItemMap = ratingDAO.countUsersRatedEachItemByCriteria(ratingCriteria.getRatingCriteriaId(), toolSessionId, itemIds, -1); - for ( int i=0; i < rows.length(); i++ ) { - JSONObject row = rows.getJSONObject(i); - Long count = countUsersRatedEachItemMap.get(row.get("itemId")); - row.put("ratesPerUser", count != null ? count : 0); + + if (needRatesPerUser) { + Map countUsersRatedEachItemMap = ratingDAO.countUsersRatedEachItemByCriteria( + ratingCriteria.getRatingCriteriaId(), toolSessionId, itemIds, -1); + for (JsonNode row : rows) { + Long count = countUsersRatedEachItemMap.get(JsonUtil.optLong(row, "itemId")); + ((ObjectNode) row).put("ratesPerUser", count == null ? 0 : count); } } } - + return rows; } Index: lams_common/src/java/org/lamsfoundation/lams/util/WebUtil.java =================================================================== diff -u -rb3c871874679a1d784db0d7dfac2fdabe65baf83 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_common/src/java/org/lamsfoundation/lams/util/WebUtil.java (.../WebUtil.java) (revision b3c871874679a1d784db0d7dfac2fdabe65baf83) +++ lams_common/src/java/org/lamsfoundation/lams/util/WebUtil.java (.../WebUtil.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -1,12 +1,8 @@ package org.lamsfoundation.lams.util; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; -import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.security.Principal; @@ -17,13 +13,14 @@ import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.tool.ToolAccessMode; import org.lamsfoundation.lams.tool.exception.ToolException; import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.web.util.AttributeNames; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * helper methods useful for servlets */ @@ -368,7 +365,7 @@ } throw new IllegalArgumentException("[" + modeValue + "] is not a legal mode" + "in LAMS"); } - + /** * Get ToolAccessMode from HttpRequest parameters. Default value is AUTHOR mode. * @@ -377,7 +374,7 @@ */ public static ToolAccessMode readToolAccessModeAuthorDefaulted(HttpServletRequest request) { String modeStr = request.getParameter(AttributeNames.ATTR_MODE); - + ToolAccessMode mode; if (StringUtils.equalsIgnoreCase(modeStr, ToolAccessMode.TEACHER.toString())) { mode = ToolAccessMode.TEACHER; @@ -553,8 +550,8 @@ /** * Produces JSON object with basic user details. */ - public static JSONObject userToJSON(User user) throws JSONException { - JSONObject userJSON = new JSONObject(); + public static ObjectNode userToJSON(User user) { + ObjectNode userJSON = JsonNodeFactory.instance.objectNode(); userJSON.put("id", user.getUserId()); userJSON.put("firstName", user.getFirstName()); userJSON.put("lastName", user.getLastName()); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java =================================================================== diff -u -r60d9a173d5590295376322fc3e857ae2dca37717 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 60d9a173d5590295376322fc3e857ae2dca37717) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -23,6 +23,7 @@ package org.lamsfoundation.lams.tool.assessment.service; +import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.sql.Timestamp; import java.util.ArrayList; @@ -48,9 +49,6 @@ import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.events.IEventNotificationService; import org.lamsfoundation.lams.gradebook.service.IGradebookService; import org.lamsfoundation.lams.learning.service.ILearnerService; @@ -112,6 +110,10 @@ import org.lamsfoundation.lams.util.NumberUtil; import org.lamsfoundation.lams.util.audit.IAuditService; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * @author Andrey Balan */ @@ -438,7 +440,7 @@ @Override public void setAttemptStarted(Assessment assessment, AssessmentUser assessmentUser, Long toolSessionId) { Set questions = assessment.getQuestions(); - + AssessmentResult lastResult = getLastAssessmentResult(assessment.getUid(), assessmentUser.getUserId()); if (lastResult != null) { @@ -467,7 +469,7 @@ assessmentResultDao.saveObject(lastResult); return; - // mark previous attempt as being not the latest any longer + // mark previous attempt as being not the latest any longer } else { lastResult.setLatest(false); assessmentResultDao.saveObject(lastResult); @@ -538,7 +540,8 @@ for (QuestionDTO questionDto : questionsForOnePage) { // in case single MarkHedging question needs to be stored -- search for that question - if ((singleMarkHedgingQuestionUid != null) && !questionDto.getUid().equals(singleMarkHedgingQuestionUid)) { + if ((singleMarkHedgingQuestionUid != null) + && !questionDto.getUid().equals(singleMarkHedgingQuestionUid)) { continue; } @@ -595,24 +598,24 @@ * @param isAutosave * in case of autosave there is no need to calculate marks * @return grade that user scored by answering that question - * @throws NoSuchMethodException - * @throws InvocationTargetException - * @throws IllegalAccessException + * @throws NoSuchMethodException + * @throws InvocationTargetException + * @throws IllegalAccessException */ - private float storeUserAnswer(AssessmentResult assessmentResult, QuestionDTO questionDto, boolean isAutosave) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + private float storeUserAnswer(AssessmentResult assessmentResult, QuestionDTO questionDto, boolean isAutosave) + throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { Assessment assessment = assessmentResult.getAssessment(); - + AssessmentQuestionResult questionResult = null; // get questionResult from DB instance of AssessmentResult for (AssessmentQuestionResult questionResultIter : assessmentResult.getQuestionResults()) { if (questionDto.getUid().equals(questionResultIter.getAssessmentQuestion().getUid())) { questionResult = questionResultIter; } } - - //if teacher edited content in monitor (modified question) it led to removal if autosaved questionResult - if (assessment.isContentModifiedInMonitor(assessmentResult.getStartDate()) - && questionResult == null) { + + //if teacher edited content in monitor (modified question) it led to removal if autosaved questionResult + if (assessment.isContentModifiedInMonitor(assessmentResult.getStartDate()) && questionResult == null) { //update questionDto AssessmentQuestion modifiedQuestion = assessmentQuestionDao.getByUid(questionDto.getUid()); QuestionDTO updatedQuestionDto = modifiedQuestion.getQuestionDTO(); @@ -704,7 +707,8 @@ java.util.regex.Pattern.CASE_INSENSITIVE | java.util.regex.Pattern.UNICODE_CASE); } boolean isAnswerMatchedCurrentOption = (questionDto.getAnswerString() != null) - ? pattern.matcher(questionDto.getAnswerString().trim()).matches() : false; + ? pattern.matcher(questionDto.getAnswerString().trim()).matches() + : false; if (isAnswerMatchedCurrentOption) { mark = optionDto.getGrade() * maxMark; @@ -720,7 +724,8 @@ boolean isAnswerMatchedCurrentOption = false; try { float answerFloat = Float.valueOf(questionDto.getAnswerString()); - isAnswerMatchedCurrentOption = ((answerFloat >= (optionDto.getOptionFloat() - optionDto.getAcceptedError())) + isAnswerMatchedCurrentOption = ((answerFloat >= (optionDto.getOptionFloat() + - optionDto.getAcceptedError())) && (answerFloat <= (optionDto.getOptionFloat() + optionDto.getAcceptedError()))); } catch (Exception e) { } @@ -738,7 +743,8 @@ answerFloat = answerFloat / unit.getMultiplier(); isAnswerMatchedCurrentOption = ((answerFloat >= (optionDto.getOptionFloat() - optionDto.getAcceptedError())) - && (answerFloat <= (optionDto.getOptionFloat() + optionDto.getAcceptedError()))); + && (answerFloat <= (optionDto.getOptionFloat() + + optionDto.getAcceptedError()))); if (isAnswerMatchedCurrentOption) { break; } @@ -756,15 +762,16 @@ } } else if (questionDto.getType() == AssessmentConstants.QUESTION_TYPE_TRUE_FALSE) { - if ((questionDto.getAnswerBoolean() == questionDto.getCorrectAnswer()) && (questionDto.getAnswerString() != null)) { + if ((questionDto.getAnswerBoolean() == questionDto.getCorrectAnswer()) + && (questionDto.getAnswerString() != null)) { mark = maxMark; } } else if (questionDto.getType() == AssessmentConstants.QUESTION_TYPE_ORDERING) { float maxMarkForCorrectAnswer = maxMark / questionDto.getOptionDtos().size(); - TreeSet correctOptionSet = new TreeSet(new SequencableComparator()); + TreeSet correctOptionSet = new TreeSet<>(new SequencableComparator()); correctOptionSet.addAll(questionDto.getOptionDtos()); - ArrayList correctOptionList = new ArrayList(correctOptionSet); + ArrayList correctOptionList = new ArrayList<>(correctOptionSet); int i = 0; for (OptionDTO optionDto : questionDto.getOptionDtos()) { if (optionDto.getUid() == correctOptionList.get(i++).getUid()) { @@ -933,7 +940,7 @@ @Override public List getReflectList(Long contentId) { - List reflectList = new LinkedList(); + List reflectList = new LinkedList<>(); List sessionList = assessmentSessionDao.getByContentId(contentId); for (AssessmentSession session : sessionList) { @@ -984,22 +991,28 @@ @Override public List getSessionDtos(Long contentId, boolean includeStatistics) { - List sessionDtos = new ArrayList(); + List sessionDtos = new ArrayList<>(); List sessionList = assessmentSessionDao.getByContentId(contentId); for (AssessmentSession session : sessionList) { Long sessionId = session.getSessionId(); SessionDTO sessionDto = new SessionDTO(sessionId, session.getSessionName()); //for statistics tab - if ( includeStatistics ) { + if (includeStatistics) { int countUsers = assessmentUserDao.getCountUsersBySession(sessionId, ""); sessionDto.setNumberLearners(countUsers); Object[] markStats = assessmentUserDao.getStatsMarksBySession(sessionId); - if ( markStats != null ) { - sessionDto.setMinMark(markStats[0] != null ? NumberUtil.formatLocalisedNumber((Float)markStats[0], (Locale)null, 2) : "0.00"); - sessionDto.setAvgMark(markStats[1] != null ? NumberUtil.formatLocalisedNumber((Float)markStats[1], (Locale)null, 2) : "0.00"); - sessionDto.setMaxMark(markStats[2] != null ? NumberUtil.formatLocalisedNumber((Float)markStats[2], (Locale)null, 2) : "0.00"); + if (markStats != null) { + sessionDto.setMinMark(markStats[0] != null + ? NumberUtil.formatLocalisedNumber((Float) markStats[0], (Locale) null, 2) + : "0.00"); + sessionDto.setAvgMark(markStats[1] != null + ? NumberUtil.formatLocalisedNumber((Float) markStats[1], (Locale) null, 2) + : "0.00"); + sessionDto.setMaxMark(markStats[2] != null + ? NumberUtil.formatLocalisedNumber((Float) markStats[2], (Locale) null, 2) + : "0.00"); } } @@ -1013,20 +1026,26 @@ public LeaderResultsDTO getLeaderResultsDTOForLeaders(Long contentId) { LeaderResultsDTO newDto = new LeaderResultsDTO(contentId); Object[] markStats = assessmentUserDao.getStatsMarksForLeaders(contentId); - if ( markStats != null ) { - newDto.setMinMark(markStats[0] != null ? NumberUtil.formatLocalisedNumber((Float)markStats[0], (Locale)null, 2) : "0.00"); - newDto.setAvgMark(markStats[1] != null ? NumberUtil.formatLocalisedNumber((Float)markStats[1], (Locale)null, 2) : "0.00"); - newDto.setMaxMark(markStats[2] != null ? NumberUtil.formatLocalisedNumber((Float)markStats[2], (Locale)null, 2) : "0.00"); - newDto.setNumberGroupsLeaderFinished((Integer)markStats[3]); + if (markStats != null) { + newDto.setMinMark( + markStats[0] != null ? NumberUtil.formatLocalisedNumber((Float) markStats[0], (Locale) null, 2) + : "0.00"); + newDto.setAvgMark( + markStats[1] != null ? NumberUtil.formatLocalisedNumber((Float) markStats[1], (Locale) null, 2) + : "0.00"); + newDto.setMaxMark( + markStats[2] != null ? NumberUtil.formatLocalisedNumber((Float) markStats[2], (Locale) null, 2) + : "0.00"); + newDto.setNumberGroupsLeaderFinished((Integer) markStats[3]); } return newDto; } - + @Override public AssessmentResultDTO getUserMasterDetail(Long sessionId, Long userId) { AssessmentResultDTO resultDto = new AssessmentResultDTO(); resultDto.setSessionId(sessionId); - + AssessmentResult lastFinishedResult = assessmentResultDao.getLastFinishedAssessmentResultByUser(sessionId, userId); if (lastFinishedResult != null) { @@ -1035,13 +1054,13 @@ Set questionResults = lastFinishedResult.getQuestionResults(); //prepare list of the questions to display in user master detail table, filtering out questions that aren't supposed to be answered - SortedSet questionResultsToDisplay = new TreeSet( + SortedSet questionResultsToDisplay = new TreeSet<>( new AssessmentQuestionResultComparator()); //in case there is at least one random question - we need to show all questions if (assessment.hasRandomQuestion()) { questionResultsToDisplay.addAll(questionResults); - //otherwise show only questions from the question list + //otherwise show only questions from the question list } else { for (QuestionReference reference : questionReferences) { for (AssessmentQuestionResult questionResult : questionResults) { @@ -1063,7 +1082,7 @@ @Override public UserSummary getUserSummary(Long contentId, Long userId, Long sessionId) { Assessment assessment = assessmentDao.getByContentId(contentId); - + UserSummary userSummary = new UserSummary(); AssessmentUser user = assessmentUserDao.getUserByUserIDAndSessionID(userId, sessionId); userSummary.setUser(user); @@ -1078,11 +1097,11 @@ if (lastFinishedResult != null) { userSummary.setLastAttemptGrade(lastFinishedResult.getGrade()); } - + if (!results.isEmpty()) { //prepare list of the questions to display, filtering out questions that aren't supposed to be answered - Set questions = new TreeSet(); + Set questions = new TreeSet<>(); //in case there is at least one random question - we need to show all questions in a drop down select if (assessment.hasRandomQuestion()) { questions.addAll(assessment.getQuestions()); @@ -1095,12 +1114,12 @@ } //prepare list of UserSummaryItems - ArrayList userSummaryItems = new ArrayList(); + ArrayList userSummaryItems = new ArrayList<>(); for (AssessmentQuestion question : questions) { UserSummaryItem userSummaryItem = new UserSummaryItem(question); //find all questionResults that correspond to the current question - List questionResults = new ArrayList(); + List questionResults = new ArrayList<>(); for (AssessmentResult result : results) { for (AssessmentQuestionResult questionResult : result.getQuestionResults()) { if (question.getUid().equals(questionResult.getAssessmentQuestion().getUid())) { @@ -1135,27 +1154,27 @@ @Override public Map getQuestionSummaryForExport(Assessment assessment) { - Map questionSummaries = new LinkedHashMap(); + Map questionSummaries = new LinkedHashMap<>(); if (assessment.getQuestions() == null) { return questionSummaries; } - SortedSet sessions = new TreeSet(new AssessmentSessionComparator()); + SortedSet sessions = new TreeSet<>(new AssessmentSessionComparator()); sessions.addAll(assessmentSessionDao.getByContentId(assessment.getContentId())); List assessmentResults = assessmentResultDao .getLastFinishedAssessmentResults(assessment.getContentId()); - Map userUidToResultMap = new HashMap(); + Map userUidToResultMap = new HashMap<>(); for (AssessmentResult assessmentResult : assessmentResults) { userUidToResultMap.put(assessmentResult.getUser().getUid(), assessmentResult); } - Map> sessionIdToUsersMap = new HashMap>(); + Map> sessionIdToUsersMap = new HashMap<>(); for (AssessmentSession session : sessions) { Long sessionId = session.getSessionId(); - List users = new ArrayList(); + List users = new ArrayList<>(); // in case of leader aware tool show only leaders' responses if (assessment.isUseSelectLeaderToolOuput()) { @@ -1175,14 +1194,14 @@ QuestionSummary questionSummary = new QuestionSummary(); questionSummary.setQuestion(question); - List> questionResults = new ArrayList>(); + List> questionResults = new ArrayList<>(); for (AssessmentSession session : sessions) { Long sessionId = session.getSessionId(); List users = sessionIdToUsersMap.get(sessionId); - ArrayList sessionQuestionResults = new ArrayList(); + ArrayList sessionQuestionResults = new ArrayList<>(); for (AssessmentUser user : users) { AssessmentResult assessmentResult = userUidToResultMap.get(user.getUid()); AssessmentQuestionResult questionResult = null; @@ -1231,12 +1250,12 @@ @Override public LinkedHashMap exportSummary(Assessment assessment, List sessionDtos, boolean showUserNames) { - LinkedHashMap dataToExport = new LinkedHashMap(); + LinkedHashMap dataToExport = new LinkedHashMap<>(); final ExcelCell[] EMPTY_ROW = new ExcelCell[0]; // -------------- First tab: Summary ---------------------------------------------------- if (showUserNames) { - ArrayList summaryTab = new ArrayList(); + ArrayList summaryTab = new ArrayList<>(); if (sessionDtos != null) { for (SessionDTO sessionDTO : sessionDtos) { @@ -1247,8 +1266,8 @@ ExcelCell[] sessionTitle = new ExcelCell[1]; sessionTitle[0] = new ExcelCell(sessionDTO.getSessionName(), true); summaryTab.add(sessionTitle); - - List userDtos = new ArrayList(); + + List userDtos = new ArrayList<>(); // in case of UseSelectLeaderToolOuput - display only one user if (assessment.isUseSelectLeaderToolOuput()) { @@ -1274,12 +1293,15 @@ userDtos = getPagedUsersBySession(sessionId, 0, countSessionUsers, "userName", "ASC", ""); } - ArrayList summaryTabLearnerList = new ArrayList(); - + ArrayList summaryTabLearnerList = new ArrayList<>(); + ExcelCell[] summaryRowTitle = new ExcelCell[3]; - summaryRowTitle[0] = new ExcelCell(getMessage("label.export.user.id"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[1] = new ExcelCell(getMessage("label.monitoring.summary.user.name"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[2] = new ExcelCell(getMessage("label.monitoring.summary.total"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryRowTitle[0] = new ExcelCell(getMessage("label.export.user.id"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryRowTitle[1] = new ExcelCell(getMessage("label.monitoring.summary.user.name"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryRowTitle[2] = new ExcelCell(getMessage("label.monitoring.summary.total"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); summaryTabLearnerList.add(summaryRowTitle); float minGrade = -9999999; @@ -1294,18 +1316,22 @@ userResultRow[2] = new ExcelCell(grade, false); summaryTabLearnerList.add(userResultRow); - if ( grade < minGrade || minGrade == -9999999 ) + if (grade < minGrade || minGrade == -9999999) { minGrade = grade; - if ( grade > maxGrade ) + } + if (grade > maxGrade) { maxGrade = grade; + } } - if ( minGrade == -9999999) + if (minGrade == -9999999) { minGrade = 0; + } - LinkedHashMap markSummary = getMarksSummaryForSession(userDtos, minGrade, maxGrade, 10); + LinkedHashMap markSummary = getMarksSummaryForSession(userDtos, minGrade, maxGrade, + 10); // work out total marks so we can do percentages. need as float for the correct divisions int totalNumEntries = 0; - for ( Map.Entry entry : markSummary.entrySet() ) { + for (Map.Entry entry : markSummary.entrySet()) { totalNumEntries += entry.getValue(); } @@ -1317,25 +1343,29 @@ summaryTab.add(minMaxRow); minMaxRow = new ExcelCell[2]; minMaxRow[0] = new ExcelCell(getMessage("label.lowest.mark"), true); - minMaxRow[1] = new ExcelCell((double)minGrade, false); + minMaxRow[1] = new ExcelCell((double) minGrade, false); summaryTab.add(minMaxRow); minMaxRow = new ExcelCell[2]; minMaxRow[0] = new ExcelCell(getMessage("label.highest.mark"), true); - minMaxRow[1] = new ExcelCell((double)maxGrade, false); + minMaxRow[1] = new ExcelCell((double) maxGrade, false); summaryTab.add(minMaxRow); - + summaryTab.add(EMPTY_ROW); ExcelCell[] binSummaryRow = new ExcelCell[3]; - binSummaryRow[0] = new ExcelCell(getMessage("label.authoring.basic.list.header.mark"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - binSummaryRow[1] = new ExcelCell(getMessage("label.number.learners"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - binSummaryRow[2] = new ExcelCell(getMessage("label.percentage"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); + binSummaryRow[0] = new ExcelCell(getMessage("label.authoring.basic.list.header.mark"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + binSummaryRow[1] = new ExcelCell(getMessage("label.number.learners"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + binSummaryRow[2] = new ExcelCell(getMessage("label.percentage"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); summaryTab.add(binSummaryRow); - float totalNumEntriesAsFloat = (float) totalNumEntries; - for ( Map.Entry entry : markSummary.entrySet() ) { + float totalNumEntriesAsFloat = totalNumEntries; + for (Map.Entry entry : markSummary.entrySet()) { binSummaryRow = new ExcelCell[3]; - binSummaryRow[0] = new ExcelCell(entry.getKey(),false); - binSummaryRow[1] = new ExcelCell(entry.getValue(),false); - binSummaryRow[2] = new ExcelCell(Math.round(entry.getValue() / totalNumEntriesAsFloat * 100),false); + binSummaryRow[0] = new ExcelCell(entry.getKey(), false); + binSummaryRow[1] = new ExcelCell(entry.getValue(), false); + binSummaryRow[2] = new ExcelCell(Math.round(entry.getValue() / totalNumEntriesAsFloat * 100), + false); summaryTab.add(binSummaryRow); } summaryTab.add(EMPTY_ROW); @@ -1352,7 +1382,7 @@ // ------------------------------------------------------------------ // -------------- Second tab: Question Summary ---------------------- - ArrayList questionSummaryTab = new ArrayList(); + ArrayList questionSummaryTab = new ArrayList<>(); // Create the question summary ExcelCell[] summaryTitle = new ExcelCell[1]; @@ -1392,13 +1422,13 @@ ExcelCell.BORDER_STYLE_BOTTOM_THIN); int questionNumber = 1; - + for (AssessmentQuestion question : questions) { int colsNum = showUserNames ? 10 : 9; ExcelCell[] questionTitle = new ExcelCell[1]; - questionTitle[0] = new ExcelCell(getMessage("label.monitoring.question.summary.question") + " " - + questionNumber++, true); + questionTitle[0] = new ExcelCell( + getMessage("label.monitoring.question.summary.question") + " " + questionNumber++, true); questionSummaryTab.add(questionTitle); // set up the summary table data for the top of the question area. @@ -1408,16 +1438,16 @@ || question.getType() == AssessmentConstants.QUESTION_TYPE_TRUE_FALSE; // For MC, Numeric & Short Answer Key is optionUid, Value is number of answers // For True/False Key 0 is false and Key 1 is true - Map summaryOfAnswers = new HashMap(); + Map summaryOfAnswers = new HashMap<>(); Integer summaryNACount = 0; Long trueKey = 1L; Long falseKey = 0L; if (doSummaryTable) { questionSummaryTab.add(startSummaryTable(question, summaryOfAnswers, trueKey, falseKey)); } - - ArrayList questionSummaryTabTemp = new ArrayList(); + ArrayList questionSummaryTabTemp = new ArrayList<>(); + //add question title row if (question.getType() == AssessmentConstants.QUESTION_TYPE_MARK_HEDGING) { count = 0; @@ -1498,9 +1528,10 @@ } else { userResultRow[count++] = new ExcelCell( AssessmentEscapeUtils.printResponsesForExcelExport(questionResult), false); - - if ( doSummaryTable ) { - summaryNACount = updateSummaryCounts(question, questionResult, summaryOfAnswers, summaryNACount); + + if (doSummaryTable) { + summaryNACount = updateSummaryCounts(question, questionResult, summaryOfAnswers, + summaryNACount); } } @@ -1528,10 +1559,11 @@ } if (doSummaryTable) { - questionSummaryTab.add(outputSummaryTable(question, summaryOfAnswers, summaryNACount, trueKey, falseKey)); + questionSummaryTab + .add(outputSummaryTable(question, summaryOfAnswers, summaryNACount, trueKey, falseKey)); questionSummaryTab.add(EMPTY_ROW); } - + // Calculating the averages ExcelCell[] averageRow; @@ -1567,7 +1599,7 @@ questionSummaryTab.addAll(questionSummaryTabTemp); questionSummaryTab.add(averageRow); questionSummaryTab.add(EMPTY_ROW); - + } } @@ -1577,24 +1609,29 @@ // ------------------------------------------------------------------ // -------------- Third tab: User Summary --------------------------- - ArrayList userSummaryTab = new ArrayList(); + ArrayList userSummaryTab = new ArrayList<>(); // Create the question summary ExcelCell[] userSummaryTitle = new ExcelCell[1]; userSummaryTitle[0] = new ExcelCell(getMessage("label.export.user.summary"), true); userSummaryTab.add(userSummaryTitle); ExcelCell[] summaryRowTitle = new ExcelCell[5]; - summaryRowTitle[0] = new ExcelCell(getMessage("label.monitoring.question.summary.question"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[1] = new ExcelCell(getMessage("label.authoring.basic.list.header.type"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[2] = new ExcelCell(getMessage("label.authoring.basic.penalty.factor"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[3] = new ExcelCell(getMessage("label.monitoring.question.summary.default.mark"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[4] = new ExcelCell(getMessage("label.monitoring.question.summary.average.mark"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryRowTitle[0] = new ExcelCell(getMessage("label.monitoring.question.summary.question"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryRowTitle[1] = new ExcelCell(getMessage("label.authoring.basic.list.header.type"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryRowTitle[2] = new ExcelCell(getMessage("label.authoring.basic.penalty.factor"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryRowTitle[3] = new ExcelCell(getMessage("label.monitoring.question.summary.default.mark"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryRowTitle[4] = new ExcelCell(getMessage("label.monitoring.question.summary.average.mark"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); userSummaryTab.add(summaryRowTitle); Float totalGradesPossible = new Float(0); Float totalAverage = new Float(0); if (assessment.getQuestionReferences() != null) { - Set questionReferences = new TreeSet(new SequencableComparator()); + Set questionReferences = new TreeSet<>(new SequencableComparator()); questionReferences.addAll(assessment.getQuestionReferences()); int randomQuestionsCount = 1; @@ -1650,7 +1687,7 @@ if (sessionDtos != null) { List assessmentResults = assessmentResultDao .getLastFinishedAssessmentResults(assessment.getContentId()); - Map userUidToResultMap = new HashMap(); + Map userUidToResultMap = new HashMap<>(); for (AssessmentResult assessmentResult : assessmentResults) { userUidToResultMap.put(assessmentResult.getUser().getUid(), assessmentResult); } @@ -1762,30 +1799,26 @@ summaryTable = new ExcelCell[question.getOptions().size() + 1]; for (AssessmentQuestionOption option : question.getOptions()) { summaryOfAnswers.put(option.getUid(), 0); - StringBuilder bldr = new StringBuilder(getMessage("label.authoring.basic.option.answer")) - .append(" ") - .append(i + 1) - .append(" - "); - if ( question.getType() == AssessmentConstants.QUESTION_TYPE_NUMERICAL ) { - bldr.append(option.getOptionFloat()) - .append(" +- ") - .append(option.getAcceptedError()); + StringBuilder bldr = new StringBuilder(getMessage("label.authoring.basic.option.answer")).append(" ") + .append(i + 1).append(" - "); + if (question.getType() == AssessmentConstants.QUESTION_TYPE_NUMERICAL) { + bldr.append(option.getOptionFloat()).append(" +- ").append(option.getAcceptedError()); } else { bldr.append(option.getOptionString().replaceAll("\\<.*?\\>", "")); } summaryTable[i] = new ExcelCell(bldr.toString(), false); i++; } - if ( question.getType() == AssessmentConstants.QUESTION_TYPE_MULTIPLE_CHOICE ) { - summaryTable[i++] = new ExcelCell(getMessage("label.not.answered"), false); + if (question.getType() == AssessmentConstants.QUESTION_TYPE_MULTIPLE_CHOICE) { + summaryTable[i++] = new ExcelCell(getMessage("label.not.answered"), false); } else { - summaryTable[i++] = new ExcelCell(getMessage("label.other"), false); + summaryTable[i++] = new ExcelCell(getMessage("label.other"), false); } } else { summaryTable = new ExcelCell[3]; summaryTable[0] = new ExcelCell(getMessage("label.authoring.true.false.true"), false); summaryTable[1] = new ExcelCell(getMessage("label.authoring.true.false.false"), false); - summaryTable[2] = new ExcelCell(getMessage("label.not.answered"), false); + summaryTable[2] = new ExcelCell(getMessage("label.not.answered"), false); summaryOfAnswers.put(trueKey, 0); summaryOfAnswers.put(falseKey, 0); } @@ -1802,11 +1835,10 @@ if (optionAnswer.getAnswerBoolean()) { Integer currentCount = summaryOfAnswers.get(optionAnswer.getOptionUid()); if (currentCount == null) { - log.error("Assessment Export: Unable to count answer in summary, refers to an unexpected option. QuestionResult " - + questionResult.getUid() - + " OptionUid " - + optionAnswer.getOptionUid() - + " question " + question.getUid()); + log.error( + "Assessment Export: Unable to count answer in summary, refers to an unexpected option. QuestionResult " + + questionResult.getUid() + " OptionUid " + optionAnswer.getOptionUid() + + " question " + question.getUid()); } else { summaryOfAnswers.put(optionAnswer.getOptionUid(), currentCount + 1); foundOption = true; @@ -1823,12 +1855,10 @@ if (submittedUid != null) { Integer currentCount = summaryOfAnswers.get(submittedUid); if (currentCount == null) { - log.error("Assessment Export: Unable to count answer in summary, refers to an unexpected option. QuestionResult " - + questionResult.getUid() - + " submittedOptionUid " - + submittedUid - + " question " - + question.getUid()); + log.error( + "Assessment Export: Unable to count answer in summary, refers to an unexpected option. QuestionResult " + + questionResult.getUid() + " submittedOptionUid " + submittedUid + " question " + + question.getUid()); } else { summaryOfAnswers.put(submittedUid, currentCount + 1); } @@ -1849,39 +1879,38 @@ private String valueAsPercentage(Integer value, int total) { Double percentage = (double) value / total * 100; - return NumberUtil.formatLocalisedNumber(percentage, (Locale)null, 2) + "%"; - } - + return NumberUtil.formatLocalisedNumber(percentage, (Locale) null, 2) + "%"; + } + private ExcelCell[] outputSummaryTable(AssessmentQuestion question, Map summaryOfAnswers, Integer summaryNACount, Long trueKey, Long falseKey) { - ExcelCell[] summaryTable = new ExcelCell[summaryOfAnswers.size()+1]; + ExcelCell[] summaryTable = new ExcelCell[summaryOfAnswers.size() + 1]; int total = summaryNACount; - for ( int value : summaryOfAnswers.values() ) { - total += value; + for (int value : summaryOfAnswers.values()) { + total += value; } int i = 0; if (question.getType() == AssessmentConstants.QUESTION_TYPE_MULTIPLE_CHOICE || question.getType() == AssessmentConstants.QUESTION_TYPE_SHORT_ANSWER - || question.getType() == AssessmentConstants.QUESTION_TYPE_NUMERICAL ) { - for (AssessmentQuestionOption option : question.getOptions()) { - summaryTable[i] = new ExcelCell(valueAsPercentage(summaryOfAnswers.get(option.getUid()), total), false); - if ( option.getGrade() > 0 ) { - summaryTable[i].setColor(IndexedColors.GREEN); + || question.getType() == AssessmentConstants.QUESTION_TYPE_NUMERICAL) { + for (AssessmentQuestionOption option : question.getOptions()) { + summaryTable[i] = new ExcelCell(valueAsPercentage(summaryOfAnswers.get(option.getUid()), total), false); + if (option.getGrade() > 0) { + summaryTable[i].setColor(IndexedColors.GREEN); + } + i++; } - i++; - } - summaryTable[i++] = new ExcelCell(valueAsPercentage(summaryNACount, total), false); + summaryTable[i++] = new ExcelCell(valueAsPercentage(summaryNACount, total), false); } else { - summaryTable = new ExcelCell[3]; - summaryTable[0] = new ExcelCell(valueAsPercentage(summaryOfAnswers.get(trueKey), total), false); - summaryTable[1] = new ExcelCell(valueAsPercentage(summaryOfAnswers.get(falseKey), total), false); - summaryTable[2] = new ExcelCell(valueAsPercentage(summaryNACount,total), false); - summaryTable[question.getCorrectAnswer() ? 0 : 1].setColor(IndexedColors.GREEN); + summaryTable = new ExcelCell[3]; + summaryTable[0] = new ExcelCell(valueAsPercentage(summaryOfAnswers.get(trueKey), total), false); + summaryTable[1] = new ExcelCell(valueAsPercentage(summaryOfAnswers.get(falseKey), total), false); + summaryTable[2] = new ExcelCell(valueAsPercentage(summaryNACount, total), false); + summaryTable[question.getCorrectAnswer() ? 0 : 1].setColor(IndexedColors.GREEN); } return summaryTable; } - /** * Used only for excell export (for getUserSummaryData() method). */ @@ -1922,11 +1951,11 @@ // When changing a mark for user and isUseSelectLeaderToolOuput is true, the mark should be propagated to all // students within the group - List users = new ArrayList(); + List users = new ArrayList<>(); if (assessment.isUseSelectLeaderToolOuput()) { users = getUsersBySession(toolSessionId); } else { - users = new ArrayList(); + users = new ArrayList<>(); AssessmentUser user = assessmentResult.getUser(); users.add(user); } @@ -1970,7 +1999,7 @@ List deletedReferences) { // create list of modified questions - List modifiedQuestions = new ArrayList(); + List modifiedQuestions = new ArrayList<>(); for (AssessmentQuestion oldQuestion : oldQuestions) { for (AssessmentQuestion newQuestion : newQuestions) { if (oldQuestion.getUid().equals(newQuestion.getUid())) { @@ -2016,7 +2045,7 @@ // create list of modified references // modifiedReferences holds pairs newReference -> oldReference.getDefaultGrade() - Map modifiedReferences = new HashMap(); + Map modifiedReferences = new HashMap<>(); for (QuestionReference oldReference : oldReferences) { for (QuestionReference newReference : newReferences) { if (oldReference.getUid().equals(newReference.getUid()) @@ -2027,7 +2056,7 @@ } // create list of added references - List addedReferences = new ArrayList(); + List addedReferences = new ArrayList<>(); for (QuestionReference newReference : newReferences) { boolean isNewReferenceMetInOldReferences = false; @@ -2055,7 +2084,7 @@ user.getUserId()); AssessmentResult lastFinishedAssessmentResult = (assessmentResults.isEmpty()) ? null : assessmentResults.get(assessmentResults.size() - 1); - + //add autosave assessmentResult as well AssessmentResult lastAssessmentResult = getLastAssessmentResult(assessment.getUid(), user.getUserId()); if (lastAssessmentResult != null && lastAssessmentResult.getFinishDate() == null) { @@ -2136,7 +2165,7 @@ } // find all question answers from random question reference - ArrayList nonRandomQuestionAnswers = new ArrayList(); + ArrayList nonRandomQuestionAnswers = new ArrayList<>(); for (AssessmentQuestionResult questionAnswer : questionAnswers) { for (QuestionReference reference : newReferences) { if (!reference.isRandomQuestion() && questionAnswer.getAssessmentQuestion().getUid() @@ -2244,7 +2273,7 @@ public boolean isGroupedActivity(long toolContentID) { return toolService.isGroupedActivity(toolContentID); } - + @Override public void auditLogStartEditingActivityInMonitor(long toolContentID) { toolService.auditLogStartEditingActivityInMonitor(toolContentID); @@ -2271,7 +2300,6 @@ eventNotificationService.notifyLessonMonitors(sessionId, message, false); } - @Override public List getMarksArray(Long sessionId) { return assessmentUserDao.getRawUserMarksBySession(sessionId); @@ -2282,66 +2310,70 @@ return assessmentUserDao.getRawLeaderMarksByToolContentId(toolContentId); } - private LinkedHashMap getMarksSummaryForSession(List userDtos, float minGrade, float maxGrade, Integer numBuckets) { + private LinkedHashMap getMarksSummaryForSession(List userDtos, float minGrade, + float maxGrade, Integer numBuckets) { - LinkedHashMap summary = new LinkedHashMap(); - TreeMap inProgress = new TreeMap(); - - if ( numBuckets == null ) + LinkedHashMap summary = new LinkedHashMap<>(); + TreeMap inProgress = new TreeMap<>(); + + if (numBuckets == null) { numBuckets = 10; - + } + int bucketSize = 1; - int intMinGrade = (int)Math.floor(minGrade); + int intMinGrade = (int) Math.floor(minGrade); float gradeDifference = maxGrade - minGrade; - if ( gradeDifference <= 10 ) { - for ( int i= intMinGrade; i <= (int)Math.ceil(maxGrade); i++ ) { + if (gradeDifference <= 10) { + for (int i = intMinGrade; i <= (int) Math.ceil(maxGrade); i++) { inProgress.put(i, 0); } } else { int intGradeDifference = (int) Math.ceil(gradeDifference); - bucketSize = (int) Math.ceil(intGradeDifference / numBuckets); - for ( int i=intMinGrade; i <= maxGrade; i = i+bucketSize ) { + bucketSize = (int) Math.ceil(intGradeDifference / numBuckets); + for (int i = intMinGrade; i <= maxGrade; i = i + bucketSize) { inProgress.put(i, 0); } } - + for (AssessmentUserDTO userDto : userDtos) { float grade = userDto.getGrade(); int bucketStart = intMinGrade; - int bucketStop = bucketStart+bucketSize; + int bucketStop = bucketStart + bucketSize; boolean looking = true; - while ( bucketStart <= maxGrade && looking ) { - if ( grade >= bucketStart && grade < bucketStop ) { + while (bucketStart <= maxGrade && looking) { + if (grade >= bucketStart && grade < bucketStop) { inProgress.put(bucketStart, inProgress.get(bucketStart) + 1); looking = false; } else { bucketStart = bucketStop; - bucketStop = bucketStart+bucketSize; + bucketStop = bucketStart + bucketSize; } } } - - for ( Map.Entry entry : inProgress.entrySet() ) { + + for (Map.Entry entry : inProgress.entrySet()) { String key; - if ( bucketSize == 1 ) + if (bucketSize == 1) { key = entry.getKey().toString(); - else { - if ( maxGrade >= entry.getKey() && maxGrade <= entry.getKey()+bucketSize-1) { - if ( (int)maxGrade == entry.getKey() ) - key = NumberUtil.formatLocalisedNumber(maxGrade, (Locale)null, 2); - else + } else { + if (maxGrade >= entry.getKey() && maxGrade <= entry.getKey() + bucketSize - 1) { + if ((int) maxGrade == entry.getKey()) { + key = NumberUtil.formatLocalisedNumber(maxGrade, (Locale) null, 2); + } else { key = new StringBuilder().append(entry.getKey()).append(" - ") - .append(NumberUtil.formatLocalisedNumber(maxGrade, (Locale)null, 2)).toString(); + .append(NumberUtil.formatLocalisedNumber(maxGrade, (Locale) null, 2)).toString(); + } } else { - key = new StringBuilder().append(entry.getKey()).append(" - ").append(entry.getKey()+bucketSize-.01).toString(); + key = new StringBuilder().append(entry.getKey()).append(" - ") + .append(entry.getKey() + bucketSize - .01).toString(); } } summary.put(key, entry.getValue()); } - + return summary; } - + // ***************************************************************************** // private methods // ***************************************************************************** @@ -2778,116 +2810,126 @@ Date startDate = null; Date finishDate = null; for (AssessmentResult result : results) { - if (startDate == null || (result.getStartDate() != null && result.getStartDate().before(startDate))) + if (startDate == null || (result.getStartDate() != null && result.getStartDate().before(startDate))) { startDate = result.getStartDate(); - if (finishDate == null || (result.getFinishDate() != null && result.getFinishDate().after(finishDate))) + } + if (finishDate == null || (result.getFinishDate() != null && result.getFinishDate().after(finishDate))) { finishDate = result.getFinishDate(); + } } - if (learner.isSessionFinished()) + if (learner.isSessionFinished()) { return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_COMPLETED, startDate, finishDate); - else + } else { return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_ATTEMPTED, startDate, null); + } } // ****************** REST methods ************************* /** * Rest call to create a new Assessment content. Required fields in toolContentJSON: "title", "instructions", * "questions", "firstName", "lastName", "lastName", "questions" and "references". * - * The questions entry should be a JSONArray containing JSON objects, which in turn must contain "questionTitle", + * The questions entry should be a ArrayNode containing JSON objects, which in turn must contain "questionTitle", * "questionText", "displayOrder" (Integer), "type" (Integer). If the type is Multiple Choice, Numerical or Matching - * Pairs then a JSONArray "answers" is required. + * Pairs then a ArrayNode "answers" is required. * - * The answers entry should be JSONArray containing JSON objects, which in turn must contain "answerText" or + * The answers entry should be ArrayNode containing JSON objects, which in turn must contain "answerText" or * "answerFloat", "displayOrder" (Integer), "grade" (Integer). * - * The references entry should be a JSONArray containing JSON objects, which in turn must contain "displayOrder" + * The references entry should be a ArrayNode containing JSON objects, which in turn must contain "displayOrder" * (Integer), "questionDisplayOrder" (Integer - to match to the question). It may also have "defaultGrade" (Integer) * and "randomQuestion" (Boolean) + * + * @throws IOException */ @SuppressWarnings("unchecked") @Override - public void createRestToolContent(Integer userID, Long toolContentID, JSONObject toolContentJSON) - throws JSONException { + public void createRestToolContent(Integer userID, Long toolContentID, ObjectNode toolContentJSON) + throws IOException { Assessment assessment = new Assessment(); assessment.setContentId(toolContentID); - assessment.setTitle(toolContentJSON.getString(RestTags.TITLE)); - assessment.setInstructions(toolContentJSON.getString(RestTags.INSTRUCTIONS)); + assessment.setTitle(toolContentJSON.get(RestTags.TITLE).asText()); + assessment.setInstructions(toolContentJSON.get(RestTags.INSTRUCTIONS).asText()); assessment.setCreated(new Date()); - assessment.setReflectOnActivity(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); - assessment.setReflectInstructions(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS, (String) null)); - assessment.setAllowGradesAfterAttempt(JsonUtil.opt(toolContentJSON, "allowGradesAfterAttempt", Boolean.FALSE)); - assessment.setAllowHistoryResponses(JsonUtil.opt(toolContentJSON, "allowHistoryResponses", Boolean.FALSE)); + assessment.setReflectOnActivity( + JsonUtil.optBoolean(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); + assessment.setReflectInstructions(JsonUtil.optString(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS)); + assessment.setAllowGradesAfterAttempt( + JsonUtil.optBoolean(toolContentJSON, "allowGradesAfterAttempt", Boolean.FALSE)); + assessment + .setAllowHistoryResponses(JsonUtil.optBoolean(toolContentJSON, "allowHistoryResponses", Boolean.FALSE)); assessment.setAllowOverallFeedbackAfterQuestion( - JsonUtil.opt(toolContentJSON, "allowOverallFeedbackAfterQuestion", Boolean.FALSE)); - assessment.setAllowQuestionFeedback(JsonUtil.opt(toolContentJSON, "allowQuestionFeedback", Boolean.FALSE)); + JsonUtil.optBoolean(toolContentJSON, "allowOverallFeedbackAfterQuestion", Boolean.FALSE)); + assessment + .setAllowQuestionFeedback(JsonUtil.optBoolean(toolContentJSON, "allowQuestionFeedback", Boolean.FALSE)); assessment.setAllowRightAnswersAfterQuestion( - JsonUtil.opt(toolContentJSON, "allowRightAnswersAfterQuestion", Boolean.FALSE)); + JsonUtil.optBoolean(toolContentJSON, "allowRightAnswersAfterQuestion", Boolean.FALSE)); assessment.setAllowWrongAnswersAfterQuestion( - JsonUtil.opt(toolContentJSON, "allowWrongAnswersAfterQuestion", Boolean.FALSE)); - assessment.setAttemptsAllowed(JsonUtil.opt(toolContentJSON, "attemptsAllows", 1)); + JsonUtil.optBoolean(toolContentJSON, "allowWrongAnswersAfterQuestion", Boolean.FALSE)); + assessment.setAttemptsAllowed(JsonUtil.optInt(toolContentJSON, "attemptsAllows", 1)); assessment.setDefineLater(false); - assessment.setDisplaySummary(JsonUtil.opt(toolContentJSON, "displaySummary", Boolean.FALSE)); + assessment.setDisplaySummary(JsonUtil.optBoolean(toolContentJSON, "displaySummary", Boolean.FALSE)); assessment.setNotifyTeachersOnAttemptCompletion( - JsonUtil.opt(toolContentJSON, "notifyTeachersOnAttemptCompletion", Boolean.FALSE)); - assessment.setNumbered(JsonUtil.opt(toolContentJSON, "numbered", Boolean.TRUE)); - assessment.setPassingMark(JsonUtil.opt(toolContentJSON, "passingMark", 0)); - assessment.setQuestionsPerPage(JsonUtil.opt(toolContentJSON, "questionsPerPage", 0)); - assessment.setReflectInstructions(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS, "")); - assessment.setReflectOnActivity(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); - assessment.setShuffled(JsonUtil.opt(toolContentJSON, "shuffled", Boolean.FALSE)); - assessment.setTimeLimit(JsonUtil.opt(toolContentJSON, "timeLimit", 0)); + JsonUtil.optBoolean(toolContentJSON, "notifyTeachersOnAttemptCompletion", Boolean.FALSE)); + assessment.setNumbered(JsonUtil.optBoolean(toolContentJSON, "numbered", Boolean.TRUE)); + assessment.setPassingMark(JsonUtil.optInt(toolContentJSON, "passingMark", 0)); + assessment.setQuestionsPerPage(JsonUtil.optInt(toolContentJSON, "questionsPerPage", 0)); + assessment.setReflectInstructions(JsonUtil.optString(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS, "")); + assessment.setReflectOnActivity( + JsonUtil.optBoolean(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); + assessment.setShuffled(JsonUtil.optBoolean(toolContentJSON, "shuffled", Boolean.FALSE)); + assessment.setTimeLimit(JsonUtil.optInt(toolContentJSON, "timeLimit", 0)); assessment.setUseSelectLeaderToolOuput( - JsonUtil.opt(toolContentJSON, RestTags.USE_SELECT_LEADER_TOOL_OUTPUT, Boolean.FALSE)); + JsonUtil.optBoolean(toolContentJSON, RestTags.USE_SELECT_LEADER_TOOL_OUTPUT, Boolean.FALSE)); // submission deadline set in monitoring if (toolContentJSON.has("overallFeedback")) { - throw new JSONException( + throw new IOException( "Assessment Tool does not support Overall Feedback for REST Authoring. " + toolContentJSON); } AssessmentUser assessmentUser = getUserByIDAndContent(userID.longValue(), toolContentID); if (assessmentUser == null) { assessmentUser = new AssessmentUser(); - assessmentUser.setFirstName(toolContentJSON.getString("firstName")); - assessmentUser.setLastName(toolContentJSON.getString("lastName")); - assessmentUser.setLoginName(toolContentJSON.getString("loginName")); + assessmentUser.setFirstName(toolContentJSON.get("firstName").asText()); + assessmentUser.setLastName(toolContentJSON.get("lastName").asText()); + assessmentUser.setLoginName(toolContentJSON.get("loginName").asText()); assessmentUser.setAssessment(assessment); } assessment.setCreatedBy(assessmentUser); // **************************** Set the question bank ********************* - JSONArray questions = toolContentJSON.getJSONArray("questions"); + ArrayNode questions = JsonUtil.optArray(toolContentJSON, "questions"); Set newQuestionSet = assessment.getQuestions(); // the Assessment constructor will set up the collection - for (int i = 0; i < questions.length(); i++) { - JSONObject questionJSONData = (JSONObject) questions.get(i); + for (JsonNode questionJSONData : questions) { AssessmentQuestion question = new AssessmentQuestion(); - short type = (short) questionJSONData.getInt("type"); + short type = JsonUtil.optInt(questionJSONData, "type").shortValue(); question.setType(type); - question.setTitle(questionJSONData.getString(RestTags.QUESTION_TITLE)); - question.setQuestion(questionJSONData.getString(RestTags.QUESTION_TEXT)); - question.setSequenceId(questionJSONData.getInt(RestTags.DISPLAY_ORDER)); + question.setTitle(questionJSONData.get(RestTags.QUESTION_TITLE).asText()); + question.setQuestion(questionJSONData.get(RestTags.QUESTION_TEXT).asText()); + question.setSequenceId(JsonUtil.optInt(questionJSONData, RestTags.DISPLAY_ORDER)); - question.setAllowRichEditor(JsonUtil.opt(questionJSONData, RestTags.ALLOW_RICH_TEXT_EDITOR, Boolean.FALSE)); - question.setAnswerRequired(JsonUtil.opt(questionJSONData, "answerRequired", Boolean.FALSE)); - question.setCaseSensitive(JsonUtil.opt(questionJSONData, "caseSensitive", Boolean.FALSE)); - question.setCorrectAnswer(JsonUtil.opt(questionJSONData, "correctAnswer", Boolean.FALSE)); - question.setDefaultGrade(JsonUtil.opt(questionJSONData, "defaultGrade", 1)); - question.setFeedback(JsonUtil.opt(questionJSONData, "feedback", (String) null)); - question.setFeedbackOnCorrect(JsonUtil.opt(questionJSONData, "feedbackOnCorrect", (String) null)); - question.setFeedbackOnIncorrect(JsonUtil.opt(questionJSONData, "feedbackOnIncorrect", (String) null)); - question.setFeedbackOnPartiallyCorrect( - JsonUtil.opt(questionJSONData, "feedbackOnPartiallyCorrect", (String) null)); - question.setGeneralFeedback(JsonUtil.opt(questionJSONData, "generalFeedback", "")); - question.setMaxWordsLimit(JsonUtil.opt(questionJSONData, "maxWordsLimit", 0)); - question.setMinWordsLimit(JsonUtil.opt(questionJSONData, "minWordsLimit", 0)); - question.setMultipleAnswersAllowed(JsonUtil.opt(questionJSONData, "multipleAnswersAllowed", Boolean.FALSE)); + question.setAllowRichEditor( + JsonUtil.optBoolean(questionJSONData, RestTags.ALLOW_RICH_TEXT_EDITOR, Boolean.FALSE)); + question.setAnswerRequired(JsonUtil.optBoolean(questionJSONData, "answerRequired", Boolean.FALSE)); + question.setCaseSensitive(JsonUtil.optBoolean(questionJSONData, "caseSensitive", Boolean.FALSE)); + question.setCorrectAnswer(JsonUtil.optBoolean(questionJSONData, "correctAnswer", Boolean.FALSE)); + question.setDefaultGrade(JsonUtil.optInt(questionJSONData, "defaultGrade", 1)); + question.setFeedback(JsonUtil.optString(questionJSONData, "feedback")); + question.setFeedbackOnCorrect(JsonUtil.optString(questionJSONData, "feedbackOnCorrect")); + question.setFeedbackOnIncorrect(JsonUtil.optString(questionJSONData, "feedbackOnIncorrect")); + question.setFeedbackOnPartiallyCorrect(JsonUtil.optString(questionJSONData, "feedbackOnPartiallyCorrect")); + question.setGeneralFeedback(JsonUtil.optString(questionJSONData, "generalFeedback", "")); + question.setMaxWordsLimit(JsonUtil.optInt(questionJSONData, "maxWordsLimit", 0)); + question.setMinWordsLimit(JsonUtil.optInt(questionJSONData, "minWordsLimit", 0)); + question.setMultipleAnswersAllowed( + JsonUtil.optBoolean(questionJSONData, "multipleAnswersAllowed", Boolean.FALSE)); question.setIncorrectAnswerNullifiesMark( - JsonUtil.opt(questionJSONData, "incorrectAnswerNullifiesMark", Boolean.FALSE)); - question.setPenaltyFactor(Float.parseFloat(JsonUtil.opt(questionJSONData, "penaltyFactor", "0.0"))); + JsonUtil.optBoolean(questionJSONData, "incorrectAnswerNullifiesMark", Boolean.FALSE)); + question.setPenaltyFactor(JsonUtil.optDouble(questionJSONData, "penaltyFactor", 0.0).floatValue()); // question.setUnits(units); Needed for numerical type question if ((type == AssessmentConstants.QUESTION_TYPE_MATCHING_PAIRS) @@ -2896,22 +2938,21 @@ || (type == AssessmentConstants.QUESTION_TYPE_MARK_HEDGING)) { if (!questionJSONData.has(RestTags.ANSWERS)) { - throw new JSONException("REST Authoring is missing answers for a question of type " + type - + ". Data:" + toolContentJSON); + throw new IOException("REST Authoring is missing answers for a question of type " + type + ". Data:" + + toolContentJSON); } - Set optionList = new LinkedHashSet(); - JSONArray optionsData = questionJSONData.getJSONArray(RestTags.ANSWERS); - for (int j = 0; j < optionsData.length(); j++) { - JSONObject answerData = (JSONObject) optionsData.get(j); + Set optionList = new LinkedHashSet<>(); + ArrayNode optionsData = JsonUtil.optArray(questionJSONData, RestTags.ANSWERS); + for (JsonNode answerData : optionsData) { AssessmentQuestionOption option = new AssessmentQuestionOption(); - option.setSequenceId(answerData.getInt(RestTags.DISPLAY_ORDER)); - option.setGrade(Float.parseFloat(answerData.getString("grade"))); - option.setCorrect(Boolean.parseBoolean(JsonUtil.opt(answerData, "correct", "false"))); - option.setAcceptedError(Float.parseFloat(JsonUtil.opt(answerData, "acceptedError", "0.0"))); - option.setFeedback(JsonUtil.opt(answerData, "feedback", (String) null)); - option.setOptionString(JsonUtil.opt(answerData, RestTags.ANSWER_TEXT, (String) null)); - option.setOptionFloat(Float.parseFloat(JsonUtil.opt(answerData, "answerFloat", "0.0"))); + option.setSequenceId(JsonUtil.optInt(answerData, RestTags.DISPLAY_ORDER)); + option.setGrade(answerData.get("grade").floatValue()); + option.setCorrect(JsonUtil.optBoolean(answerData, "correct", false)); + option.setAcceptedError(JsonUtil.optDouble(answerData, "acceptedError", 0.0).floatValue()); + option.setFeedback(JsonUtil.optString(answerData, "feedback")); + option.setOptionString(JsonUtil.optString(answerData, RestTags.ANSWER_TEXT)); + option.setOptionFloat(JsonUtil.optDouble(answerData, "answerFloat", 0.0).floatValue()); // option.setQuestion(question); can't find the use for this field yet! optionList.add(option); } @@ -2923,23 +2964,23 @@ } // **************************** Now set up the references to the questions in the bank ********************* - JSONArray references = toolContentJSON.getJSONArray("references"); + ArrayNode references = JsonUtil.optArray(toolContentJSON, "references"); Set newReferenceSet = assessment.getQuestionReferences(); // the Assessment constructor will set up the - // collection - for (int i = 0; i < references.length(); i++) { - JSONObject referenceJSONData = (JSONObject) references.get(i); + + ;// collection + for (JsonNode referenceJSONData : references) { QuestionReference reference = new QuestionReference(); reference.setType((short) 0); - reference.setDefaultGrade(JsonUtil.opt(referenceJSONData, "defaultGrade", 1)); - reference.setSequenceId(referenceJSONData.getInt(RestTags.DISPLAY_ORDER)); + reference.setDefaultGrade(JsonUtil.optInt(referenceJSONData, "defaultGrade", 1)); + reference.setSequenceId(JsonUtil.optInt(referenceJSONData, RestTags.DISPLAY_ORDER)); AssessmentQuestion matchingQuestion = matchQuestion(newQuestionSet, - referenceJSONData.getInt("questionDisplayOrder")); + JsonUtil.optInt(referenceJSONData, "questionDisplayOrder")); if (matchingQuestion == null) { - throw new JSONException("Unable to find matching question for displayOrder " + throw new IOException("Unable to find matching question for displayOrder " + referenceJSONData.get("questionDisplayOrder") + ". Data:" + toolContentJSON); } reference.setQuestion(matchingQuestion); - reference.setRandomQuestion(JsonUtil.opt(referenceJSONData, "randomQuestion", Boolean.FALSE)); + reference.setRandomQuestion(JsonUtil.optBoolean(referenceJSONData, "randomQuestion", Boolean.FALSE)); reference.setTitle(null); newReferenceSet.add(reference); } @@ -2961,10 +3002,10 @@ } // TODO Implement REST support for all types and then remove checkType method - void checkType(short type) throws JSONException { + void checkType(short type) throws IOException { if ((type != AssessmentConstants.QUESTION_TYPE_ESSAY) && (type != AssessmentConstants.QUESTION_TYPE_MULTIPLE_CHOICE)) { - throw new JSONException( + throw new IOException( "Assessment Tool does not support REST Authoring for anything but Essay Type and Multiple Choice. Found type " + type); } Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/MonitoringAction.java =================================================================== diff -u -r60d9a173d5590295376322fc3e857ae2dca37717 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision 60d9a173d5590295376322fc3e857ae2dca37717) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -21,7 +21,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.tool.assessment.web.action; import java.io.IOException; @@ -47,9 +46,6 @@ import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.gradebook.util.GradebookConstants; import org.lamsfoundation.lams.tool.assessment.AssessmentConstants; import org.lamsfoundation.lams.tool.assessment.dto.AssessmentResultDTO; @@ -72,21 +68,26 @@ import org.lamsfoundation.lams.util.DateUtil; import org.lamsfoundation.lams.util.ExcelCell; import org.lamsfoundation.lams.util.ExcelUtil; +import org.lamsfoundation.lams.util.JsonUtil; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; import org.lamsfoundation.lams.web.util.SessionMap; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + public class MonitoringAction extends Action { public static Logger log = Logger.getLogger(MonitoringAction.class); private IAssessmentService service; @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException, JSONException { + HttpServletResponse response) throws IOException, ServletException { request.setAttribute("initialTabId", WebUtil.readLongParam(request, AttributeNames.PARAM_CURRENT_TAB, true)); String param = mapping.getParameter(); @@ -126,7 +127,7 @@ if (param.equals("statistic")) { return statistic(mapping, form, request, response); } - + return mapping.findForward(AssessmentConstants.ERROR); } @@ -135,7 +136,7 @@ initAssessmentService(); // initialize Session Map - SessionMap sessionMap = new SessionMap(); + SessionMap sessionMap = new SessionMap<>(); request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMap.getSessionID()); @@ -153,7 +154,8 @@ Date tzSubmissionDeadline = DateUtil.convertToTimeZoneFromDefault(teacherTimeZone, submissionDeadline); request.setAttribute(AssessmentConstants.ATTR_SUBMISSION_DEADLINE, tzSubmissionDeadline.getTime()); // use the unconverted time, as convertToStringForJSON() does the timezone conversion if needed - request.setAttribute(AssessmentConstants.ATTR_SUBMISSION_DEADLINE_DATESTRING, DateUtil.convertToStringForJSON(submissionDeadline, request.getLocale())); + request.setAttribute(AssessmentConstants.ATTR_SUBMISSION_DEADLINE_DATESTRING, + DateUtil.convertToStringForJSON(submissionDeadline, request.getLocale())); } @@ -165,7 +167,7 @@ } //prepare list of the questions to display in question drop down menu, filtering out questions that aren't supposed to be answered - Set questionList = new TreeSet(); + Set questionList = new TreeSet<>(); //in case there is at least one random question - we need to show all questions in a drop down select if (assessment.hasRandomQuestion()) { questionList.addAll(assessment.getQuestions()); @@ -178,7 +180,7 @@ } //prepare toolOutputDefinitions and activityEvaluation - List toolOutputDefinitions = new ArrayList(); + List toolOutputDefinitions = new ArrayList<>(); toolOutputDefinitions.add(AssessmentConstants.OUTPUT_NAME_LEARNER_TOTAL_SCORE); toolOutputDefinitions.add(AssessmentConstants.OUTPUT_NAME_BEST_SCORE); toolOutputDefinitions.add(AssessmentConstants.OUTPUT_NAME_FIRST_SCORE); @@ -198,7 +200,7 @@ WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID)); return mapping.findForward(AssessmentConstants.SUCCESS); } - + private ActionForward userMasterDetail(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { initAssessmentService(); @@ -268,7 +270,7 @@ * @param request * @param response * @return - * @throws IOException + * @throws IOException */ private ActionForward setSubmissionDeadline(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException { @@ -309,7 +311,7 @@ * @throws IOException */ private ActionForward setActivityEvaluation(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws JSONException, IOException { + HttpServletResponse response) throws IOException { initAssessmentService(); String sessionMapID = request.getParameter(AssessmentConstants.ATTR_SESSION_MAP_ID); @@ -320,11 +322,11 @@ String activityEvaluation = WebUtil.readStrParam(request, AssessmentConstants.ATTR_ACTIVITY_EVALUATION); service.setActivityEvaluation(contentID, activityEvaluation); - // update the session ready for stats tab to be reloaded otherwise flicking between tabs + // update the session ready for stats tab to be reloaded otherwise flicking between tabs // causes the old value to be redisplayed sessionMap.put(AssessmentConstants.ATTR_ACTIVITY_EVALUATION, activityEvaluation); - JSONObject responseJSON = new JSONObject(); + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); responseJSON.put("success", "true"); response.setContentType("application/json;charset=utf-8"); response.getWriter().print(new String(responseJSON.toString())); @@ -335,7 +337,7 @@ * Refreshes user list. */ public ActionForward getUsers(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse res) throws IOException, ServletException, JSONException { + HttpServletResponse res) throws IOException, ServletException { initAssessmentService(); String sessionMapID = request.getParameter(AssessmentConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession() @@ -354,7 +356,7 @@ } String searchString = WebUtil.readStrParam(request, "userName", true); - List userDtos = new ArrayList(); + List userDtos = new ArrayList<>(); int countSessionUsers = 0; //in case of UseSelectLeaderToolOuput - display only one user if (assessment.isUseSelectLeaderToolOuput()) { @@ -387,31 +389,31 @@ Math.ceil(new Integer(countSessionUsers).doubleValue() / new Integer(rowLimit).doubleValue())) .intValue(); - JSONArray rows = new JSONArray(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); int i = 1; for (AssessmentUserDTO userDto : userDtos) { - JSONArray userData = new JSONArray(); - userData.put(userDto.getUserId()); - userData.put(sessionId); + ArrayNode userData = JsonNodeFactory.instance.arrayNode(); + userData.add(userDto.getUserId()); + userData.add(sessionId); String fullName = StringEscapeUtils.escapeHtml(userDto.getFirstName() + " " + userDto.getLastName()); - userData.put(fullName); - userData.put(userDto.getGrade()); + userData.add(fullName); + userData.add(userDto.getGrade()); if (userDto.getPortraitId() != null ) - userData.put(userDto.getPortraitId()); + userData.add(userDto.getPortraitId()); - JSONObject userRow = new JSONObject(); + ObjectNode userRow = JsonNodeFactory.instance.objectNode(); userRow.put("id", i++); - userRow.put("cell", userData); + userRow.set("cell", userData); - rows.put(userRow); + rows.add(userRow); } - JSONObject responseJSON = new JSONObject(); + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); responseJSON.put("total", totalPages); responseJSON.put("page", page); responseJSON.put("records", countSessionUsers); - responseJSON.put("rows", rows); + responseJSON.set("rows", rows); res.setContentType("application/json;charset=utf-8"); res.getWriter().print(new String(responseJSON.toString())); @@ -422,7 +424,7 @@ * Refreshes user list. */ public ActionForward getUsersByQuestion(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse res) throws IOException, ServletException, JSONException { + HttpServletResponse res) throws IOException, ServletException { initAssessmentService(); String sessionMapID = request.getParameter(AssessmentConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession() @@ -442,7 +444,7 @@ } String searchString = WebUtil.readStrParam(request, "userName", true); - List userDtos = new ArrayList(); + List userDtos = new ArrayList<>(); int countSessionUsers = 0; //in case of UseSelectLeaderToolOuput - display only one user if (assessment.isUseSelectLeaderToolOuput()) { @@ -483,54 +485,54 @@ Math.ceil(new Integer(countSessionUsers).doubleValue() / new Integer(rowLimit).doubleValue())) .intValue(); - JSONArray rows = new JSONArray(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); int i = 1; for (AssessmentUserDTO userDto : userDtos) { Long questionResultUid = userDto.getQuestionResultUid(); String fullName = StringEscapeUtils.escapeHtml(userDto.getFirstName() + " " + userDto.getLastName()); - JSONArray userData = new JSONArray(); + ArrayNode userData = JsonNodeFactory.instance.arrayNode(); if (questionResultUid != null) { AssessmentQuestionResult questionResult = service.getAssessmentQuestionResultByUid(questionResultUid); - userData.put(questionResultUid); - userData.put(questionResult.getMaxMark()); - userData.put(fullName); - userData.put(AssessmentEscapeUtils.printResponsesForJqgrid(questionResult)); - userData.put(questionResult.getMark()); + userData.add(questionResultUid); + userData.add(questionResult.getMaxMark()); + userData.add(fullName); + userData.add(AssessmentEscapeUtils.printResponsesForJqgrid(questionResult)); + userData.add(questionResult.getMark()); } else { - userData.put(""); - userData.put(""); - userData.put(fullName); - userData.put("-"); - userData.put("-"); + userData.add(""); + userData.add(""); + userData.add(fullName); + userData.add("-"); + userData.add("-"); } - JSONObject userRow = new JSONObject(); + ObjectNode userRow = JsonNodeFactory.instance.objectNode(); userRow.put("id", i++); - userRow.put("cell", userData); + userRow.set("cell", userData); - rows.put(userRow); + rows.add(userRow); } - JSONObject responseJSON = new JSONObject(); + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); responseJSON.put("total", totalPages); responseJSON.put("page", page); responseJSON.put("records", countSessionUsers); - responseJSON.put("rows", rows); + responseJSON.set("rows", rows); res.setContentType("application/json;charset=utf-8"); res.getWriter().print(new String(responseJSON.toString())); return null; } - /** + /** * Get the mark summary with data arranged in bands. Can be displayed graphically or in a table. */ private ActionForward getMarkChartData(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse res) throws IOException, ServletException, JSONException { + HttpServletResponse res) throws IOException, ServletException { initAssessmentService(); @@ -542,22 +544,23 @@ Long contentId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_CONTENT_ID); Assessment assessment = service.getAssessmentByContentId(contentId); List results = null; - - if ( assessment != null ) { - if ( assessment.isUseSelectLeaderToolOuput() ) { + + if (assessment != null) { + if (assessment.isUseSelectLeaderToolOuput()) { results = service.getMarksArrayForLeaders(contentId); } else { Long sessionId = WebUtil.readLongParam(request, AssessmentConstants.ATTR_TOOL_SESSION_ID); results = service.getMarksArray(sessionId); } } - - JSONObject responseJSON = new JSONObject(); - if ( results != null ) - responseJSON.put("data", results); - else - responseJSON.put("data", new Float[0]); + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); + if (results != null) { + responseJSON.set("data", JsonUtil.readArray(results)); + } else { + responseJSON.set("data", JsonUtil.readArray(new Float[0])); + } + res.setContentType("application/json;charset=utf-8"); res.getWriter().write(responseJSON.toString()); return null; @@ -626,7 +629,7 @@ return null; } - + private ActionForward statistic(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { @@ -638,8 +641,8 @@ Long contentId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); Assessment assessment = service.getAssessmentByContentId(contentId); - if ( assessment != null ) { - if ( assessment.isUseSelectLeaderToolOuput() ) { + if (assessment != null) { + if (assessment.isUseSelectLeaderToolOuput()) { LeaderResultsDTO leaderDto = service.getLeaderResultsDTOForLeaders(contentId); sessionMap.put("leaderDto", leaderDto); } else { @@ -650,7 +653,6 @@ return mapping.findForward(AssessmentConstants.SUCCESS); } - // ************************************************************************************* // Private method // ************************************************************************************* Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/actions/LearningWebsocketServer.java =================================================================== diff -u -r60d9a173d5590295376322fc3e857ae2dca37717 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/actions/LearningWebsocketServer.java (.../LearningWebsocketServer.java) (revision 60d9a173d5590295376322fc3e857ae2dca37717) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/actions/LearningWebsocketServer.java (.../LearningWebsocketServer.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -8,7 +8,6 @@ import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; -import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import javax.websocket.CloseReason; @@ -21,9 +20,6 @@ import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.tool.chat.model.ChatMessage; import org.lamsfoundation.lams.tool.chat.model.ChatSession; import org.lamsfoundation.lams.tool.chat.model.ChatUser; @@ -32,12 +28,18 @@ import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; import org.lamsfoundation.lams.util.HashUtil; +import org.lamsfoundation.lams.util.JsonUtil; import org.lamsfoundation.lams.util.hibernate.HibernateSessionManager; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * Receives, processes and sends Chat messages to Learners. * @@ -130,34 +132,34 @@ Set sessionWebsockets = LearningWebsocketServer.websockets.get(toolSessionId); Roster roster = null; - JSONArray rosterJSON = null; + ArrayNode rosterJSON = null; String rosterString = null; for (Websocket websocket : sessionWebsockets) { // the connection is valid, carry on - JSONObject responseJSON = new JSONObject(); + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); // fetch roster only once, but messages are personalised - if (rosterJSON == null) { - roster = LearningWebsocketServer.rosters.get(toolSessionId); - if (roster == null) { - // build a new roster object - roster = new Roster(toolSessionId); - LearningWebsocketServer.rosters.put(toolSessionId, roster); + try { + if (rosterJSON == null) { + roster = LearningWebsocketServer.rosters.get(toolSessionId); + if (roster == null) { + // build a new roster object + roster = new Roster(toolSessionId); + LearningWebsocketServer.rosters.put(toolSessionId, roster); + } + + rosterJSON = roster.getRosterJSON(); + rosterString = rosterJSON.toString(); } - rosterJSON = roster.getRosterJSON(); - rosterString = rosterJSON.toString(); - } - - try { String userName = websocket.userName; - JSONArray messagesJSON = LearningWebsocketServer.getMessages(chatSession, messages, userName); + ArrayNode messagesJSON = LearningWebsocketServer.getMessages(chatSession, messages, userName); // if hash of roster and messages is the same as before, do not send the message, save the bandwidth String hash = HashUtil.sha1(rosterString + messagesJSON.toString()); if ((websocket.hash == null) || !websocket.hash.equals(hash)) { websocket.hash = hash; - responseJSON.put("messages", messagesJSON); - responseJSON.put("roster", rosterJSON); + responseJSON.set("messages", messagesJSON); + responseJSON.set("roster", rosterJSON); // send the payload to the Learner's browser if (websocket.session.isOpen()) { @@ -181,21 +183,24 @@ private long lastDBCheckTime = 0; // Learners who are currently active - private final TreeMap activeUsers = new TreeMap(); + private final TreeMap activeUsers = new TreeMap(); private Roster(Long toolSessionId) { this.toolSessionId = toolSessionId; } /** * Checks which Learners + * + * @throws IOException + * @throws JsonProcessingException */ - private JSONArray getRosterJSON() { + private ArrayNode getRosterJSON() throws JsonProcessingException, IOException { TreeMap localActiveUsers = new TreeMap(); Set sessionWebsockets = LearningWebsocketServer.websockets.get(toolSessionId); // find out who is active locally for (Websocket websocket : sessionWebsockets) { - localActiveUsers.put(websocket.nickName, new Long[] {websocket.lamsUserId, websocket.portraitId} ); + localActiveUsers.put(websocket.nickName, new Long[] { websocket.lamsUserId, websocket.portraitId }); } // is it time to sync with the DB yet? @@ -210,7 +215,8 @@ // refresh current collection activeUsers.clear(); for (ChatUser activeUser : storedActiveUsers) { - activeUsers.put(activeUser.getNickname(), new Long[] {activeUser.getUserId(), getPortraitId(activeUser.getUserId())}); + activeUsers.put(activeUser.getNickname(), new Long[] { activeUser.getUserId(), + LearningWebsocketServer.getPortraitId(activeUser.getUserId()) }); } lastDBCheckTime = currentTime; @@ -219,16 +225,12 @@ activeUsers.putAll(localActiveUsers); } - JSONArray rosterJSON = new JSONArray(); - for ( Map.Entry entry : activeUsers.entrySet() ) { + ArrayNode rosterJSON = JsonNodeFactory.instance.arrayNode(); + for (Map.Entry entry : activeUsers.entrySet()) { Long[] ids = entry.getValue(); - try { - JSONObject userJSON = new JSONObject().put("nickName", entry.getKey()).put("lamsUserId", ids[0]).put("portraitId", ids[1]); - rosterJSON.put(userJSON); - } catch (JSONException e) { - log.error("Unable to add user to Chat roster. User details "+entry.getKey()+": "+ids); - e.printStackTrace(); - } + ObjectNode userJSON = JsonNodeFactory.instance.objectNode().put("nickName", entry.getKey()) + .put("lamsUserId", ids[0]).put("portraitId", ids[1]); + rosterJSON.add(userJSON); } return rosterJSON; } @@ -269,7 +271,8 @@ HibernateSessionManager.openSession(); ChatUser chatUser = LearningWebsocketServer.getChatService().getUserByLoginNameAndSessionId(userName, toolSessionId); - Websocket websocket = new Websocket(session, chatUser.getNickname(), chatUser.getUserId(), getPortraitId(chatUser.getUserId())); + Websocket websocket = new Websocket(session, chatUser.getNickname(), chatUser.getUserId(), + LearningWebsocketServer.getPortraitId(chatUser.getUserId())); finalSessionWebsockets.add(websocket); // update the chat window immediatelly @@ -315,24 +318,27 @@ /** * Stores a message sent by a Learner. + * + * @throws IOException + * @throws JsonProcessingException */ @OnMessage - public void receiveMessage(String input, Session session) throws JSONException { + public void receiveMessage(String input, Session session) throws JsonProcessingException, IOException { if (StringUtils.isBlank(input)) { return; } if (input.equalsIgnoreCase("ping")) { // just a ping every few minutes return; } - JSONObject messageJSON = new JSONObject(input); - String message = messageJSON.getString("message"); + ObjectNode messageJSON = JsonUtil.readObject(input); + String message = JsonUtil.optString(messageJSON, "message"); if (StringUtils.isBlank(message)) { return; } - Long toolSessionId = messageJSON.getLong("toolSessionID"); - String toUser = messageJSON.getString("toUser"); + Long toolSessionId = JsonUtil.optLong(messageJSON, "toolSessionID"); + String toUser = JsonUtil.optString(messageJSON, "toUser"); new Thread(() -> { try { // websocket communication bypasses standard HTTP filters, so Hibernate session needs to be initialised manually @@ -374,9 +380,8 @@ /** * Filteres messages meant for the given user (group or personal). */ - private static JSONArray getMessages(ChatSession chatSession, List messages, String userName) - throws JSONException { - JSONArray messagesJSON = new JSONArray(); + private static ArrayNode getMessages(ChatSession chatSession, List messages, String userName) { + ArrayNode messagesJSON = JsonNodeFactory.instance.arrayNode(); for (ChatMessage message : messages) { // all messasges need to be written out, not only new ones, @@ -386,27 +391,29 @@ || message.getToUser().getLoginName().equals(userName))) { String filteredMessage = LearningWebsocketServer.getChatService().filterMessage(message.getBody(), chatSession.getChat()); - JSONObject messageJSON = new JSONObject(); + ObjectNode messageJSON = JsonNodeFactory.instance.objectNode(); messageJSON.put("body", filteredMessage); messageJSON.put("from", message.getFromUser().getNickname()); messageJSON.put("lamsUserId", message.getFromUser().getUserId()); messageJSON.put("type", message.getType()); - messagesJSON.put(messageJSON); + messagesJSON.add(messageJSON); } } return messagesJSON; } private static Long getPortraitId(Long userId) { - if ( userId != null ) { - User user = (User) getUserManagementService().findById(User.class, userId.intValue()); - if ( user != null ) + if (userId != null) { + User user = (User) LearningWebsocketServer.getUserManagementService().findById(User.class, + userId.intValue()); + if (user != null) { return user.getPortraitUuid(); - } + } + } return null; } - + private static IChatService getChatService() { if (LearningWebsocketServer.chatService == null) { WebApplicationContext wac = WebApplicationContextUtils @@ -420,7 +427,8 @@ if (LearningWebsocketServer.userManagmentService == null) { WebApplicationContext wac = WebApplicationContextUtils .getRequiredWebApplicationContext(SessionManager.getServletContext()); - LearningWebsocketServer.userManagmentService = (IUserManagementService) wac.getBean("userManagementService"); + LearningWebsocketServer.userManagmentService = (IUserManagementService) wac + .getBean("userManagementService"); } return LearningWebsocketServer.userManagmentService; } Index: lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/web/action/MonitoringAction.java =================================================================== diff -u -r60d9a173d5590295376322fc3e857ae2dca37717 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision 60d9a173d5590295376322fc3e857ae2dca37717) +++ lams_tool_daco/src/java/org/lamsfoundation/lams/tool/daco/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -21,7 +21,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.tool.daco.web.action; import java.io.IOException; @@ -46,9 +45,6 @@ import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.notebook.model.NotebookEntry; import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; import org.lamsfoundation.lams.tool.daco.DacoConstants; @@ -73,12 +69,16 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + public class MonitoringAction extends Action { public static Logger log = Logger.getLogger(MonitoringAction.class); @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException, ParseException, JSONException { + HttpServletResponse response) throws IOException, ServletException, ParseException { String param = mapping.getParameter(); if (param.equals("summary")) { @@ -200,7 +200,7 @@ } protected ActionForward getUsers(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse res) throws IOException, ServletException, JSONException { + HttpServletResponse res) throws IOException, ServletException { IDacoService service = getDacoService(); String sessionMapID = WebUtil.readStrParam(request, DacoConstants.ATTR_SESSION_MAP_ID, true); @@ -238,22 +238,22 @@ List users = service.getUsersForTablesorter(sessionId, page, size, sorting, searchString, daco.isReflectOnActivity()); - JSONArray rows = new JSONArray(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); - JSONObject responsedata = new JSONObject(); + ObjectNode responsedata = JsonNodeFactory.instance.objectNode(); responsedata.put("total_rows", service.getCountUsersBySession(sessionId, searchString)); for (Object[] userAndReflection : users) { - JSONObject responseRow = new JSONObject(); + ObjectNode responseRow = JsonNodeFactory.instance.objectNode(); DacoUser user = (DacoUser) userAndReflection[0]; responseRow.put(DacoConstants.USER_ID, user.getUserId()); responseRow.put(DacoConstants.USER_FULL_NAME, StringEscapeUtils.escapeHtml(user.getFullName())); if (userAndReflection.length > 1 && userAndReflection[1] != null) { - responseRow.put(DacoConstants.RECORD_COUNT, userAndReflection[1]); + responseRow.put(DacoConstants.RECORD_COUNT, (Integer) userAndReflection[1]); } else { responseRow.put(DacoConstants.RECORD_COUNT, 0); } @@ -263,11 +263,11 @@ StringEscapeUtils.escapeHtml((String) userAndReflection[2])); } if (userAndReflection.length > 3 && userAndReflection[3] != null) { - responseRow.put(DacoConstants.PORTRAIT_ID, userAndReflection[3]); + responseRow.put(DacoConstants.PORTRAIT_ID, (String) userAndReflection[3]); } - rows.put(responseRow); + rows.add(responseRow); } - responsedata.put("rows", rows); + responsedata.set("rows", rows); res.setContentType("application/json;charset=utf-8"); res.getWriter().print(new String(responsedata.toString())); return null; @@ -320,7 +320,7 @@ String dateHeader = service.getLocalisedMessage(DacoConstants.KEY_LABEL_EXPORT_FILE_DATE, null); Set questions = daco.getDacoQuestions(); - HashMap questionUidToSpreadsheetColumnIndex = new HashMap(); + HashMap questionUidToSpreadsheetColumnIndex = new HashMap<>(); // First two columns are "user" and date when was the answer added int columnIndex = 2; String[] columnNames = new String[questions.size() + 2]; @@ -339,7 +339,7 @@ String latitudeHeader = service.getLocalisedMessage(DacoConstants.KEY_LABEL_LEARNING_LONGLAT_LATITUDE, null); String latitudeUnit = service.getLocalisedMessage(DacoConstants.KEY_LABEL_LEARNING_LONGLAT_LATITUDE_UNIT, null); - List rows = new LinkedList(); + List rows = new LinkedList<>(); // We get all sessions with all users with all their records from the given Daco content List monitoringSummary = service.getSummaryForExport(daco.getContentId(), null); // Get current user's locale to format numbers properly @@ -397,7 +397,7 @@ if (!StringUtils.isBlank(answerString)) { DacoQuestion question = answer.getQuestion(); DacoQuestion currentQuestion = question; - List answerOptions = new LinkedList( + List answerOptions = new LinkedList<>( question.getAnswerOptions()); StringBuilder cellStringBuilder = new StringBuilder(); // instead of number, we create a comma-separated string of chosen options @@ -451,7 +451,7 @@ case DacoConstants.QUESTION_TYPE_RADIO: case DacoConstants.QUESTION_TYPE_DROPDOWN: if (!StringUtils.isBlank(answerString)) { - List answerOptions = new LinkedList( + List answerOptions = new LinkedList<>( answer.getQuestion().getAnswerOptions()); try { int chosenAnswer = Integer.parseInt(answerString) - 1; Index: lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/service/ForumService.java =================================================================== diff -u -r60d9a173d5590295376322fc3e857ae2dca37717 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/service/ForumService.java (.../ForumService.java) (revision 60d9a173d5590295376322fc3e857ae2dca37717) +++ lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/service/ForumService.java (.../ForumService.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -42,9 +42,6 @@ import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.apache.struts.upload.FormFile; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.contentrepository.ICredentials; import org.lamsfoundation.lams.contentrepository.ITicket; import org.lamsfoundation.lams.contentrepository.NodeKey; @@ -114,6 +111,9 @@ import org.lamsfoundation.lams.util.MessageService; import org.lamsfoundation.lams.util.audit.IAuditService; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * * @author Steve.Ni @@ -1514,50 +1514,49 @@ /** * Used by the Rest calls to create content. Mandatory fields in toolContentJSON: title, instructions, topics. - * Topics must contain a JSONArray of JSONObject objects, which have the following mandatory fields: subject, body + * Topics must contain a ArrayNode of ObjectNode objects, which have the following mandatory fields: subject, body * There will usually be at least one topic object in the Topics array but the array may be of zero length. */ @Override - public void createRestToolContent(Integer userID, Long toolContentID, JSONObject toolContentJSON) - throws JSONException { + public void createRestToolContent(Integer userID, Long toolContentID, ObjectNode toolContentJSON) { Forum forum = new Forum(); Date updateDate = new Date(); forum.setCreated(updateDate); forum.setUpdated(updateDate); forum.setContentId(toolContentID); - forum.setTitle(toolContentJSON.getString(RestTags.TITLE)); - forum.setInstructions(toolContentJSON.getString(RestTags.INSTRUCTIONS)); + forum.setTitle(JsonUtil.optString(toolContentJSON, RestTags.TITLE)); + forum.setInstructions(JsonUtil.optString(toolContentJSON, RestTags.INSTRUCTIONS)); - forum.setAllowAnonym(JsonUtil.opt(toolContentJSON, "allowAnonym", Boolean.FALSE)); - forum.setAllowEdit(JsonUtil.opt(toolContentJSON, "allowEdit", Boolean.TRUE)); // defaults to true in the default - // entry in the db - forum.setAllowNewTopic(JsonUtil.opt(toolContentJSON, "allowNewTopic", Boolean.TRUE)); // defaults to true in the - // default entry in the db - forum.setAllowRateMessages(JsonUtil.opt(toolContentJSON, "allowRateMessages", Boolean.FALSE)); - forum.setAllowRichEditor(JsonUtil.opt(toolContentJSON, RestTags.ALLOW_RICH_TEXT_EDITOR, Boolean.FALSE)); - forum.setAllowUpload(JsonUtil.opt(toolContentJSON, "allowUpload", Boolean.FALSE)); + forum.setAllowAnonym(JsonUtil.optBoolean(toolContentJSON, "allowAnonym", Boolean.FALSE)); + forum.setAllowEdit(JsonUtil.optBoolean(toolContentJSON, "allowEdit", Boolean.TRUE)); // defaults to true in the default + // entry in the db + forum.setAllowNewTopic(JsonUtil.optBoolean(toolContentJSON, "allowNewTopic", Boolean.TRUE)); // defaults to true in the + // default entry in the db + forum.setAllowRateMessages(JsonUtil.optBoolean(toolContentJSON, "allowRateMessages", Boolean.FALSE)); + forum.setAllowRichEditor(JsonUtil.optBoolean(toolContentJSON, RestTags.ALLOW_RICH_TEXT_EDITOR, Boolean.FALSE)); + forum.setAllowUpload(JsonUtil.optBoolean(toolContentJSON, "allowUpload", Boolean.FALSE)); forum.setContentInUse(false); forum.setDefineLater(false); - forum.setLimitedMaxCharacters(JsonUtil.opt(toolContentJSON, "limitedMaxCharacters", Boolean.TRUE)); - forum.setLimitedMinCharacters(JsonUtil.opt(toolContentJSON, "limitedMinCharacters", Boolean.FALSE)); - forum.setLockWhenFinished(JsonUtil.opt(toolContentJSON, "lockWhenFinished", Boolean.FALSE)); - forum.setMaxCharacters(JsonUtil.opt(toolContentJSON, "maxCharacters", 5000)); // defaults to 5000 chars in the - // default entry in the db. - forum.setMaximumRate(JsonUtil.opt(toolContentJSON, "maximumRate", 0)); - forum.setMaximumReply(JsonUtil.opt(toolContentJSON, "maximumReply", 0)); - forum.setMinCharacters(JsonUtil.opt(toolContentJSON, "minCharacters", 0)); - forum.setMinimumRate(JsonUtil.opt(toolContentJSON, "minimumRate", 0)); - forum.setMinimumReply(JsonUtil.opt(toolContentJSON, "minimumReply", 0)); + forum.setLimitedMaxCharacters(JsonUtil.optBoolean(toolContentJSON, "limitedMaxCharacters", Boolean.TRUE)); + forum.setLimitedMinCharacters(JsonUtil.optBoolean(toolContentJSON, "limitedMinCharacters", Boolean.FALSE)); + forum.setLockWhenFinished(JsonUtil.optBoolean(toolContentJSON, "lockWhenFinished", Boolean.FALSE)); + forum.setMaxCharacters(JsonUtil.optInt(toolContentJSON, "maxCharacters", 5000)); // defaults to 5000 chars in the + // default entry in the db. + forum.setMaximumRate(JsonUtil.optInt(toolContentJSON, "maximumRate", 0)); + forum.setMaximumReply(JsonUtil.optInt(toolContentJSON, "maximumReply", 0)); + forum.setMinCharacters(JsonUtil.optInt(toolContentJSON, "minCharacters", 0)); + forum.setMinimumRate(JsonUtil.optInt(toolContentJSON, "minimumRate", 0)); + forum.setMinimumReply(JsonUtil.optInt(toolContentJSON, "minimumReply", 0)); forum.setNotifyLearnersOnForumPosting( - JsonUtil.opt(toolContentJSON, "notifyLearnersOnForumPosting", Boolean.FALSE)); + JsonUtil.optBoolean(toolContentJSON, "notifyLearnersOnForumPosting", Boolean.FALSE)); forum.setNotifyLearnersOnMarkRelease( - JsonUtil.opt(toolContentJSON, "notifyLearnersOnMarkRelease", Boolean.FALSE)); + JsonUtil.optBoolean(toolContentJSON, "notifyLearnersOnMarkRelease", Boolean.FALSE)); forum.setNotifyTeachersOnForumPosting( - JsonUtil.opt(toolContentJSON, "notifyTeachersOnForumPosting", Boolean.FALSE)); - forum.setReflectInstructions((String) JsonUtil.opt(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS, null)); - forum.setReflectOnActivity(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); + JsonUtil.optBoolean(toolContentJSON, "notifyTeachersOnForumPosting", Boolean.FALSE)); + forum.setReflectInstructions(JsonUtil.optString(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS)); + forum.setReflectOnActivity(JsonUtil.optBoolean(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); // submissionDeadline is set in monitoring // *******************************Handle user******************* @@ -1571,27 +1570,27 @@ // UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); ForumUser forumUser = getUserByID(userID.longValue()); if (forumUser == null) { - forumUser = new ForumUser(userID.longValue(), toolContentJSON.getString("firstName"), - toolContentJSON.getString("lastName"), toolContentJSON.getString("loginName")); + forumUser = new ForumUser(userID.longValue(), JsonUtil.optString(toolContentJSON, "firstName"), + JsonUtil.optString(toolContentJSON, "lastName"), JsonUtil.optString(toolContentJSON, "loginName")); getForumUserDao().save(forumUser); } forum.setCreatedBy(forumUser); updateForum(forum); // **************************** Handle topic ********************* - JSONArray topics = toolContentJSON.getJSONArray("topics"); - for (int i = 0; i < topics.length(); i++) { - JSONObject msgData = (JSONObject) topics.get(i); + ArrayNode topics = JsonUtil.optArray(toolContentJSON, "topics"); + for (int i = 0; i < topics.size(); i++) { + ObjectNode msgData = (ObjectNode) topics.get(i); Message newMsg = new Message(); // newMsg.setAttachments(attachments); TODO newMsg.setCreatedBy(forumUser); newMsg.setCreated(updateDate); newMsg.setModifiedBy(null); newMsg.setUpdated(updateDate); - newMsg.setSubject(msgData.getString("subject")); - newMsg.setBody(msgData.getString("body")); + newMsg.setSubject(JsonUtil.optString(msgData, "subject")); + newMsg.setBody(JsonUtil.optString(msgData, "body")); newMsg.setForum(forum); newMsg.setHideFlag(false); // newMsg.setIsAnonymous(false); Does not appear on authoring interface Index: lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/web/actions/MonitoringAction.java =================================================================== diff -u -r60d9a173d5590295376322fc3e857ae2dca37717 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/web/actions/MonitoringAction.java (.../MonitoringAction.java) (revision 60d9a173d5590295376322fc3e857ae2dca37717) +++ lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/web/actions/MonitoringAction.java (.../MonitoringAction.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -59,9 +59,6 @@ import org.apache.struts.action.ActionMessages; import org.apache.struts.action.ActionRedirect; import org.apache.struts.config.ForwardConfig; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.tool.forum.dto.MessageDTO; import org.lamsfoundation.lams.tool.forum.dto.SessionDTO; import org.lamsfoundation.lams.tool.forum.persistence.Forum; @@ -87,6 +84,10 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + public class MonitoringAction extends Action { private static Logger log = Logger.getLogger(MonitoringAction.class); @@ -221,7 +222,8 @@ Date tzSubmissionDeadline = DateUtil.convertToTimeZoneFromDefault(learnerTimeZone, submissionDeadline); sessionMap.put(ForumConstants.ATTR_SUBMISSION_DEADLINE, tzSubmissionDeadline.getTime()); // use the unconverted time, as convertToStringForJSON() does the timezone conversion if needed - request.setAttribute(ForumConstants.ATTR_SUBMISSION_DEADLINE_DATESTRING, DateUtil.convertToStringForJSON(submissionDeadline, request.getLocale())); + request.setAttribute(ForumConstants.ATTR_SUBMISSION_DEADLINE_DATESTRING, + DateUtil.convertToStringForJSON(submissionDeadline, request.getLocale())); } boolean isGroupedActivity = forumService.isGroupedActivity(toolContentId); @@ -232,7 +234,7 @@ * Refreshes user list. */ public ActionForward getUsers(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse res) throws IOException, ServletException, JSONException { + HttpServletResponse res) throws IOException, ServletException { forumService = getForumService(); String sessionMapId = WebUtil.readStrParam(request, ForumConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession() @@ -295,14 +297,14 @@ List users = forumService.getUsersForTablesorter(sessionId, page, size, sorting, searchString, forum.isReflectOnActivity()); - JSONArray rows = new JSONArray(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); - JSONObject responcedata = new JSONObject(); + ObjectNode responcedata = JsonNodeFactory.instance.objectNode(); responcedata.put("total_rows", forumService.getCountUsersBySession(sessionId, searchString)); for (Object[] userAndReflection : users) { - JSONObject responseRow = new JSONObject(); + ObjectNode responseRow = JsonNodeFactory.instance.objectNode(); ForumUser user = (ForumUser) userAndReflection[0]; @@ -339,14 +341,14 @@ if (userAndReflection.length > 1 && userAndReflection[1] != null) { responseRow.put("notebookEntry", StringEscapeUtils.escapeHtml((String) userAndReflection[1])); } - + if (userAndReflection.length > 2 && userAndReflection[2] != null) { - responseRow.put(ForumConstants.ATTR_PORTRAIT_ID, userAndReflection[2]); + responseRow.put(ForumConstants.ATTR_PORTRAIT_ID, (String) userAndReflection[2]); } - rows.put(responseRow); + rows.add(responseRow); } - responcedata.put("rows", rows); + responcedata.set("rows", rows); res.setContentType("application/json;charset=utf-8"); res.getWriter().print(new String(responcedata.toString())); return null; @@ -805,7 +807,7 @@ return mapping.findForward("success"); } else { // mark from view forum - // display root topic rather than leaf one + // display root topic rather than leaf one Long rootTopicId = forumService.getRootTopicId(msg.getUid()); ForwardConfig redirectConfig = mapping.findForwardConfig("viewTopic"); @@ -826,7 +828,7 @@ * @param request * @param response * @return - * @throws IOException + * @throws IOException */ public ActionForward setSubmissionDeadline(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException { @@ -878,8 +880,7 @@ * @return */ private Map> getTopicsSortedByAuthor(List topics) { - Map> topicsByUser = new TreeMap<>( - new ForumUserComparator()); + Map> topicsByUser = new TreeMap<>(new ForumUserComparator()); for (MessageDTO topic : topics) { if (topic.getMessage().getIsAuthored()) { continue; Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/service/McService.java =================================================================== diff -u -r729f1d10a1efd78ec420b373a7af23ee66ec3454 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/service/McService.java (.../McService.java) (revision 729f1d10a1efd78ec420b373a7af23ee66ec3454) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/service/McService.java (.../McService.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -51,9 +51,6 @@ import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.contentrepository.client.IToolContentHandler; import org.lamsfoundation.lams.gradebook.service.IGradebookService; import org.lamsfoundation.lams.learning.service.ILearnerService; @@ -111,6 +108,10 @@ import org.lamsfoundation.lams.web.util.AttributeNames; import org.springframework.dao.DataAccessException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * * The POJO implementation of Mc service. All business logics of MCQ tool are implemented in this class. It translate @@ -594,7 +595,8 @@ for (McUsrAttempt attempt : finalizedUserAttempts) { Integer displayOrder = attempt.getMcQueContent().getDisplayOrder(); int arrayIndex = (displayOrder != null) && (displayOrder.intValue() > 0) - ? displayOrder.intValue() - 1 : 1; + ? displayOrder.intValue() - 1 + : 1; if (userMarks[arrayIndex] == null) { // We get the mark for the attempt if the answer is correct and we don't allow @@ -667,7 +669,7 @@ e); } } - + @Override public List getLearnerMarksByContentId(Long toolContentId) { return mcUsrAttemptDAO.getLearnerMarksByContentId(toolContentId); @@ -1529,7 +1531,7 @@ public ToolOutput getToolOutput(String name, Long toolSessionId, Long learnerId) { return mcOutputFactory.getToolOutput(name, this, toolSessionId, learnerId); } - + @Override public List getToolOutputs(String name, Long toolContentId) { return mcOutputFactory.getToolOutputs(name, this, toolContentId); @@ -1588,10 +1590,10 @@ public boolean isGroupedActivity(long toolContentID) { return toolService.isGroupedActivity(toolContentID); } - + @Override public void auditLogStartEditingActivityInMonitor(long toolContentID) { - toolService.auditLogStartEditingActivityInMonitor(toolContentID); + toolService.auditLogStartEditingActivityInMonitor(toolContentID); } @Override @@ -1795,32 +1797,41 @@ for (McUsrAttempt item : attempts) { Date newDate = item.getAttemptTime(); if (newDate != null) { - if (startDate == null || newDate.before(startDate)) + if (startDate == null || newDate.before(startDate)) { startDate = newDate; - if (endDate == null || newDate.after(endDate)) + } + if (endDate == null || newDate.after(endDate)) { endDate = newDate; + } } } - if (learner.isResponseFinalised()) + if (learner.isResponseFinalised()) { return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_COMPLETED, startDate, endDate); - else + } else { return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_ATTEMPTED, startDate, null); + } } @Override public LeaderResultsDTO getLeaderResultsDTOForLeaders(Long contentId) { LeaderResultsDTO newDto = new LeaderResultsDTO(contentId); Object[] markStats = mcUserDAO.getStatsMarksForLeaders(contentId); - if ( markStats != null ) { - newDto.setMinMark(markStats[0] != null ? NumberUtil.formatLocalisedNumber((Float)markStats[0], (Locale)null, 2) : "0.00"); - newDto.setAvgMark(markStats[1] != null ? NumberUtil.formatLocalisedNumber((Float)markStats[1], (Locale)null, 2) : "0.00"); - newDto.setMaxMark(markStats[2] != null ? NumberUtil.formatLocalisedNumber((Float)markStats[2], (Locale)null, 2) : "0.00"); - newDto.setNumberGroupsLeaderFinished((Integer)markStats[3]); + if (markStats != null) { + newDto.setMinMark( + markStats[0] != null ? NumberUtil.formatLocalisedNumber((Float) markStats[0], (Locale) null, 2) + : "0.00"); + newDto.setAvgMark( + markStats[1] != null ? NumberUtil.formatLocalisedNumber((Float) markStats[1], (Locale) null, 2) + : "0.00"); + newDto.setMaxMark( + markStats[2] != null ? NumberUtil.formatLocalisedNumber((Float) markStats[2], (Locale) null, 2) + : "0.00"); + newDto.setNumberGroupsLeaderFinished((Integer) markStats[3]); } return newDto; } - + @SuppressWarnings("unchecked") @Override public List getSessionDtos(Long contentId, boolean includeStatistics) { @@ -1841,11 +1852,14 @@ Object[] markStats = mcUserDAO.getStatsMarksBySession(session.getMcSessionId()); if (markStats != null) { sessionDto.setMinMark(markStats[0] != null - ? NumberUtil.formatLocalisedNumber((Float) markStats[0], (Locale) null, 2) : "0.00"); + ? NumberUtil.formatLocalisedNumber((Float) markStats[0], (Locale) null, 2) + : "0.00"); sessionDto.setAvgMark(markStats[1] != null - ? NumberUtil.formatLocalisedNumber((Float) markStats[1], (Locale) null, 2) : "0.00"); + ? NumberUtil.formatLocalisedNumber((Float) markStats[1], (Locale) null, 2) + : "0.00"); sessionDto.setMaxMark(markStats[2] != null - ? NumberUtil.formatLocalisedNumber((Float) markStats[2], (Locale) null, 2) : "0.00"); + ? NumberUtil.formatLocalisedNumber((Float) markStats[2], (Locale) null, 2) + : "0.00"); } } @@ -1854,7 +1868,7 @@ } return sessionDtos; } - + @Override public List getMarksArray(Long sessionId) { return mcUserDAO.getRawUserMarksBySession(sessionId); @@ -1865,22 +1879,19 @@ return mcUserDAO.getRawLeaderMarksByToolContentId(toolContentId); } - - // ****************** REST methods ************************* /** * Rest call to create a new Multiple Choice content. Required fields in toolContentJSON: "title", "instructions", - * "questions". The questions entry should be JSONArray containing JSON objects, which in turn must contain - * "questionText", "displayOrder" (Integer) and a JSONArray "answers". The answers entry should be JSONArray + * "questions". The questions entry should be ArrayNode containing JSON objects, which in turn must contain + * "questionText", "displayOrder" (Integer) and a ArrayNode "answers". The answers entry should be ArrayNode * containing JSON objects, which in turn must contain "answerText", "displayOrder" (Integer), "correct" (Boolean). * * Retries are controlled by lockWhenFinished, which defaults to true (no retries). */ @SuppressWarnings("unchecked") @Override - public void createRestToolContent(Integer userID, Long toolContentID, JSONObject toolContentJSON) - throws JSONException { + public void createRestToolContent(Integer userID, Long toolContentID, ObjectNode toolContentJSON) { McContent mcq = new McContent(); Date updateDate = new Date(); @@ -1891,37 +1902,38 @@ mcq.setDefineLater(false); mcq.setMcContentId(toolContentID); - mcq.setTitle(toolContentJSON.getString(RestTags.TITLE)); - mcq.setInstructions(toolContentJSON.getString(RestTags.INSTRUCTIONS)); + mcq.setTitle(JsonUtil.optString(toolContentJSON, RestTags.TITLE)); + mcq.setInstructions(JsonUtil.optString(toolContentJSON, RestTags.INSTRUCTIONS)); - mcq.setRetries(JsonUtil.opt(toolContentJSON, "allowRetries", Boolean.FALSE)); + mcq.setRetries(JsonUtil.optBoolean(toolContentJSON, "allowRetries", Boolean.FALSE)); mcq.setUseSelectLeaderToolOuput( - JsonUtil.opt(toolContentJSON, RestTags.USE_SELECT_LEADER_TOOL_OUTPUT, Boolean.FALSE)); - mcq.setReflect(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); - mcq.setReflectionSubject(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS, "")); - mcq.setQuestionsSequenced(JsonUtil.opt(toolContentJSON, "questionsSequenced", Boolean.FALSE)); - mcq.setRandomize(JsonUtil.opt(toolContentJSON, "randomize", Boolean.FALSE)); - mcq.setShowReport(JsonUtil.opt(toolContentJSON, "showReport", Boolean.FALSE)); - mcq.setDisplayAnswers(JsonUtil.opt(toolContentJSON, "displayAnswers", Boolean.FALSE)); - mcq.setShowMarks(JsonUtil.opt(toolContentJSON, "showMarks", Boolean.FALSE)); - mcq.setPrefixAnswersWithLetters(JsonUtil.opt(toolContentJSON, "prefixAnswersWithLetters", Boolean.TRUE)); - mcq.setPassMark(JsonUtil.opt(toolContentJSON, "passMark", 0)); + JsonUtil.optBoolean(toolContentJSON, RestTags.USE_SELECT_LEADER_TOOL_OUTPUT, Boolean.FALSE)); + mcq.setReflect(JsonUtil.optBoolean(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); + mcq.setReflectionSubject(JsonUtil.optString(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS, "")); + mcq.setQuestionsSequenced(JsonUtil.optBoolean(toolContentJSON, "questionsSequenced", Boolean.FALSE)); + mcq.setRandomize(JsonUtil.optBoolean(toolContentJSON, "randomize", Boolean.FALSE)); + mcq.setShowReport(JsonUtil.optBoolean(toolContentJSON, "showReport", Boolean.FALSE)); + mcq.setDisplayAnswers(JsonUtil.optBoolean(toolContentJSON, "displayAnswers", Boolean.FALSE)); + mcq.setShowMarks(JsonUtil.optBoolean(toolContentJSON, "showMarks", Boolean.FALSE)); + mcq.setPrefixAnswersWithLetters(JsonUtil.optBoolean(toolContentJSON, "prefixAnswersWithLetters", Boolean.TRUE)); + mcq.setPassMark(JsonUtil.optInt(toolContentJSON, "passMark", 0)); // submissionDeadline is set in monitoring createMc(mcq); // Questions - JSONArray questions = toolContentJSON.getJSONArray(RestTags.QUESTIONS); - for (int i = 0; i < questions.length(); i++) { - JSONObject questionData = (JSONObject) questions.get(i); - McQueContent question = new McQueContent(questionData.getString(RestTags.QUESTION_TEXT), - questionData.getInt(RestTags.DISPLAY_ORDER), 1, "", mcq, null, new HashSet()); + ArrayNode questions = JsonUtil.optArray(toolContentJSON, RestTags.QUESTIONS); + for (JsonNode questionData : questions) { + McQueContent question = new McQueContent(JsonUtil.optString(questionData, RestTags.QUESTION_TEXT), + JsonUtil.optInt(questionData, RestTags.DISPLAY_ORDER), 1, "", mcq, null, + new HashSet()); - JSONArray optionsData = questionData.getJSONArray(RestTags.ANSWERS); - for (int j = 0; j < optionsData.length(); j++) { - JSONObject optionData = (JSONObject) optionsData.get(j); - question.getMcOptionsContents().add(new McOptsContent(optionData.getInt(RestTags.DISPLAY_ORDER), - optionData.getBoolean(RestTags.CORRECT), optionData.getString(RestTags.ANSWER_TEXT), question)); + ArrayNode optionsData = JsonUtil.optArray(questionData, RestTags.ANSWERS); + for (JsonNode optionData : optionsData) { + question.getMcOptionsContents() + .add(new McOptsContent(JsonUtil.optInt(optionData, RestTags.DISPLAY_ORDER), + JsonUtil.optBoolean(optionData, RestTags.CORRECT), + JsonUtil.optString(optionData, RestTags.ANSWER_TEXT), question)); } saveOrUpdateMcQueContent(question); } Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/action/McMonitoringAction.java =================================================================== diff -u -r729f1d10a1efd78ec420b373a7af23ee66ec3454 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/action/McMonitoringAction.java (.../McMonitoringAction.java) (revision 729f1d10a1efd78ec420b373a7af23ee66ec3454) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/action/McMonitoringAction.java (.../McMonitoringAction.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -37,14 +37,10 @@ import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; -import org.apache.log4j.Logger; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionRedirect; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.notebook.model.NotebookEntry; import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; import org.lamsfoundation.lams.tool.exception.ToolException; @@ -62,18 +58,21 @@ import org.lamsfoundation.lams.tool.mc.service.IMcService; import org.lamsfoundation.lams.tool.mc.service.McServiceProxy; import org.lamsfoundation.lams.util.DateUtil; +import org.lamsfoundation.lams.util.JsonUtil; import org.lamsfoundation.lams.util.MessageService; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.action.LamsDispatchAction; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * * @author Ozgur Demirtas */ public class McMonitoringAction extends LamsDispatchAction { - private static Logger logger = Logger.getLogger(McMonitoringAction.class.getName()); - /** * displayAnswers */ @@ -82,11 +81,11 @@ IMcService mcService = McServiceProxy.getMcService(getServlet().getServletContext()); String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); - + McContent mcContent = mcService.getMcContent(new Long(strToolContentID)); mcContent.setDisplayAnswers(new Boolean(true)); mcService.updateMc(mcContent); - + // use redirect to prevent resubmition of the same request ActionRedirect redirect = new ActionRedirect(mapping.findForwardConfig("monitoringStarterRedirect")); redirect.addParameter(McAppConstants.TOOL_CONTENT_ID, strToolContentID); @@ -173,7 +172,8 @@ /** * Set Submission Deadline - * @throws IOException + * + * @throws IOException */ public ActionForward setSubmissionDeadline(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException { @@ -214,14 +214,14 @@ * @throws IOException */ public ActionForward setActivityEvaluation(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws JSONException, IOException { + HttpServletResponse response) throws IOException { IMcService service = McServiceProxy.getMcService(getServlet().getServletContext()); Long contentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); String activityEvaluation = WebUtil.readStrParam(request, McAppConstants.ATTR_ACTIVITY_EVALUATION); service.setActivityEvaluation(contentID, activityEvaluation); - JSONObject responseJSON = new JSONObject(); + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); responseJSON.put("success", "true"); response.setContentType("application/json;charset=utf-8"); response.getWriter().print(new String(responseJSON.toString())); @@ -270,7 +270,7 @@ * Return paged users for jqGrid. */ public ActionForward getPagedUsers(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws JSONException, IOException { + HttpServletResponse response) throws IOException { IMcService mcService = McServiceProxy.getMcService(getServlet().getServletContext()); Long sessionId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); @@ -295,38 +295,38 @@ int totalPages = new Double( Math.ceil(new Integer(countVisitLogs).doubleValue() / new Integer(rowLimit).doubleValue())).intValue(); - JSONArray rows = new JSONArray(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); int i = 1; for (McUserMarkDTO userDto : userDtos) { - JSONArray visitLogData = new JSONArray(); + ArrayNode visitLogData = JsonNodeFactory.instance.arrayNode(); Long userUid = Long.parseLong(userDto.getQueUsrId()); - visitLogData.put(userUid); - visitLogData.put(userDto.getUserId()); + visitLogData.add(userUid); + visitLogData.add(userDto.getUserId()); String fullName = StringEscapeUtils.escapeHtml(userDto.getFullName()); if (groupLeader != null && groupLeader.getUid().equals(userUid)) { fullName += " (" + mcService.getLocalizedMessage("label.monitoring.group.leader") + ")"; } - visitLogData.put(fullName); + visitLogData.add(fullName); Long totalMark = (userDto.getTotalMark() == null) ? 0 : userDto.getTotalMark(); - visitLogData.put(totalMark); + visitLogData.add(totalMark); + + visitLogData.add(userDto.getPortraitId()); - visitLogData.put(userDto.getPortraitId()); - - JSONObject userRow = new JSONObject(); + ObjectNode userRow = JsonNodeFactory.instance.objectNode(); userRow.put("id", i++); - userRow.put("cell", visitLogData); + userRow.set("cell", visitLogData); - rows.put(userRow); + rows.add(userRow); } - JSONObject responseJSON = new JSONObject(); + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); responseJSON.put("total", totalPages); responseJSON.put("page", page); responseJSON.put("records", countVisitLogs); - responseJSON.put("rows", rows); + responseJSON.set("rows", rows); response.setContentType("application/json;charset=utf-8"); response.getWriter().write(responseJSON.toString()); @@ -347,48 +347,49 @@ return null; } - + /** * Get the mark summary with data arranged in bands. Can be displayed graphically or in a table. */ public ActionForward getMarkChartData(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse res) throws IOException, ServletException, JSONException { + HttpServletResponse res) throws IOException, ServletException { IMcService mcService = McServiceProxy.getMcService(getServlet().getServletContext()); Long contentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); McContent mcContent = mcService.getMcContent(contentID); List results = null; - - if ( mcContent != null ) { - if ( mcContent.isUseSelectLeaderToolOuput() ) { + + if (mcContent != null) { + if (mcContent.isUseSelectLeaderToolOuput()) { results = mcService.getMarksArrayForLeaders(contentID); } else { Long sessionID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); results = mcService.getMarksArray(sessionID); } } - - JSONObject responseJSON = new JSONObject(); - if ( results != null ) - responseJSON.put("data", results); - else - responseJSON.put("data", new Float[0]); + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); + if (results != null) { + responseJSON.set("data", JsonUtil.readArray(results)); + } else { + responseJSON.set("data", JsonUtil.readArray(new Float[0])); + } + res.setContentType("application/json;charset=utf-8"); res.getWriter().write(responseJSON.toString()); return null; } - + public ActionForward statistic(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { IMcService mcService = McServiceProxy.getMcService(getServlet().getServletContext()); Long contentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); request.setAttribute(AttributeNames.PARAM_TOOL_CONTENT_ID, contentID); McContent mcContent = mcService.getMcContent(contentID); - if ( mcContent != null ) { - if ( mcContent.isUseSelectLeaderToolOuput() ) { + if (mcContent != null) { + if (mcContent.isUseSelectLeaderToolOuput()) { LeaderResultsDTO leaderDto = mcService.getLeaderResultsDTOForLeaders(contentID); request.setAttribute("leaderDto", leaderDto); } else { @@ -397,7 +398,7 @@ } request.setAttribute("useSelectLeaderToolOutput", mcContent.isUseSelectLeaderToolOuput()); } - + // prepare toolOutputDefinitions and activityEvaluation List toolOutputDefinitions = new ArrayList(); toolOutputDefinitions.add(McAppConstants.OUTPUT_NAME_LEARNER_MARK); @@ -409,5 +410,4 @@ return mapping.findForward(McAppConstants.STATISTICS); } - } Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/service/QaService.java =================================================================== diff -u -r729f1d10a1efd78ec420b373a7af23ee66ec3454 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/service/QaService.java (.../QaService.java) (revision 729f1d10a1efd78ec420b373a7af23ee66ec3454) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/service/QaService.java (.../QaService.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -21,7 +21,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.tool.qa.service; import java.util.ArrayList; @@ -39,9 +38,6 @@ import javax.servlet.http.HttpSession; import org.apache.log4j.Logger; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.contentrepository.client.IToolContentHandler; import org.lamsfoundation.lams.events.IEventNotificationService; import org.lamsfoundation.lams.learning.service.ILearnerService; @@ -95,6 +91,10 @@ import org.lamsfoundation.lams.web.util.AttributeNames; import org.springframework.dao.DataAccessException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * The POJO implementation of Qa service. All business logics of Qa tool are implemented in this class. It translate the * request from presentation layer and perform approporiate database operation. @@ -568,8 +568,7 @@ @SuppressWarnings("unchecked") public void removeLearnerContent(Long toolContentId, Integer userId) throws ToolException { if (logger.isDebugEnabled()) { - logger - .debug("Removing Q&A answers for user ID " + userId + " and toolContentId " + toolContentId); + logger.debug("Removing Q&A answers for user ID " + userId + " and toolContentId " + toolContentId); } QaContent content = qaDAO.getQaByContentId(toolContentId); @@ -844,7 +843,7 @@ public boolean isCommentsEnabled(Long toolContentId) { return ratingService.isCommentsEnabled(toolContentId); } - + @Override public boolean isRatingsEnabled(QaContent qaContent) { //check if allow rate answers is ON and also that there is at least one non-comments rating criteria available @@ -864,7 +863,8 @@ @Override public List getRatingCriteriaDtos(Long contentId, Long toolSessionId, Collection itemIds, boolean isCommentsByOtherUsersRequired, Long userId) { - return ratingService.getRatingCriteriaDtos(contentId, toolSessionId, itemIds, isCommentsByOtherUsersRequired, userId); + return ratingService.getRatingCriteriaDtos(contentId, toolSessionId, itemIds, isCommentsByOtherUsersRequired, + userId); } @Override @@ -899,7 +899,7 @@ public ToolOutput getToolOutput(String name, Long toolSessionId, Long learnerId) { return getQaOutputFactory().getToolOutput(name, this, toolSessionId, learnerId); } - + @Override public List getToolOutputs(String name, Long toolContentId) { return new ArrayList(); @@ -974,10 +974,10 @@ public boolean isGroupedActivity(long toolContentID) { return toolService.isGroupedActivity(toolContentID); } - + @Override public void auditLogStartEditingActivityInMonitor(long toolContentID) { - toolService.auditLogStartEditingActivityInMonitor(toolContentID); + toolService.auditLogStartEditingActivityInMonitor(toolContentID); } @Override @@ -1205,35 +1205,37 @@ if (learner == null) { return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_NOT_ATTEMPTED, null, null); } - + Date startDate = null; Date endDate = null; Set attempts = learner.getQaUsrResps(); for (QaUsrResp item : attempts) { Date newDate = item.getAttemptTime(); if (newDate != null) { - if (startDate == null || newDate.before(startDate)) + if (startDate == null || newDate.before(startDate)) { startDate = newDate; - if (endDate == null || newDate.after(endDate)) + } + if (endDate == null || newDate.after(endDate)) { endDate = newDate; + } } } - if (learner.isLearnerFinished()) + if (learner.isLearnerFinished()) { return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_COMPLETED, startDate, endDate); - else + } else { return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_ATTEMPTED, startDate, null); + } } // ****************** REST methods ************************* /** * Rest call to create a new Q&A content. Required fields in toolContentJSON: title, instructions, questions. The - * questions entry should be JSONArray containing JSON objects, which in turn must contain "questionText", + * questions entry should be ArrayNode containing JSON objects, which in turn must contain "questionText", * "displayOrder" and may also contain feedback and required (boolean) */ @Override - public void createRestToolContent(Integer userID, Long toolContentID, JSONObject toolContentJSON) - throws JSONException { + public void createRestToolContent(Integer userID, Long toolContentID, ObjectNode toolContentJSON) { QaContent qa = new QaContent(); Date updateDate = new Date(); @@ -1243,26 +1245,26 @@ qa.setCreatedBy(userID.longValue()); qa.setQaContentId(toolContentID); - qa.setTitle(toolContentJSON.getString(RestTags.TITLE)); - qa.setInstructions(toolContentJSON.getString(RestTags.INSTRUCTIONS)); + qa.setTitle(JsonUtil.optString(toolContentJSON, RestTags.TITLE)); + qa.setInstructions(JsonUtil.optString(toolContentJSON, RestTags.INSTRUCTIONS)); qa.setDefineLater(false); - qa.setLockWhenFinished(JsonUtil.opt(toolContentJSON, RestTags.LOCK_WHEN_FINISHED, Boolean.FALSE)); - qa.setNoReeditAllowed(JsonUtil.opt(toolContentJSON, "noReeditAllowed", Boolean.FALSE)); - qa.setAllowRichEditor(JsonUtil.opt(toolContentJSON, RestTags.ALLOW_RICH_TEXT_EDITOR, Boolean.FALSE)); + qa.setLockWhenFinished(JsonUtil.optBoolean(toolContentJSON, RestTags.LOCK_WHEN_FINISHED, Boolean.FALSE)); + qa.setNoReeditAllowed(JsonUtil.optBoolean(toolContentJSON, "noReeditAllowed", Boolean.FALSE)); + qa.setAllowRichEditor(JsonUtil.optBoolean(toolContentJSON, RestTags.ALLOW_RICH_TEXT_EDITOR, Boolean.FALSE)); qa.setUseSelectLeaderToolOuput( - JsonUtil.opt(toolContentJSON, RestTags.USE_SELECT_LEADER_TOOL_OUTPUT, Boolean.FALSE)); - qa.setMinimumRates(JsonUtil.opt(toolContentJSON, RestTags.MINIMUM_RATES, 0)); - qa.setMaximumRates(JsonUtil.opt(toolContentJSON, RestTags.MAXIMUM_RATES, 0)); - qa.setShowOtherAnswers(JsonUtil.opt(toolContentJSON, "showOtherAnswers", Boolean.TRUE)); - qa.setUsernameVisible(JsonUtil.opt(toolContentJSON, "usernameVisible", Boolean.FALSE)); - qa.setAllowRateAnswers(JsonUtil.opt(toolContentJSON, "allowRateAnswers", Boolean.FALSE)); + JsonUtil.optBoolean(toolContentJSON, RestTags.USE_SELECT_LEADER_TOOL_OUTPUT, Boolean.FALSE)); + qa.setMinimumRates(JsonUtil.optInt(toolContentJSON, RestTags.MINIMUM_RATES, 0)); + qa.setMaximumRates(JsonUtil.optInt(toolContentJSON, RestTags.MAXIMUM_RATES, 0)); + qa.setShowOtherAnswers(JsonUtil.optBoolean(toolContentJSON, "showOtherAnswers", Boolean.TRUE)); + qa.setUsernameVisible(JsonUtil.optBoolean(toolContentJSON, "usernameVisible", Boolean.FALSE)); + qa.setAllowRateAnswers(JsonUtil.optBoolean(toolContentJSON, "allowRateAnswers", Boolean.FALSE)); qa.setNotifyTeachersOnResponseSubmit( - JsonUtil.opt(toolContentJSON, "notifyTeachersOnResponseSubmit", Boolean.FALSE)); - qa.setReflect(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); - qa.setReflectionSubject(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS, (String) null)); - qa.setQuestionsSequenced(JsonUtil.opt(toolContentJSON, "questionsSequenced", Boolean.FALSE)); + JsonUtil.optBoolean(toolContentJSON, "notifyTeachersOnResponseSubmit", Boolean.FALSE)); + qa.setReflect(JsonUtil.optBoolean(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); + qa.setReflectionSubject(JsonUtil.optString(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS)); + qa.setQuestionsSequenced(JsonUtil.optBoolean(toolContentJSON, "questionsSequenced", Boolean.FALSE)); // submissionDeadline is set in monitoring // qa.setMonitoringReportTitle(); Can't find this field in the database - assuming unused. @@ -1271,13 +1273,12 @@ saveOrUpdateQaContent(qa); // Questions - JSONArray questions = toolContentJSON.getJSONArray(RestTags.QUESTIONS); - for (int i = 0; i < questions.length(); i++) { - JSONObject questionData = (JSONObject) questions.get(i); - QaQueContent question = new QaQueContent(questionData.getString(RestTags.QUESTION_TEXT), - questionData.getInt(RestTags.DISPLAY_ORDER), JsonUtil.opt(questionData, "feedback", (String) null), - JsonUtil.opt(questionData, "required", Boolean.FALSE), - JsonUtil.opt(questionData, "minWordsLimit", 0), qa); + ArrayNode questions = JsonUtil.optArray(toolContentJSON, RestTags.QUESTIONS); + for (JsonNode questionData : questions) { + QaQueContent question = new QaQueContent(JsonUtil.optString(questionData, RestTags.QUESTION_TEXT), + JsonUtil.optInt(questionData, RestTags.DISPLAY_ORDER), JsonUtil.optString(questionData, "feedback"), + JsonUtil.optBoolean(questionData, "required", Boolean.FALSE), + JsonUtil.optInt(questionData, "minWordsLimit", 0), qa); saveOrUpdateQuestion(question); } Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/action/QaLearningAction.java =================================================================== diff -u -r729f1d10a1efd78ec420b373a7af23ee66ec3454 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/action/QaLearningAction.java (.../QaLearningAction.java) (revision 729f1d10a1efd78ec420b373a7af23ee66ec3454) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/action/QaLearningAction.java (.../QaLearningAction.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -19,7 +19,6 @@ http://www.gnu.org/licenses/gpl.txt * ***********************************************************************/ - package org.lamsfoundation.lams.tool.qa.web.action; import java.io.IOException; @@ -47,9 +46,6 @@ import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionMessages; import org.apache.struts.action.ActionRedirect; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.notebook.model.NotebookEntry; import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; import org.lamsfoundation.lams.rating.dto.ItemRatingCriteriaDTO; @@ -81,6 +77,10 @@ import org.lamsfoundation.lams.web.util.AttributeNames; import org.lamsfoundation.lams.web.util.SessionMap; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * @author Ozgur Demirtas */ @@ -219,7 +219,7 @@ } public ActionForward checkLeaderProgress(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws JSONException, IOException { + HttpServletResponse response) throws IOException { Long toolSessionId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); @@ -228,10 +228,10 @@ boolean isLeaderResponseFinalized = leader.isResponseFinalized(); - JSONObject JSONObject = new JSONObject(); - JSONObject.put("isLeaderResponseFinalized", isLeaderResponseFinalized); + ObjectNode ObjectNode = JsonNodeFactory.instance.objectNode(); + ObjectNode.put("isLeaderResponseFinalized", isLeaderResponseFinalized); response.setContentType("application/x-json;charset=utf-8"); - response.getWriter().print(JSONObject); + response.getWriter().print(ObjectNode); return null; } @@ -375,8 +375,8 @@ generalLearnerFlowDTO.setHttpSessionID(httpSessionID); /** Set up the data for the view all answers screen */ - QaLearningAction.refreshSummaryData(request, qaContent, qaSession, QaLearningAction.qaService, httpSessionID, user, - generalLearnerFlowDTO); + QaLearningAction.refreshSummaryData(request, qaContent, qaSession, QaLearningAction.qaService, + httpSessionID, user, generalLearnerFlowDTO); generalLearnerFlowDTO.setRequestLearningReport(new Boolean(true).toString()); generalLearnerFlowDTO.setRequestLearningReportProgress(new Boolean(false).toString()); @@ -457,8 +457,8 @@ qaLearningForm.resetUserActions(); qaLearningForm.setSubmitAnswersContent(null); - QaLearningAction.refreshSummaryData(request, qaContent, qaSession, QaLearningAction.qaService, httpSessionID, user, - generalLearnerFlowDTO); + QaLearningAction.refreshSummaryData(request, qaContent, qaSession, QaLearningAction.qaService, httpSessionID, + user, generalLearnerFlowDTO); generalLearnerFlowDTO.setRequestLearningReport(new Boolean(true).toString()); generalLearnerFlowDTO.setRequestLearningReportProgress(new Boolean(false).toString()); @@ -799,8 +799,8 @@ generalLearnerFlowDTO.setNotebookEntry(entryText); generalLearnerFlowDTO.setRequestLearningReportProgress(new Boolean(true).toString()); - QaLearningAction.refreshSummaryData(request, qaContent, qaSession, QaLearningAction.qaService, httpSessionID, qaQueUsr, - generalLearnerFlowDTO); + QaLearningAction.refreshSummaryData(request, qaContent, qaSession, QaLearningAction.qaService, httpSessionID, + qaQueUsr, generalLearnerFlowDTO); boolean isLearnerFinished = qaQueUsr.isLearnerFinished(); generalLearnerFlowDTO.setRequestLearningReportViewOnly(new Boolean(isLearnerFinished).toString()); @@ -929,8 +929,8 @@ * User id is needed if isUserNamesVisible is false && learnerRequest is true, as it is required to work out if the * data being analysed is the current user. */ - public static void refreshSummaryData(HttpServletRequest request, QaContent qaContent, QaSession qaSession, IQaService qaService, - String httpSessionID, QaQueUsr user, GeneralLearnerFlowDTO generalLearnerFlowDTO) { + public static void refreshSummaryData(HttpServletRequest request, QaContent qaContent, QaSession qaSession, + IQaService qaService, String httpSessionID, QaQueUsr user, GeneralLearnerFlowDTO generalLearnerFlowDTO) { SessionMap sessionMap = (SessionMap) request.getSession() .getAttribute(httpSessionID); @@ -946,26 +946,26 @@ int commentsMinWordsLimit = 0; boolean isCommentsEnabled = false; int countRatedQuestions = 0; - if (qaContent.isAllowRateAnswers() ) { + if (qaContent.isAllowRateAnswers()) { - if ( userResponses.isEmpty()) { + if (userResponses.isEmpty()) { Set criterias = qaContent.getRatingCriterias(); - for ( LearnerItemRatingCriteria criteria : criterias ) { - if ( criteria.isCommentRating() ) { + for (LearnerItemRatingCriteria criteria : criterias) { + if (criteria.isCommentRating()) { isCommentsEnabled = true; break; } } - + } else { - // create itemIds list + // create itemIds list List itemIds = new LinkedList(); for (QaUsrResp responseIter : userResponses) { itemIds.add(responseIter.getResponseId()); } - List itemRatingDtos = qaService.getRatingCriteriaDtos(qaContent.getQaContentId(), qaSession.getQaSessionId(), itemIds, - true, userId); + List itemRatingDtos = qaService.getRatingCriteriaDtos(qaContent.getQaContentId(), + qaSession.getQaSessionId(), itemIds, true, userId); sessionMap.put(AttributeNames.ATTR_ITEM_RATING_DTOS, itemRatingDtos); if (itemRatingDtos.size() > 0) { @@ -992,9 +992,9 @@ countRatedQuestions = qaService.getCountItemsRatedByUser(qaContent.getQaContentId(), userId.intValue()); } } - + request.setAttribute(TOOL_SESSION_ID, qaSession.getQaSessionId()); - + sessionMap.put("commentsMinWordsLimit", commentsMinWordsLimit); sessionMap.put("isCommentsEnabled", isCommentsEnabled); sessionMap.put(AttributeNames.ATTR_COUNT_RATED_ITEMS, countRatedQuestions); @@ -1007,14 +1007,14 @@ * Refreshes user list. */ public ActionForward getResponses(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse res) throws IOException, ServletException, JSONException { + HttpServletResponse res) throws IOException, ServletException { initializeQAService(); // teacher timezone HttpSession ss = SessionManager.getSession(); UserDTO userDto = (UserDTO) ss.getAttribute(AttributeNames.USER); TimeZone userTimeZone = userDto.getTimeZone(); - + boolean isAllowRateAnswers = WebUtil.readBooleanParam(request, "isAllowRateAnswers"); boolean isAllowRichEditor = WebUtil.readBooleanParam(request, "isAllowRichEditor"); boolean isOnlyLeadersIncluded = WebUtil.readBooleanParam(request, "isOnlyLeadersIncluded", false); @@ -1046,29 +1046,29 @@ } else if (sortByCol2 != null) { sorting = sortByCol2.equals(0) ? QaAppConstants.SORT_BY_RATING_ASC : QaAppConstants.SORT_BY_RATING_DESC; - } else if ( ! isMonitoring) { + } else if (!isMonitoring) { // Is it learner and comment only? If so sort by number of comments. QaSession qaSession = QaLearningAction.qaService.getSessionById(qaSessionId); - Set criterias = qaSession.getQaContent().getRatingCriterias(); + Set criterias = qaSession.getQaContent().getRatingCriterias(); boolean hasComment = false; boolean hasRating = false; - for ( LearnerItemRatingCriteria criteria : criterias ) { - if ( criteria.isCommentRating() ) { + for (LearnerItemRatingCriteria criteria : criterias) { + if (criteria.isCommentRating()) { hasComment = true; - } else { + } else { hasRating = true; } } - if ( hasComment && ! hasRating) { - sorting = QaAppConstants.SORT_BY_COMMENT_COUNT; + if (hasComment && !hasRating) { + sorting = QaAppConstants.SORT_BY_COMMENT_COUNT; } } List responses = QaLearningAction.qaService.getResponsesForTablesorter(qaContentId, qaSessionId, questionUid, userId, isOnlyLeadersIncluded, page, size, sorting, searchString); - JSONObject responcedata = new JSONObject(); - JSONArray rows = new JSONArray(); + ObjectNode responcedata = JsonNodeFactory.instance.objectNode(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); responcedata.put("total_rows", QaLearningAction.qaService.getCountResponsesBySessionAndQuestion(qaSessionId, questionUid, userId, isOnlyLeadersIncluded, searchString)); @@ -1097,19 +1097,23 @@ for (QaUsrResp response : responses) { QaQueUsr user = response.getQaQueUser(); - /* LDEV-3891: This code has been commented out, as the escapeCsv puts double quotes in the string, which goes through to the - * client and wrecks img src entries. It appears the browser cannot process the string with all the double quotes. - * This is the second time it is being fixed - the escapeCsv was removed in LDEV-3448 and then added back in - * when Peer Review was added (LDEV-3480). If escapeCsv needs to be added in again, make sure it does not break + /* + * LDEV-3891: This code has been commented out, as the escapeCsv puts double quotes in the string, which + * goes through to the + * client and wrecks img src entries. It appears the browser cannot process the string with all the double + * quotes. + * This is the second time it is being fixed - the escapeCsv was removed in LDEV-3448 and then added back in + * when Peer Review was added (LDEV-3480). If escapeCsv needs to be added in again, make sure it does not + * break * learner added images being seen in monitoring. - //remove leading and trailing quotes - String answer = StringEscapeUtils.escapeCsv(response.getAnswer()); - if (isAllowRichEditor && answer.startsWith("\"") && answer.length() >= 3) { - answer = answer.substring(1, answer.length() - 1); - } + * //remove leading and trailing quotes + * String answer = StringEscapeUtils.escapeCsv(response.getAnswer()); + * if (isAllowRichEditor && answer.startsWith("\"") && answer.length() >= 3) { + * answer = answer.substring(1, answer.length() - 1); + * } */ - JSONObject responseRow = new JSONObject(); + ObjectNode responseRow = JsonNodeFactory.instance.objectNode(); responseRow.put("responseUid", response.getResponseId().toString()); responseRow.put("answer", response.getAnswer()); responseRow.put("userName", StringEscapeUtils.escapeCsv(user.getFullname())); @@ -1122,7 +1126,7 @@ // in the server time zone. Date attemptTime = response.getAttemptTime(); responseRow.put("attemptTime", DateUtil.convertToStringForJSON(attemptTime, request.getLocale())); - responseRow.put("timeAgo", DateUtil.convertToStringForTimeagoJSON(attemptTime)); + responseRow.put("timeAgo", DateUtil.convertToStringForTimeagoJSON(attemptTime)); if (isAllowRateAnswers) { @@ -1138,18 +1142,18 @@ boolean isItemAuthoredByUser = response.getQaQueUser().getQueUsrId().equals(userId); responseRow.put("isItemAuthoredByUser", isItemAuthoredByUser); - JSONArray criteriasRows = new JSONArray(); + ArrayNode criteriasRows = JsonNodeFactory.instance.arrayNode(); for (ItemRatingCriteriaDTO criteriaDto : itemRatingDto.getCriteriaDtos()) { - JSONObject criteriasRow = new JSONObject(); + ObjectNode criteriasRow = JsonNodeFactory.instance.objectNode(); criteriasRow.put("ratingCriteriaId", criteriaDto.getRatingCriteria().getRatingCriteriaId()); criteriasRow.put("title", criteriaDto.getRatingCriteria().getTitle()); criteriasRow.put("averageRating", criteriaDto.getAverageRating()); criteriasRow.put("numberOfVotes", criteriaDto.getNumberOfVotes()); criteriasRow.put("userRating", criteriaDto.getUserRating()); - criteriasRows.put(criteriasRow); + criteriasRows.add(criteriasRow); } - responseRow.put("criteriaDtos", criteriasRows); + responseRow.set("criteriaDtos", criteriasRows); //handle comments responseRow.put("commentsCriteriaId", itemRatingDto.getCommentsCriteriaId()); @@ -1158,9 +1162,9 @@ responseRow.put("commentPostedByUser", commentPostedByUser); if (itemRatingDto.getCommentDtos() != null) { - JSONArray comments = new JSONArray(); + ArrayNode comments = JsonNodeFactory.instance.arrayNode(); for (RatingCommentDTO commentDto : itemRatingDto.getCommentDtos()) { - JSONObject comment = new JSONObject(); + ObjectNode comment = JsonNodeFactory.instance.objectNode(); comment.put("comment", StringEscapeUtils.escapeCsv(commentDto.getComment())); if (isMonitoring) { @@ -1172,15 +1176,15 @@ comment.put("userFullName", StringEscapeUtils.escapeCsv(commentDto.getUserFullName())); } - comments.put(comment); + comments.add(comment); } - responseRow.put("comments", comments); + responseRow.set("comments", comments); } } - rows.put(responseRow); + rows.add(responseRow); } - responcedata.put("rows", rows); + responcedata.set("rows", rows); res.setContentType("application/json;charset=utf-8"); res.getWriter().print(new String(responcedata.toString())); Index: lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/service/ResourceServiceImpl.java =================================================================== diff -u -r8e090b3ddf269cdffececa4bc55a9333da5b0858 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/service/ResourceServiceImpl.java (.../ResourceServiceImpl.java) (revision 8e090b3ddf269cdffececa4bc55a9333da5b0858) +++ lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/service/ResourceServiceImpl.java (.../ResourceServiceImpl.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -32,7 +32,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.LinkedList; @@ -46,9 +45,6 @@ import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.apache.struts.upload.FormFile; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.contentrepository.ICredentials; import org.lamsfoundation.lams.contentrepository.ITicket; import org.lamsfoundation.lams.contentrepository.IVersionedNode; @@ -116,6 +112,10 @@ import org.lamsfoundation.lams.util.zipfile.ZipFileUtilException; import org.lamsfoundation.lams.web.util.AttributeNames; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * @author Dapeng.Ni */ @@ -310,7 +310,7 @@ } // add resource items from Authoring Resource resource = session.getResource(); - List items = new ArrayList(); + List items = new ArrayList<>(); items.addAll(resource.getResourceItems()); // add resource items from ResourceSession @@ -428,7 +428,7 @@ @Override public List getSummary(Long contentId) { - List groupList = new ArrayList(); + List groupList = new ArrayList<>(); Resource resource = resourceDao.getByContentId(contentId); @@ -442,14 +442,14 @@ group.setSessionId(session.getSessionId()); group.setSessionName(session.getSessionName()); - Set items = new TreeSet(new ResourceItemComparator()); + Set items = new TreeSet<>(new ResourceItemComparator()); // firstly, put all initial resource item into this group. items.addAll(resource.getResourceItems()); // add this session's resource items items.addAll(session.getResourceItems()); // item ids of items that could be rated. - List itemsToRate = new ArrayList(); + List itemsToRate = new ArrayList<>(); // get all item which is accessed by users in this session Map visitCountMap = resourceItemVisitDao.getSummary(contentId, session.getSessionId()); @@ -460,24 +460,25 @@ resourceItemDTO.setViewNumber(visitCountMap.get(item.getUid()).intValue()); } group.getItems().add(resourceItemDTO); - if ( item.isAllowRating() ) { + if (item.isAllowRating()) { itemsToRate.add(item.getUid()); } } - + List itemRatingDtos = null; - if ( itemsToRate.size() > 0 ) { - itemRatingDtos = ratingService.getRatingCriteriaDtos(contentId, session.getSessionId(), itemsToRate, false, -1L); + if (itemsToRate.size() > 0) { + itemRatingDtos = ratingService.getRatingCriteriaDtos(contentId, session.getSessionId(), itemsToRate, + false, -1L); group.setAllowRating(true); } else { group.setAllowRating(false); } - for (ResourceItemDTO item: group.getItems()) { + for (ResourceItemDTO item : group.getItems()) { if (item.isAllowRating()) { // find corresponding itemRatingDto - for ( ItemRatingDTO ratingDTO : itemRatingDtos ) { - if ( item.getItemUid().equals(ratingDTO.getItemId()) ) { + for (ItemRatingDTO ratingDTO : itemRatingDtos) { + if (item.getItemUid().equals(ratingDTO.getItemId())) { item.setRatingDTO(ratingDTO); break; } @@ -493,7 +494,7 @@ @Override public List getReflectList(Long contentId) { - List reflections = new LinkedList(); + List reflections = new LinkedList<>(); List sessionList = resourceSessionDao.getByContentId(contentId); for (ResourceSession session : sessionList) { @@ -529,7 +530,8 @@ user.setAccessDate(visit.getAccessDate()); user.setCompleteDate(visit.getCompleteDate()); Date timeTaken = ((visit.getCompleteDate() != null) && (visit.getAccessDate() != null)) - ? new Date(visit.getCompleteDate().getTime() - visit.getAccessDate().getTime()) : null; + ? new Date(visit.getCompleteDate().getTime() - visit.getAccessDate().getTime()) + : null; user.setTimeTaken(timeTaken); userList.add(user); } @@ -791,10 +793,10 @@ public boolean isGroupedActivity(long toolContentID) { return toolService.isGroupedActivity(toolContentID); } - + @Override public void auditLogStartEditingActivityInMonitor(long toolContentID) { - toolService.auditLogStartEditingActivityInMonitor(toolContentID); + toolService.auditLogStartEditingActivityInMonitor(toolContentID); } // ******************************************************************************* @@ -867,13 +869,13 @@ item.setCreateBy(user); useRatings = useRatings || item.isAllowRating(); } - + Set criterias = toolContentObj.getRatingCriterias(); if (criterias != null) { for (LearnerItemRatingCriteria criteria : criterias) { criteria.setToolContentId(toolContentId); } - } + } resourceDao.saveObject(toolContentObj); } catch (ImportToolContentException e) { @@ -1091,7 +1093,7 @@ @Override public List getToolOutputs(String name, Long toolContentId) { - return new ArrayList(); + return new ArrayList<>(); } @Override @@ -1107,8 +1109,9 @@ @Override public LearnerItemRatingCriteria createRatingCriteria(Long toolContentId) throws RatingException { List ratingCriterias = ratingService.getCriteriasByToolContentId(toolContentId); - if ( ratingCriterias == null || ratingCriterias.size() == 0 ) { - return ratingService.saveLearnerItemRatingCriteria(toolContentId, null, 1, RatingCriteria.RATING_STYLE_STAR, false, 0); + if (ratingCriterias == null || ratingCriterias.size() == 0) { + return ratingService.saveLearnerItemRatingCriteria(toolContentId, null, 1, RatingCriteria.RATING_STYLE_STAR, + false, 0); } else { return (LearnerItemRatingCriteria) ratingCriterias.get(0); } @@ -1118,9 +1121,10 @@ public int deleteRatingCriteria(Long toolContentId) { return ratingService.deleteAllRatingCriterias(toolContentId); } - + @Override - public List getRatingCriteriaDtos(Long toolContentId, Long toolSessionId, Collection itemIds, Long userId) { + public List getRatingCriteriaDtos(Long toolContentId, Long toolSessionId, Collection itemIds, + Long userId) { return ratingService.getRatingCriteriaDtos(toolContentId, toolSessionId, itemIds, false, userId); } @@ -1229,91 +1233,94 @@ if (learner == null) { return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_NOT_ATTEMPTED, null, null); } - + Object[] dates = resourceItemVisitDao.getDateRangeOfAccesses(learner.getUid(), toolSessionId); - if (learner.isSessionFinished()) - return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_COMPLETED, (Date)dates[0], (Date)dates[1]); - else - return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_ATTEMPTED,(Date) dates[0], null); + if (learner.isSessionFinished()) { + return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_COMPLETED, (Date) dates[0], (Date) dates[1]); + } else { + return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_ATTEMPTED, (Date) dates[0], null); + } } - + // ****************** REST methods ************************* /** * Used by the Rest calls to create content. Mandatory fields in toolContentJSON: title, instructions, resources, - * user fields firstName, lastName and loginName Resources must contain a JSONArray of JSONObject objects, which + * user fields firstName, lastName and loginName Resources must contain a ArrayNode of ObjectNode objects, which * have the following mandatory fields: title, description, type. If there are instructions for a resource, the - * instructions are a JSONArray of Strings. There should be at least one resource object in the resources array. + * instructions are a ArrayNode of Strings. There should be at least one resource object in the resources array. + * + * @throws IOException */ @Override - public void createRestToolContent(Integer userID, Long toolContentID, JSONObject toolContentJSON) - throws JSONException { + public void createRestToolContent(Integer userID, Long toolContentID, ObjectNode toolContentJSON) + throws IOException { Date updateDate = new Date(); Resource resource = new Resource(); resource.setContentId(toolContentID); - resource.setTitle(toolContentJSON.getString(RestTags.TITLE)); - resource.setInstructions(toolContentJSON.getString(RestTags.INSTRUCTIONS)); + resource.setTitle(JsonUtil.optString(toolContentJSON, RestTags.TITLE)); + resource.setInstructions(JsonUtil.optString(toolContentJSON, RestTags.INSTRUCTIONS)); resource.setCreated(updateDate); - resource.setAllowAddFiles(JsonUtil.opt(toolContentJSON, "allowAddFiles", Boolean.FALSE)); - resource.setAllowAddUrls(JsonUtil.opt(toolContentJSON, "allowAddUrls", Boolean.FALSE)); - resource.setLockWhenFinished(JsonUtil.opt(toolContentJSON, RestTags.LOCK_WHEN_FINISHED, Boolean.FALSE)); - resource.setMiniViewResourceNumber(JsonUtil.opt(toolContentJSON, "minViewResourceNumber", 0)); + resource.setAllowAddFiles(JsonUtil.optBoolean(toolContentJSON, "allowAddFiles", Boolean.FALSE)); + resource.setAllowAddUrls(JsonUtil.optBoolean(toolContentJSON, "allowAddUrls", Boolean.FALSE)); + resource.setLockWhenFinished(JsonUtil.optBoolean(toolContentJSON, RestTags.LOCK_WHEN_FINISHED, Boolean.FALSE)); + resource.setMiniViewResourceNumber(JsonUtil.optInt(toolContentJSON, "minViewResourceNumber", 0)); resource.setNotifyTeachersOnAssigmentSumbit( - JsonUtil.opt(toolContentJSON, "notifyTeachersOnAssigmentSubmit", Boolean.FALSE)); + JsonUtil.optBoolean(toolContentJSON, "notifyTeachersOnAssigmentSubmit", Boolean.FALSE)); resource.setNotifyTeachersOnAssigmentSumbit( - JsonUtil.opt(toolContentJSON, "notifyTeachersOnFileUpload", Boolean.FALSE)); - resource.setReflectOnActivity(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); - resource.setReflectInstructions(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS, (String) null)); - resource.setRunAuto(JsonUtil.opt(toolContentJSON, "runAuto", Boolean.FALSE)); + JsonUtil.optBoolean(toolContentJSON, "notifyTeachersOnFileUpload", Boolean.FALSE)); + resource.setReflectOnActivity( + JsonUtil.optBoolean(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); + resource.setReflectInstructions(JsonUtil.optString(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS)); + resource.setRunAuto(JsonUtil.optBoolean(toolContentJSON, "runAuto", Boolean.FALSE)); resource.setContentInUse(false); resource.setDefineLater(false); ResourceUser resourceUser = getUserByIDAndContent(userID.longValue(), toolContentID); if (resourceUser == null) { resourceUser = new ResourceUser(); - resourceUser.setFirstName(toolContentJSON.getString("firstName")); - resourceUser.setLastName(toolContentJSON.getString("lastName")); - resourceUser.setLoginName(toolContentJSON.getString("loginName")); + resourceUser.setFirstName(JsonUtil.optString(toolContentJSON, "firstName")); + resourceUser.setLastName(JsonUtil.optString(toolContentJSON, "lastName")); + resourceUser.setLoginName(JsonUtil.optString(toolContentJSON, "loginName")); // resourceUser.setResource(content); } resource.setCreatedBy(resourceUser); // **************************** Handle topic ********************* - JSONArray resources = toolContentJSON.getJSONArray("resources"); + ArrayNode resources = JsonUtil.optArray(toolContentJSON, "resources"); Set itemList = new LinkedHashSet(); - for (int i = 0; i < resources.length(); i++) { - JSONObject itemData = (JSONObject) resources.get(i); + for (JsonNode itemData : resources) { ResourceItem item = new ResourceItem(); - item.setTitle(itemData.getString("title")); - item.setType((short) itemData.getInt("type")); + item.setTitle(JsonUtil.optString(itemData, "title")); + item.setType(JsonUtil.optInt(itemData, "type").shortValue()); item.setCreateBy(resourceUser); item.setCreateDate(updateDate); item.setComplete(false); item.setCreateByAuthor(true); item.setHide(false); - item.setOrderId(itemData.getInt(RestTags.DISPLAY_ORDER)); + item.setOrderId(JsonUtil.optInt(itemData, RestTags.DISPLAY_ORDER)); - item.setDescription(JsonUtil.opt(itemData, "description", (String) null)); - item.setFileName(JsonUtil.opt(itemData, "name", (String) null)); - item.setFileType(JsonUtil.opt(itemData, "fileType", (String) null)); + item.setDescription(JsonUtil.optString(itemData, "description")); + item.setFileName(JsonUtil.optString(itemData, "name")); + item.setFileType(JsonUtil.optString(itemData, "fileType")); item.setFileUuid(JsonUtil.optLong(itemData, "crUuid")); item.setFileVersionId(JsonUtil.optLong(itemData, "crVersionId")); - item.setImsSchema(JsonUtil.opt(itemData, "imsSchema", (String) null)); - item.setOrganizationXml(JsonUtil.opt(itemData, "organizationXml", (String) null)); - item.setOpenUrlNewWindow(JsonUtil.opt(itemData, "openUrlNewWindow", Boolean.FALSE)); - item.setUrl(JsonUtil.opt(itemData, "url", (String) null)); + item.setImsSchema(JsonUtil.optString(itemData, "imsSchema")); + item.setOrganizationXml(JsonUtil.optString(itemData, "organizationXml")); + item.setOpenUrlNewWindow(JsonUtil.optBoolean(itemData, "openUrlNewWindow", Boolean.FALSE)); + item.setUrl(JsonUtil.optString(itemData, "url")); - JSONArray instructionStrings = itemData.getJSONArray("instructions"); - if ((instructionStrings != null) && (instructionStrings.length() > 0)) { + ArrayNode instructionStrings = JsonUtil.optArray(itemData, "instructions"); + if ((instructionStrings != null) && (instructionStrings.size() > 0)) { Set instructions = new LinkedHashSet(); - for (int j = 0; j < instructionStrings.length(); j++) { + for (int j = 0; j < instructionStrings.size(); j++) { ResourceItemInstruction rii = new ResourceItemInstruction(); - rii.setDescription(instructionStrings.getString(j)); + rii.setDescription(instructionStrings.get(j).asText(null)); rii.setSequenceId(j); instructions.add(rii); } @@ -1322,7 +1329,7 @@ // TODO files - need to save it somehow, validate the file size, etc. Needed for websites, files & LO if ((item.getFileName() != null) || (item.getFileUuid() != null)) { - throw new JSONException( + throw new IOException( "Only URLS supported via REST interface currently - files and learning objects are not supported."); } @@ -1335,6 +1342,7 @@ } + @Override public void evict(Object object) { resourceDao.releaseFromCache(object); } Index: lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/action/MonitoringAction.java =================================================================== diff -u -r8e090b3ddf269cdffececa4bc55a9333da5b0858 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision 8e090b3ddf269cdffececa4bc55a9333da5b0858) +++ lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -21,7 +21,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.tool.rsrc.web.action; import java.io.IOException; @@ -42,9 +41,6 @@ import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.notebook.model.NotebookEntry; import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; import org.lamsfoundation.lams.tool.rsrc.ResourceConstants; @@ -64,12 +60,16 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + public class MonitoringAction extends Action { public static Logger log = Logger.getLogger(MonitoringAction.class); @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException, JSONException { + HttpServletResponse response) throws IOException, ServletException { String param = mapping.getParameter(); request.setAttribute("initialTabId", WebUtil.readLongParam(request, AttributeNames.PARAM_CURRENT_TAB, true)); @@ -139,7 +139,7 @@ } private ActionForward getSubgridData(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws JSONException, IOException { + HttpServletResponse response) throws IOException { IResourceService service = getResourceService(); Long itemUid = WebUtil.readLongParam(request, ResourceConstants.ATTR_RESOURCE_ITEM_UID); @@ -162,7 +162,7 @@ int totalPages = new Double( Math.ceil(new Integer(countVisitLogs).doubleValue() / new Integer(rowLimit).doubleValue())).intValue(); - JSONArray rows = new JSONArray(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); DateFormat timeTakenFormatter = new SimpleDateFormat("H:mm:ss"); DateFormat dateFormatter = new SimpleDateFormat("d-MMM-yyyy h:mm a"); HttpSession ss = SessionManager.getSession(); @@ -171,35 +171,35 @@ int i = 1; for (VisitLogDTO visitLogDto : visitLogDtos) { - JSONArray visitLogData = new JSONArray(); - visitLogData.put(visitLogDto.getUserId()); + ArrayNode visitLogData = JsonNodeFactory.instance.arrayNode(); + visitLogData.add(visitLogDto.getUserId()); String fullName = StringEscapeUtils.escapeHtml(visitLogDto.getUserFullName()); - visitLogData.put(fullName); + visitLogData.add(fullName); String accessDate = (visitLogDto.getAccessDate() == null) ? "" : dateFormatter.format( DateUtil.convertToTimeZoneFromDefault(monitorTimeZone, visitLogDto.getAccessDate())); - visitLogData.put(accessDate); + visitLogData.add(accessDate); String completeDate = (visitLogDto.getCompleteDate() == null) ? "" : dateFormatter.format( DateUtil.convertToTimeZoneFromDefault(monitorTimeZone, visitLogDto.getCompleteDate())); - visitLogData.put(completeDate); + visitLogData.add(completeDate); String timeTaken = (visitLogDto.getTimeTaken() == null) ? "" : timeTakenFormatter.format(visitLogDto.getTimeTaken()); - visitLogData.put(timeTaken); - visitLogData.put(visitLogDto.getPortraitId()); + visitLogData.add(timeTaken); + visitLogData.add(visitLogDto.getPortraitId()); - JSONObject userRow = new JSONObject(); + ObjectNode userRow = JsonNodeFactory.instance.objectNode(); userRow.put("id", i++); - userRow.put("cell", visitLogData); + userRow.set("cell", visitLogData); - rows.put(userRow); + rows.add(userRow); } - JSONObject responseJSON = new JSONObject(); + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); responseJSON.put("total", totalPages); responseJSON.put("page", page); responseJSON.put("records", countVisitLogs); - responseJSON.put("rows", rows); + responseJSON.set("rows", rows); response.setContentType("application/json;charset=utf-8"); response.getWriter().write(responseJSON.toString()); Index: lams_tool_notebook/src/java/org/lamsfoundation/lams/tool/notebook/service/NotebookService.java =================================================================== diff -u -r8e090b3ddf269cdffececa4bc55a9333da5b0858 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_notebook/src/java/org/lamsfoundation/lams/tool/notebook/service/NotebookService.java (.../NotebookService.java) (revision 8e090b3ddf269cdffececa4bc55a9333da5b0858) +++ lams_tool_notebook/src/java/org/lamsfoundation/lams/tool/notebook/service/NotebookService.java (.../NotebookService.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -21,7 +21,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.tool.notebook.service; import java.util.ArrayList; @@ -33,8 +32,6 @@ import java.util.SortedMap; import org.apache.log4j.Logger; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.contentrepository.client.IToolContentHandler; import org.lamsfoundation.lams.events.IEventNotificationService; import org.lamsfoundation.lams.learning.service.ILearnerService; @@ -72,6 +69,8 @@ import org.lamsfoundation.lams.util.MessageService; import org.lamsfoundation.lams.util.audit.IAuditService; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * An implementation of the INotebookService interface. * @@ -164,10 +163,10 @@ public ToolOutput getToolOutput(String name, Long toolSessionId, Long learnerId) { return getNotebookOutputFactory().getToolOutput(name, this, toolSessionId, learnerId); } - + @Override public List getToolOutputs(String name, Long toolContentId) { - return new ArrayList(); + return new ArrayList<>(); } @Override @@ -638,10 +637,10 @@ public boolean isGroupedActivity(long toolContentID) { return toolService.isGroupedActivity(toolContentID); } - + @Override public void auditLogStartEditingActivityInMonitor(long toolContentID) { - toolService.auditLogStartEditingActivityInMonitor(toolContentID); + toolService.auditLogStartEditingActivityInMonitor(toolContentID); } @Override @@ -653,7 +652,7 @@ public Class[] getSupportedToolOutputDefinitionClasses(int definitionType) { return getNotebookOutputFactory().getSupportedDefinitionClasses(definitionType); } - + @Override public ToolCompletionStatus getCompletionStatus(Long learnerId, Long toolSessionId) { // db doesn't have a start/finish date for learner, and session start/finish is null @@ -672,20 +671,19 @@ * Rest call to create a new Notebook content. Required fields in toolContentJSON: "title", "instructions". */ @Override - public void createRestToolContent(Integer userID, Long toolContentID, JSONObject toolContentJSON) - throws JSONException { + public void createRestToolContent(Integer userID, Long toolContentID, ObjectNode toolContentJSON) { Date updateDate = new Date(); Notebook nb = new Notebook(); nb.setToolContentId(toolContentID); - nb.setTitle(toolContentJSON.getString(RestTags.TITLE)); - nb.setInstructions(toolContentJSON.getString(RestTags.INSTRUCTIONS)); + nb.setTitle(JsonUtil.optString(toolContentJSON, RestTags.TITLE)); + nb.setInstructions(JsonUtil.optString(toolContentJSON, RestTags.INSTRUCTIONS)); nb.setCreateBy(userID.longValue()); nb.setCreateDate(updateDate); nb.setUpdateDate(updateDate); - nb.setLockOnFinished(JsonUtil.opt(toolContentJSON, RestTags.LOCK_WHEN_FINISHED, Boolean.FALSE)); - nb.setAllowRichEditor(JsonUtil.opt(toolContentJSON, RestTags.ALLOW_RICH_TEXT_EDITOR, Boolean.FALSE)); + nb.setLockOnFinished(JsonUtil.optBoolean(toolContentJSON, RestTags.LOCK_WHEN_FINISHED, Boolean.FALSE)); + nb.setAllowRichEditor(JsonUtil.optBoolean(toolContentJSON, RestTags.ALLOW_RICH_TEXT_EDITOR, Boolean.FALSE)); // submissionDeadline is set in monitoring nb.setContentInUse(false); Index: lams_tool_notebook/src/java/org/lamsfoundation/lams/tool/notebook/web/actions/MonitoringAction.java =================================================================== diff -u -r8e090b3ddf269cdffececa4bc55a9333da5b0858 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_notebook/src/java/org/lamsfoundation/lams/tool/notebook/web/actions/MonitoringAction.java (.../MonitoringAction.java) (revision 8e090b3ddf269cdffececa4bc55a9333da5b0858) +++ lams_tool_notebook/src/java/org/lamsfoundation/lams/tool/notebook/web/actions/MonitoringAction.java (.../MonitoringAction.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -21,7 +21,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.tool.notebook.web.actions; import java.io.IOException; @@ -35,13 +34,9 @@ import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; -import org.apache.log4j.Logger; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.tool.notebook.dto.NotebookSessionsDTO; import org.lamsfoundation.lams.tool.notebook.model.Notebook; import org.lamsfoundation.lams.tool.notebook.model.NotebookUser; @@ -58,16 +53,11 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; -/** - * - * - * - * - * - */ -public class MonitoringAction extends LamsDispatchAction { +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; - private static Logger log = Logger.getLogger(MonitoringAction.class); +public class MonitoringAction extends LamsDispatchAction { private static String noEntryText = null; // access via getNoEntryText() public INotebookService notebookService; @@ -102,14 +92,15 @@ TimeZone teacherTimeZone = teacher.getTimeZone(); Date tzSubmissionDeadline = DateUtil.convertToTimeZoneFromDefault(teacherTimeZone, submissionDeadline); request.setAttribute(NotebookConstants.ATTR_SUBMISSION_DEADLINE, tzSubmissionDeadline.getTime()); - request.setAttribute(NotebookConstants.ATTR_SUBMISSION_DEADLINE_DATESTRING, DateUtil.convertToStringForJSON(submissionDeadline, request.getLocale())); + request.setAttribute(NotebookConstants.ATTR_SUBMISSION_DEADLINE_DATESTRING, + DateUtil.convertToStringForJSON(submissionDeadline, request.getLocale())); } return mapping.findForward("success"); } public ActionForward getUsers(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws JSONException, IOException { + HttpServletResponse response) throws IOException { setupService(); Long toolSessionId = new Long(WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID)); @@ -134,13 +125,13 @@ } } - JSONObject responsedata = new JSONObject(); + ObjectNode responsedata = JsonNodeFactory.instance.objectNode(); int totalRows = notebookService.getCountUsersBySession(toolSessionId, searchString); responsedata.put("total_rows", totalRows); responsedata.put("page", page); responsedata.put("total", Math.ceil((float) totalRows / size)); - JSONArray rows = new JSONArray(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); // our code expects the first page to be 0 but jqgrid uses 1 for the first page. List users = notebookService.getUsersForTablesorter(toolSessionId, page > 0 ? page - 1 : 0, size, sorting, searchString); @@ -150,15 +141,15 @@ int id = 1; for (Object[] userAndReflection : users) { - JSONObject responseRow = new JSONObject(); + ObjectNode responseRow = JsonNodeFactory.instance.objectNode(); NotebookUser user = (NotebookUser) userAndReflection[0]; responseRow.put("id", id++); responseRow.put(NotebookConstants.PARAM_USER_UID, user.getUid()); responseRow.put(NotebookConstants.PARAM_NAME, StringEscapeUtils.escapeHtml(user.getLastName() + " " + user.getFirstName())); if (userAndReflection.length > 1 && userAndReflection[1] != null) { - responseRow.put(NotebookConstants.PARAM_ENTRY, userAndReflection[1]); + responseRow.put(NotebookConstants.PARAM_ENTRY, (String) userAndReflection[1]); } if (user.getTeachersComment() != null && user.getTeachersComment().length() > 0) { responseRow.put(NotebookConstants.PARAM_COMMENT, user.getTeachersComment()); @@ -168,19 +159,19 @@ Date modifiedDate = (Date) userAndReflection[2]; responseRow.put(NotebookConstants.PARAM_MODIFIED_DATE, DateUtil.convertToStringForJSON(modifiedDate, request.getLocale())); - responseRow.put(NotebookConstants.PARAM_MODIFIED_DATE_TIMEAGO, + responseRow.put(NotebookConstants.PARAM_MODIFIED_DATE_TIMEAGO, DateUtil.convertToStringForTimeagoJSON(modifiedDate)); } else { responseRow.put(NotebookConstants.PARAM_MODIFIED_DATE, noEntry); } - + responseRow.put(NotebookConstants.ATTR_USER_ID, user.getUserId()); if (userAndReflection.length > 3 && userAndReflection[3] != null) { - responseRow.put(NotebookConstants.ATTR_PORTRAIT_ID, userAndReflection[3]); + responseRow.put(NotebookConstants.ATTR_PORTRAIT_ID, (String) userAndReflection[3]); } - rows.put(responseRow); + rows.add(responseRow); } - responsedata.put("rows", rows); + responsedata.set("rows", rows); response.setContentType("application/json;charset=utf-8"); response.getWriter().print(responsedata.toString()); return null; @@ -229,7 +220,7 @@ * @param request * @param response * @return - * @throws IOException + * @throws IOException */ public ActionForward setSubmissionDeadline(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException { Index: lams_tool_preview/src/java/org/lamsfoundation/lams/tool/peerreview/service/PeerreviewServiceImpl.java =================================================================== diff -u -r8e090b3ddf269cdffececa4bc55a9333da5b0858 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_preview/src/java/org/lamsfoundation/lams/tool/peerreview/service/PeerreviewServiceImpl.java (.../PeerreviewServiceImpl.java) (revision 8e090b3ddf269cdffececa4bc55a9333da5b0858) +++ lams_tool_preview/src/java/org/lamsfoundation/lams/tool/peerreview/service/PeerreviewServiceImpl.java (.../PeerreviewServiceImpl.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -42,9 +42,6 @@ import org.apache.commons.lang.StringEscapeUtils; import org.apache.log4j.Logger; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.events.IEventNotificationService; import org.lamsfoundation.lams.learning.service.ILearnerService; import org.lamsfoundation.lams.learningdesign.service.ExportToolContentException; @@ -89,6 +86,9 @@ import org.lamsfoundation.lams.util.MessageService; import org.springframework.util.StringUtils; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * @author Andrey Balan */ @@ -224,7 +224,7 @@ @Override public List getGroupSummaries(Long contentId) { - List groupList = new ArrayList(); + List groupList = new ArrayList<>(); // get all sessions in a peerreview and retrieve all peerreview items under this session // plus initial peerreview items by author creating (resItemList) @@ -246,7 +246,7 @@ public int getCountUsersBySession(final Long toolSessionId, final Long excludeUserId) { return peerreviewUserDao.getCountUsersBySession(toolSessionId, excludeUserId); } - + @Override public int getCountUsersBySession(final Long toolSessionId) { return peerreviewUserDao.getCountUsersBySession(toolSessionId); @@ -321,23 +321,25 @@ if (user == null) { return; } - + //If user is marked as hidden - it will automatically remove all rating left by him to prevent statistics mess up. if (isHidden) { ratingService.removeUserCommitsByContent(toolContentId, user.getUserId().intValue()); } - + user.setHidden(isHidden); peerreviewUserDao.saveObject(user); } @Override - public int rateItems(RatingCriteria ratingCriteria, Long toolSessionId, Integer userId, Map newRatings) { + public int rateItems(RatingCriteria ratingCriteria, Long toolSessionId, Integer userId, + Map newRatings) { return ratingService.rateItems(ratingCriteria, toolSessionId, userId, newRatings); } @Override - public void commentItem(RatingCriteria ratingCriteria, Long toolSessionId, Integer userId, Long itemId, String comment) { + public void commentItem(RatingCriteria ratingCriteria, Long toolSessionId, Integer userId, Long itemId, + String comment) { ratingService.commentItem(ratingCriteria, toolSessionId, userId, itemId, comment); } @@ -360,17 +362,17 @@ userManagementService); for (Object[] raw : rawData) { - raw[raw.length - 2] = (Object) StringEscapeUtils.escapeCsv((String)raw[raw.length - 2]); + raw[raw.length - 2] = (Object) StringEscapeUtils.escapeCsv((String)raw[raw.length - 2]); } // if !getByUser -> is get current user's ratings from other users -> // convertToStyledJSON.getAllUsers needs to be true otherwise current user (the only one in the set!) is dropped return ratingService.convertToStyledDTO(criteria, currentUserId, !getByUser || getAllUsers, rawData); } @Override - public JSONArray getUsersRatingsCommentsByCriteriaIdJSON(Long toolContentId, Long toolSessionId, + public ArrayNode getUsersRatingsCommentsByCriteriaIdJSON(Long toolContentId, Long toolSessionId, RatingCriteria criteria, Long currentUserId, Integer page, Integer size, int sorting, String searchString, - boolean getAllUsers, boolean getByUser, boolean needRatesPerUser) throws JSONException { + boolean getAllUsers, boolean getByUser, boolean needRatesPerUser) { List rawData = peerreviewUserDao.getRatingsComments(toolContentId, toolSessionId, criteria, currentUserId, page, size, sorting, searchString, getByUser, ratingService, userManagementService); @@ -380,8 +382,8 @@ } // if !getByUser -> is get current user's ratings from other users -> // convertToStyledJSON.getAllUsers needs to be true otherwise current user (the only one in the set!) is dropped - return ratingService.convertToStyledJSON(criteria, toolSessionId, currentUserId, !getByUser || getAllUsers, rawData, - needRatesPerUser); + return ratingService.convertToStyledJSON(criteria, toolSessionId, currentUserId, !getByUser || getAllUsers, + rawData, needRatesPerUser); } @Override @@ -394,10 +396,10 @@ List rawData = peerreviewUserDao.getDetailedRatingsComments(toolContentId, toolSessionId, criteriaId, itemId); for (Object[] raw : rawData) { - raw[2] = (raw[2] == null ? null : numberFormat.format((Float) raw[2])); // format rating + raw[2] = (raw[2] == null ? null : numberFormat.format(raw[2])); // format rating // format name StringBuilder description = new StringBuilder((String) raw[3]).append(" ").append((String) raw[4]); - raw[4] = (Object) StringEscapeUtils.escapeCsv(description.toString()); + raw[4] = StringEscapeUtils.escapeCsv(description.toString()); } return rawData; @@ -422,10 +424,10 @@ public boolean isGroupedActivity(long toolContentID) { return toolService.isGroupedActivity(toolContentID); } - + @Override public void auditLogStartEditingActivityInMonitor(long toolContentID) { - toolService.auditLogStartEditingActivityInMonitor(toolContentID); + toolService.auditLogStartEditingActivityInMonitor(toolContentID); } @Override @@ -446,7 +448,7 @@ for (Object[] raw : rawData) { StringBuilder description = new StringBuilder((String) raw[1]).append(" ").append((String) raw[2]); - raw[2] = (Object) StringEscapeUtils.escapeCsv(description.toString()); + raw[2] = StringEscapeUtils.escapeCsv(description.toString()); } return rawData; @@ -499,7 +501,8 @@ for (RatingCriteria criteria : ratingCriterias) { int sorting = (criteria.isStarStyleRating() || criteria.isHedgeStyleRating()) - ? PeerreviewConstants.SORT_BY_AVERAGE_RESULT_DESC : PeerreviewConstants.SORT_BY_AVERAGE_RESULT_ASC; + ? PeerreviewConstants.SORT_BY_AVERAGE_RESULT_DESC + : PeerreviewConstants.SORT_BY_AVERAGE_RESULT_ASC; StyledCriteriaRatingDTO dto = getUsersRatingsCommentsByCriteriaIdDTO(toolContentId, sessionId, criteria, user.getUserId(), false, sorting, null, true, false); generateRatingEntryForEmail(notificationMessage, criteria, dto); @@ -529,7 +532,8 @@ new Object[] { escapedTitle, StringUtils.replace(comments.toString(), "<BR>", "
") })); } else { String avgRating = dto.getRatingDtos().get(0).getAverageRating().length() > 0 - ? dto.getRatingDtos().get(0).getAverageRating() : "0"; + ? dto.getRatingDtos().get(0).getAverageRating() + : "0"; StringBuilder comments = null; if (criteria.isStarStyleRating()) { if (criteria.isCommentsEnabled()) { @@ -581,9 +585,10 @@ public int[] getNumberPossibleRatings(Long toolContentId, Long toolSessionId, Long userId) { int[] retValue = new int[2]; - ArrayList itemIds = new ArrayList(1); + ArrayList itemIds = new ArrayList<>(1); itemIds.add(userId); - Map numRatingsForUserMap = ratingService.countUsersRatedEachItem(toolContentId, toolSessionId, itemIds, -1); + Map numRatingsForUserMap = ratingService.countUsersRatedEachItem(toolContentId, toolSessionId, + itemIds, -1); Long numRatingsForUser = numRatingsForUserMap.get(userId); retValue[0] = numRatingsForUser != null ? numRatingsForUser.intValue() : 0; @@ -704,7 +709,7 @@ @Override public SortedMap getToolOutputDefinitions(Long toolContentId, int definitionType) throws ToolException { - return new TreeMap(); + return new TreeMap<>(); } @Override @@ -878,17 +883,18 @@ @Override public List getRatingCriteriaDtos(Long contentId, Long toolSessionId, Collection itemIds, boolean isCommentsByOtherUsersRequired, Long userId) { - return ratingService.getRatingCriteriaDtos(contentId, toolSessionId, itemIds, isCommentsByOtherUsersRequired, userId); + return ratingService.getRatingCriteriaDtos(contentId, toolSessionId, itemIds, isCommentsByOtherUsersRequired, + userId); } @Override public List getRatingCriteriaDtos(Long contentId, Long toolSessionId, Collection itemIds, boolean isCommentsByOtherUsersRequired, Long userId, boolean isCountUsersRatedEachItem) { - List itemRatingDTOs = getRatingCriteriaDtos(contentId, toolSessionId, itemIds, isCommentsByOtherUsersRequired, - userId); + List itemRatingDTOs = getRatingCriteriaDtos(contentId, toolSessionId, itemIds, + isCommentsByOtherUsersRequired, userId); if (isCountUsersRatedEachItem) { - Map itemIdToRatedUsersCountMap = ratingService.countUsersRatedEachItem(contentId, toolSessionId, + Map itemIdToRatedUsersCountMap = ratingService.countUsersRatedEachItem(contentId, toolSessionId, itemIds, userId.intValue()); for (ItemRatingDTO itemRatingDTO : itemRatingDTOs) { @@ -907,6 +913,7 @@ return ratingService.getCountItemsRatedByUser(toolContentId, userId); } + @Override public int getCountItemsRatedByUserByCriteria(final Long criteriaId, final Integer userId) { return ratingService.getCountItemsRatedByUserByCriteria(criteriaId, userId); } @@ -930,7 +937,7 @@ @Override public SortedMap getToolOutput(List names, Long toolSessionId, Long learnerId) { - return new TreeMap(); + return new TreeMap<>(); } @Override @@ -940,7 +947,7 @@ @Override public List getToolOutputs(String name, Long toolContentId) { - return new ArrayList(); + return new ArrayList<>(); } @Override @@ -1021,35 +1028,36 @@ /** * Used by the Rest calls to create content. Mandatory fields in toolContentJSON: title, instructions, peerreview, - * user fields firstName, lastName and loginName Peerreview must contain a JSONArray of JSONObject objects, which + * user fields firstName, lastName and loginName Peerreview must contain a ArrayNode of ObjectNode objects, which * have the following mandatory fields: title, description, type. If there are instructions for a peerreview, the - * instructions are a JSONArray of Strings. There should be at least one peerreview object in the peerreview array. + * instructions are a ArrayNode of Strings. There should be at least one peerreview object in the peerreview array. */ @Override - public void createRestToolContent(Integer userID, Long toolContentID, JSONObject toolContentJSON) - throws JSONException { + public void createRestToolContent(Integer userID, Long toolContentID, ObjectNode toolContentJSON) { Date updateDate = new Date(); Peerreview peerreview = new Peerreview(); peerreview.setContentId(toolContentID); - peerreview.setTitle(toolContentJSON.getString(RestTags.TITLE)); - peerreview.setInstructions(toolContentJSON.getString(RestTags.INSTRUCTIONS)); + peerreview.setTitle(JsonUtil.optString(toolContentJSON, RestTags.TITLE)); + peerreview.setInstructions(JsonUtil.optString(toolContentJSON, RestTags.INSTRUCTIONS)); peerreview.setCreated(updateDate); - peerreview.setLockWhenFinished(JsonUtil.opt(toolContentJSON, RestTags.LOCK_WHEN_FINISHED, Boolean.FALSE)); - peerreview.setReflectOnActivity(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); - peerreview.setReflectInstructions(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS, (String) null)); + peerreview + .setLockWhenFinished(JsonUtil.optBoolean(toolContentJSON, RestTags.LOCK_WHEN_FINISHED, Boolean.FALSE)); + peerreview.setReflectOnActivity( + JsonUtil.optBoolean(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); + peerreview.setReflectInstructions(JsonUtil.optString(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS)); peerreview.setContentInUse(false); peerreview.setDefineLater(false); PeerreviewUser peerreviewUser = getUserByIDAndContent(userID.longValue(), toolContentID); if (peerreviewUser == null) { peerreviewUser = new PeerreviewUser(); - peerreviewUser.setFirstName(toolContentJSON.getString("firstName")); - peerreviewUser.setLastName(toolContentJSON.getString("lastName")); - peerreviewUser.setLoginName(toolContentJSON.getString("loginName")); + peerreviewUser.setFirstName(JsonUtil.optString(toolContentJSON, "firstName")); + peerreviewUser.setLastName(JsonUtil.optString(toolContentJSON, "lastName")); + peerreviewUser.setLoginName(JsonUtil.optString(toolContentJSON, "loginName")); // peerreviewUser.setPeerreview(content); } Index: lams_tool_preview/src/java/org/lamsfoundation/lams/tool/peerreview/web/action/MonitoringAction.java =================================================================== diff -u -r8e090b3ddf269cdffececa4bc55a9333da5b0858 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_preview/src/java/org/lamsfoundation/lams/tool/peerreview/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision 8e090b3ddf269cdffececa4bc55a9333da5b0858) +++ lams_tool_preview/src/java/org/lamsfoundation/lams/tool/peerreview/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -21,7 +21,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.tool.peerreview.web.action; import java.io.IOException; @@ -44,9 +43,6 @@ import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.rating.model.RatingCriteria; import org.lamsfoundation.lams.tool.peerreview.PeerreviewConstants; import org.lamsfoundation.lams.tool.peerreview.dto.GroupSummary; @@ -56,19 +52,25 @@ import org.lamsfoundation.lams.util.ExcelCell; import org.lamsfoundation.lams.util.ExcelUtil; import org.lamsfoundation.lams.util.FileUtil; +import org.lamsfoundation.lams.util.JsonUtil; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.util.AttributeNames; import org.lamsfoundation.lams.web.util.SessionMap; import org.springframework.util.StringUtils; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + public class MonitoringAction extends Action { public static Logger log = Logger.getLogger(MonitoringAction.class); @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException, JSONException { + HttpServletResponse response) throws IOException, ServletException { String param = mapping.getParameter(); request.setAttribute("initialTabId", WebUtil.readLongParam(request, AttributeNames.PARAM_CURRENT_TAB, true)); @@ -119,7 +121,7 @@ private ActionForward summary(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { // initial Session Map - SessionMap sessionMap = new SessionMap(); + SessionMap sessionMap = new SessionMap<>(); request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); request.setAttribute(PeerreviewConstants.ATTR_SESSION_MAP_ID, sessionMap.getSessionID()); // save contentFolderID into session @@ -138,10 +140,10 @@ sessionMap.put(PeerreviewConstants.ATTR_PEERREVIEW, peerreview); sessionMap.put(PeerreviewConstants.ATTR_TOOL_CONTENT_ID, contentId); sessionMap.put(PeerreviewConstants.ATTR_IS_GROUPED_ACTIVITY, service.isGroupedActivity(contentId)); - + List criterias = service.getRatingCriterias(contentId); request.setAttribute(PeerreviewConstants.ATTR_CRITERIAS, criterias); - + return mapping.findForward(PeerreviewConstants.SUCCESS); } @@ -169,7 +171,7 @@ * Refreshes user list. */ public ActionForward getUsers(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse res) throws IOException, ServletException, JSONException { + HttpServletResponse res) throws IOException, ServletException { IPeerreviewService service = getPeerreviewService(); Long toolContentId = WebUtil.readLongParam(request, "toolContentId"); @@ -185,11 +187,12 @@ String sortBy = WebUtil.readStrParam(request, PeerreviewConstants.PARAM_SIDX, true); int sorting = PeerreviewConstants.SORT_BY_AVERAGE_RESULT_DESC; - if ( criteria.isRankingStyleRating() ) + if (criteria.isRankingStyleRating()) { sorting = PeerreviewConstants.SORT_BY_AVERAGE_RESULT_ASC; - else if ( criteria.isCommentRating() ) + } else if (criteria.isCommentRating()) { sorting = PeerreviewConstants.SORT_BY_USERNAME_ASC; - + } + if (sortBy != null && sortBy.equals(PeerreviewConstants.PARAM_SORT_NAME)) { if (sortOrder != null && sortOrder.equals(PeerreviewConstants.SORT_DESC)) { sorting = PeerreviewConstants.SORT_BY_USERNAME_DESC; @@ -208,14 +211,14 @@ // in case of monitoring we show all results. in case of learning - don't show results from the current user Long dummyUserId = -1L; - - JSONObject responcedata = new JSONObject(); + + ObjectNode responseData = JsonNodeFactory.instance.objectNode(); int numUsersInSession = service.getCountUsersBySession(toolSessionId, dummyUserId); - responcedata.put("page", page + 1); - responcedata.put("total", Math.ceil((float) numUsersInSession / size)); - responcedata.put("records", numUsersInSession); + responseData.put("page", page + 1); + responseData.put("total", Math.ceil((float) numUsersInSession / size)); + responseData.put("records", numUsersInSession); - JSONArray rows = new JSONArray(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); String emailResultsText = service.getLocalisedMessage("button.email.results", null); if (criteria.isCommentRating()) { @@ -225,82 +228,78 @@ for (int i = 0; i < rawRows.size(); i++) { Object[] rawRow = rawRows.get(i); - JSONObject cell = new JSONObject(); - cell.put("itemId", rawRow[0]); - cell.put("itemDescription", rawRow[2]); - cell.put("itemDescription2", rawRow[3]); + ObjectNode cell = JsonNodeFactory.instance.objectNode(); + cell.put("itemId", (Long) rawRow[0]); + cell.put("itemDescription", (String) rawRow[2]); + cell.put("itemDescription2", (String) rawRow[3]); Number numCommentsNumber = (Number) rawRow[1]; int numComments = numCommentsNumber != null ? numCommentsNumber.intValue() : 0; if (numComments > 0) { - cell.put("rating", service.getLocalisedMessage("label.monitoring.num.of.comments", new Object[] { numComments })); + cell.put("rating", service.getLocalisedMessage("label.monitoring.num.of.comments", + new Object[] { numComments })); cell.put("email", generateResultsButton(toolSessionId, rawRow[0], emailResultsText)); } else { cell.put("rating", ""); cell.put("email", ""); } - JSONObject row = new JSONObject(); + ObjectNode row = JsonNodeFactory.instance.objectNode(); row.put("id", "" + rawRow[0]); - row.put("cell", cell); - rows.put(row); + row.set("cell", cell); + rows.add(row); } } else { // all other styles can use the "normal" routine and munge the JSON to suit jqgrid - JSONArray rawRows = service.getUsersRatingsCommentsByCriteriaIdJSON(toolContentId, toolSessionId, criteria, + ArrayNode rawRows = service.getUsersRatingsCommentsByCriteriaIdJSON(toolContentId, toolSessionId, criteria, dummyUserId, page, size, sorting, searchString, true, true, false); - - for (int i = 0; i < rawRows.length(); i++) { - - JSONObject rawRow = rawRows.getJSONObject(i); - - String averageRating = (String) rawRow.get("averageRating"); + for (JsonNode rawNode : rawRows) { + ObjectNode rawRow = (ObjectNode) rawNode; + String averageRating = JsonUtil.optString(rawRow, "averageRating"); Object numberOfVotes = rawRow.get("numberOfVotes"); if (averageRating != null && averageRating.length() > 0) { if (criteria.isStarStyleRating()) { String starString = "
"; - starString += "
"; + starString += "
"; starString += "
"; - starString += "
"; - String msg = service.getLocalisedMessage("label.average.rating", new Object[] { averageRating, - numberOfVotes }); + starString += "
"; + String msg = service.getLocalisedMessage("label.average.rating", + new Object[] { averageRating, numberOfVotes }); starString += msg; starString += "
"; rawRow.put("rating", starString); - rawRow.put("email", generateResultsButton(toolSessionId, (Long) rawRow.get("itemId"), emailResultsText)); + rawRow.put("email", generateResultsButton(toolSessionId, JsonUtil.optLong(rawRow, "itemId"), + emailResultsText)); } else { rawRow.put("rating", averageRating); - rawRow.put("email", generateResultsButton(toolSessionId, (Long) rawRow.get("itemId"), emailResultsText)); + rawRow.put("email", generateResultsButton(toolSessionId, JsonUtil.optLong(rawRow, "itemId"), + emailResultsText)); } } - JSONObject row = new JSONObject(); + ObjectNode row = JsonNodeFactory.instance.objectNode(); row.put("id", "" + rawRow.get("itemId")); - row.put("cell", rawRow); - rows.put(row); + row.set("cell", rawRow); + rows.add(row); } } - responcedata.put("rows", rows); + responseData.set("rows", rows); res.setContentType("application/json;charset=utf-8"); - res.getWriter().print(new String(responcedata.toString())); + res.getWriter().print(new String(responseData.toString())); return null; } private String generateResultsButton(Object toolSessionId, Object userId, String emailResultsText) { - return new StringBuilder("") - .append(emailResultsText) - .append("") - .toString(); + return new StringBuilder("").append(emailResultsText) + .append("").toString(); } private ActionForward getSubgridData(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws JSONException, IOException { + HttpServletResponse response) throws IOException { IPeerreviewService service = getPeerreviewService(); Long itemId = WebUtil.readLongParam(request, "itemId"); @@ -309,76 +308,77 @@ Long criteriaId = WebUtil.readLongParam(request, "criteriaId"); // ratings left by others for this user - List ratings = service.getDetailedRatingsComments(toolContentId, toolSessionId, criteriaId, itemId ); + List ratings = service.getDetailedRatingsComments(toolContentId, toolSessionId, criteriaId, itemId); RatingCriteria criteria = service.getCriteriaByCriteriaId(criteriaId); String title = StringEscapeUtils.escapeHtml(criteria.getTitle()); - + // processed data from db is userId, comment, rating, first_name, escaped( firstname + last_name) // if no rating or comment, then the entries will be null and not an empty string - JSONArray rows = new JSONArray(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); int i = 0; - + for (Object[] ratingDetails : ratings) { - if ( ratingDetails[2] != null ) { - JSONArray userData = new JSONArray(); - userData.put(i); - userData.put(ratingDetails[4]); - userData.put(ratingDetails[2]); - userData.put(title); + if (ratingDetails[2] != null) { + ArrayNode userData = JsonNodeFactory.instance.arrayNode(); + userData.add(i); + userData.add(JsonUtil.readObject(ratingDetails[4])); + userData.add(JsonUtil.readObject(ratingDetails[2])); + userData.add(title); - JSONObject userRow = new JSONObject(); - userRow.put("id", i++); - userRow.put("cell", userData); - - rows.put(userRow); + ObjectNode userRow = JsonNodeFactory.instance.objectNode(); + userRow.put("id", i++); + userRow.set("cell", userData); + + rows.add(userRow); } } - if ( criteria.isCommentsEnabled() ) { + if (criteria.isCommentsEnabled()) { for (Object[] ratingDetails : ratings) { // Show comment if comment has been left by user. Exclude the special case where it is a hedging rating // and the rating is not null - otherwise we end up putting the justification comment against entries that were not rated. String comment = (String) ratingDetails[1]; - if ( comment != null && ( ! criteria.isHedgeStyleRating() || ( criteria.isHedgeStyleRating() && ratingDetails[2] != null ) ) ) { - JSONArray userData = new JSONArray(); - userData.put(i); - userData.put(ratingDetails[4]); + if (comment != null && (!criteria.isHedgeStyleRating() + || (criteria.isHedgeStyleRating() && ratingDetails[2] != null))) { + ArrayNode userData = JsonNodeFactory.instance.arrayNode(); + userData.add(i); + userData.add(JsonUtil.readObject(ratingDetails[4])); String commentText = StringEscapeUtils.escapeHtml(comment); commentText = StringUtils.replace(commentText, "<BR>", "
"); - userData.put(commentText); - userData.put("Comments"); + userData.add(commentText); + userData.add("Comments"); - JSONObject userRow = new JSONObject(); + ObjectNode userRow = JsonNodeFactory.instance.objectNode(); userRow.put("id", i++); - userRow.put("cell", userData); + userRow.set("cell", userData); - rows.put(userRow); + rows.add(userRow); } } } - - JSONObject responseJSON = new JSONObject(); + + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); responseJSON.put("total", 1); responseJSON.put("page", 1); - responseJSON.put("records", rows.length()); - responseJSON.put("rows", rows); + responseJSON.put("records", rows.size()); + responseJSON.set("rows", rows); response.setContentType("application/json;charset=utf-8"); response.getWriter().write(responseJSON.toString()); return null; } private ActionForward statistic(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) { + HttpServletResponse response) { IPeerreviewService service = getPeerreviewService(); String sessionMapID = request.getParameter(PeerreviewConstants.ATTR_SESSION_MAP_ID); Long toolContentId = WebUtil.readLongParam(request, PeerreviewConstants.ATTR_TOOL_CONTENT_ID); request.setAttribute("summaryList", service.getStatistics(toolContentId)); request.setAttribute(PeerreviewConstants.ATTR_SESSION_MAP_ID, sessionMapID); return mapping.findForward(PeerreviewConstants.SUCCESS); } - + private ActionForward reflections(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { @@ -389,12 +389,12 @@ Long toolSessionId = WebUtil.readLongParam(request, "toolSessionId"); request.setAttribute("toolSessionId", toolSessionId); - + return mapping.findForward(PeerreviewConstants.SUCCESS); } private ActionForward getReflections(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws JSONException, IOException { + HttpServletResponse response) throws IOException { String sessionMapID = request.getParameter(PeerreviewConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession() @@ -410,7 +410,7 @@ String sortBy = WebUtil.readStrParam(request, PeerreviewConstants.PARAM_SIDX, true); int sorting = PeerreviewConstants.SORT_BY_USERNAME_ASC; - + if (sortBy != null && sortBy.equals(PeerreviewConstants.PARAM_SORT_NAME)) { if (sortOrder != null && sortOrder.equals(PeerreviewConstants.SORT_DESC)) { sorting = PeerreviewConstants.SORT_BY_USERNAME_DESC; @@ -427,72 +427,69 @@ String searchString = WebUtil.readStrParam(request, "itemDescription", true); - // setting date format to ISO8601 for jquery.timeago - DateFormat dateFormatterTimeAgo = new SimpleDateFormat(DateUtil.ISO8601_FORMAT); - dateFormatterTimeAgo.setTimeZone(TimeZone.getTimeZone("GMT")); + // setting date format to ISO8601 for jquery.timeago + DateFormat dateFormatterTimeAgo = new SimpleDateFormat(DateUtil.ISO8601_FORMAT); + dateFormatterTimeAgo.setTimeZone(TimeZone.getTimeZone("GMT")); IPeerreviewService service = getPeerreviewService(); int sessionUserCount = service.getCountUsersBySession(toolSessionId, -1L); - - JSONObject responcedata = new JSONObject(); + + ObjectNode responcedata = JsonNodeFactory.instance.objectNode(); responcedata.put("page", page + 1); responcedata.put("total", Math.ceil((float) sessionUserCount / size)); responcedata.put("records", sessionUserCount); - List nbEntryList = service.getUserNotebookEntriesForTablesorter(toolSessionId, - page, size, sorting, searchString); - + List nbEntryList = service.getUserNotebookEntriesForTablesorter(toolSessionId, page, size, sorting, + searchString); + // processed data from db is user.user_id, user.first_name, escaped( first_name + last_name), notebook entry, notebook date // if no rating or comment, then the entries will be null and not an empty string - JSONArray rows = new JSONArray(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); int i = 0; - + for (Object[] nbEntry : nbEntryList) { - JSONArray userData = new JSONArray(); - userData.put(nbEntry[0]); + ArrayNode userData = JsonNodeFactory.instance.arrayNode(); + userData.add(JsonUtil.readObject(nbEntry[0])); - Date entryTime = (Date) nbEntry[4]; - if ( entryTime == null ) { - userData.put((String)nbEntry[2]); - } else { - StringBuilder nameField = new StringBuilder((String)nbEntry[2]) - .append("
") - .append(""); - userData.put(nameField.toString()); - } - - userData.put(StringEscapeUtils.escapeHtml((String)nbEntry[3])); + Date entryTime = (Date) nbEntry[4]; + if (entryTime == null) { + userData.add((String) nbEntry[2]); + } else { + StringBuilder nameField = new StringBuilder((String) nbEntry[2]).append("
") + .append(""); + userData.add(nameField.toString()); + } - JSONObject userRow = new JSONObject(); - userRow.put("id", i++); - userRow.put("cell", userData); + userData.add(StringEscapeUtils.escapeHtml((String) nbEntry[3])); - rows.put(userRow); + ObjectNode userRow = JsonNodeFactory.instance.objectNode(); + userRow.put("id", i++); + userRow.set("cell", userData); + + rows.add(userRow); } - responcedata.put("rows", rows); + responcedata.set("rows", rows); response.setContentType("application/json;charset=utf-8"); response.getWriter().write(responcedata.toString()); return null; } private ActionForward sendResultsToUser(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws JSONException, IOException { + HttpServletResponse response) throws IOException { return sendResults(mapping, request, response, true); } private ActionForward sendResultsToSessionUsers(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws JSONException, IOException { + HttpServletResponse response) throws IOException { return sendResults(mapping, request, response, false); } - private ActionForward sendResults(ActionMapping mapping, HttpServletRequest request, - HttpServletResponse response, boolean oneUserOnly) throws JSONException, IOException { + private ActionForward sendResults(ActionMapping mapping, HttpServletRequest request, HttpServletResponse response, + boolean oneUserOnly) throws IOException { String sessionMapID = request.getParameter(PeerreviewConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession() @@ -504,8 +501,8 @@ IPeerreviewService service = getPeerreviewService(); int numEmailsSent = 0; - - if ( oneUserOnly) { + + if (oneUserOnly) { Long userId = WebUtil.readLongParam(request, PeerreviewConstants.PARAM_USERID); numEmailsSent = service.emailReportToUser(contentId, toolSessionId, userId); } else { @@ -516,26 +513,27 @@ response.getWriter().write(service.getLocalisedMessage("msg.results.sent", new Object[] { numEmailsSent })); return null; } - + /** * Exports Team Report into Excel spreadsheet. - * @throws ServletException - * @throws IOException + * + * @throws ServletException + * @throws IOException */ private ActionForward exportTeamReport(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException { - + IPeerreviewService service = getPeerreviewService(); Long toolContentId = WebUtil.readLongParam(request, PeerreviewConstants.ATTR_TOOL_CONTENT_ID); Peerreview peerreview = service.getPeerreviewByContentId(toolContentId); if (peerreview == null) { log.warn("Did not find Peer Review with toolContentId: " + toolContentId + " export content"); - return null; + return null; } - + String fileName = peerreview.getTitle().replaceAll(" ", "_") + ".xlsx"; - + try { fileName = FileUtil.encodeFilenameForDownload(request, fileName); @@ -558,35 +556,35 @@ ExcelUtil.createExcel(out, dataToExport, "Exported on:", true); } catch (IOException e) { - log.error("exportTeamReportExcelSpreadsheet i/o error occured: "+e.getMessage(), e); + log.error("exportTeamReportExcelSpreadsheet i/o error occured: " + e.getMessage(), e); throw new ServletException(e); } return null; } - + private ActionForward manageUsers(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException { - + IPeerreviewService service = getPeerreviewService(); String sessionMapID = request.getParameter(PeerreviewConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession() .getAttribute(sessionMapID); request.setAttribute(PeerreviewConstants.ATTR_SESSION_MAP_ID, sessionMap.getSessionID()); - + return mapping.findForward(PeerreviewConstants.SUCCESS); } - + /** * Gets a paged set of data for stars or comments. These are directly saved to the database, not through - * LearnerAction like Ranking and Hedging. + * LearnerAction like Ranking and Hedging. */ private ActionForward getManageUsers(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse res) throws IOException, ServletException, JSONException { - + HttpServletResponse res) throws IOException, ServletException { + IPeerreviewService service = getPeerreviewService(); Long toolSessionId = WebUtil.readLongParam(request, "toolSessionId"); - + // Getting the params passed in from the jqGrid int page = WebUtil.readIntParam(request, PeerreviewConstants.PARAM_PAGE) - 1; int size = WebUtil.readIntParam(request, PeerreviewConstants.PARAM_ROWS); @@ -602,48 +600,48 @@ } } String searchString = WebUtil.readStrParam(request, "userName", true); - - JSONObject responcedata = new JSONObject(); + ObjectNode responcedata = JsonNodeFactory.instance.objectNode(); + int numUsersInSession = service.getCountUsersBySession(toolSessionId); responcedata.put("page", page + 1); responcedata.put("total", Math.ceil((float) numUsersInSession / size)); responcedata.put("records", numUsersInSession); - + // gets the user List rawRows = service.getPagedUsers(toolSessionId, page, size, sorting, searchString); - JSONArray rows = new JSONArray(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); for (int i = 0; i < rawRows.size(); i++) { Object[] rawRow = rawRows.get(i); - JSONObject cell = new JSONObject(); - cell.put("hidden", !(Boolean)rawRow[1]); - cell.put("userUid", rawRow[0]); + ObjectNode cell = JsonNodeFactory.instance.objectNode(); + cell.put("hidden", !(Boolean) rawRow[1]); + cell.put("userUid", (Integer) rawRow[0]); cell.put("userName", (String) rawRow[2]); - JSONObject row = new JSONObject(); + ObjectNode row = JsonNodeFactory.instance.objectNode(); row.put("id", "" + rawRow[0]); - row.put("cell", cell); - rows.put(row); + row.set("cell", cell); + rows.add(row); } - responcedata.put("rows", rows); + responcedata.set("rows", rows); res.setContentType("application/json;charset=utf-8"); res.getWriter().print(new String(responcedata.toString())); return null; } - + private ActionForward setUserHidden(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { IPeerreviewService service = getPeerreviewService(); Long toolContentId = WebUtil.readLongParam(request, PeerreviewConstants.ATTR_TOOL_CONTENT_ID); Long userUid = WebUtil.readLongParam(request, "userUid"); boolean isHidden = !WebUtil.readBooleanParam(request, "hidden"); - + service.setUserHidden(toolContentId, userUid, isHidden); return null; } - + // ************************************************************************************* // Private method // ************************************************************************************* Index: lams_tool_sbmt/src/java/org/lamsfoundation/lams/tool/sbmt/service/SubmitFilesService.java =================================================================== diff -u -r60d9a173d5590295376322fc3e857ae2dca37717 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_sbmt/src/java/org/lamsfoundation/lams/tool/sbmt/service/SubmitFilesService.java (.../SubmitFilesService.java) (revision 60d9a173d5590295376322fc3e857ae2dca37717) +++ lams_tool_sbmt/src/java/org/lamsfoundation/lams/tool/sbmt/service/SubmitFilesService.java (.../SubmitFilesService.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -21,8 +21,6 @@ * **************************************************************** */ - - package org.lamsfoundation.lams.tool.sbmt.service; import java.io.FileNotFoundException; @@ -44,8 +42,6 @@ import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.apache.struts.upload.FormFile; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.contentrepository.ICredentials; import org.lamsfoundation.lams.contentrepository.ITicket; import org.lamsfoundation.lams.contentrepository.IVersionedNode; @@ -105,6 +101,8 @@ import org.lamsfoundation.lams.util.audit.IAuditService; import org.springframework.dao.DataAccessException; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * @author Manpreet Minhas */ @@ -534,10 +532,10 @@ public ToolOutput getToolOutput(String name, Long toolSessionId, Long learnerId) { return getSubmitFilesOutputFactory().getToolOutput(name, this, toolSessionId, learnerId); } - + @Override public List getToolOutputs(String name, Long toolContentId) { - return new ArrayList(); + return new ArrayList<>(); } @Override @@ -620,7 +618,8 @@ * java.lang.Long) */ @Override - public List getFilesUploadedByUser(Integer userID, Long sessionID, Locale currentLocale, boolean includeRemovedFiles) { + public List getFilesUploadedByUser(Integer userID, Long sessionID, Locale currentLocale, + boolean includeRemovedFiles) { List list = submissionDetailsDAO.getBySessionAndLearner(sessionID, userID); SortedSet details = new TreeSet(this.new FileDtoComparator()); if (list == null) { @@ -629,7 +628,7 @@ NumberFormat numberFormat = currentLocale != null ? NumberFormat.getInstance(currentLocale) : null; for (SubmissionDetails submissionDetails : list) { - if ( includeRemovedFiles || ! submissionDetails.isRemoved() ) { + if (includeRemovedFiles || !submissionDetails.isRemoved()) { FileDetailsDTO detailDto = new FileDetailsDTO(submissionDetails, numberFormat); details.add(detailDto); } @@ -743,16 +742,15 @@ } } - @Override public void removeLearnerFile(Long detailID, UserDTO monitor) { SubmissionDetails detail = submissionDetailsDAO.getSubmissionDetailsByID(detailID); if (detail != null) { - if(monitor != null){ + if (monitor != null) { - auditRemoveRestore(monitor, detail, "audit.file.delete"); + auditRemoveRestore(monitor, detail, "audit.file.delete"); } detail.setRemoved(true); @@ -762,13 +760,13 @@ @Override public void restoreLearnerFile(Long detailID, UserDTO monitor) { - + SubmissionDetails detail = submissionDetailsDAO.getSubmissionDetailsByID(detailID); if (detail != null) { - - auditRemoveRestore(monitor, detail,"audit.file.restore"); - + + auditRemoveRestore(monitor, detail, "audit.file.restore"); + detail.setRemoved(false); submissionDetailsDAO.update(detail); } @@ -777,17 +775,16 @@ private void auditRemoveRestore(UserDTO monitor, SubmissionDetails detail, String i18nKey) { SubmitUser learner = detail.getLearner(); - StringBuilder instructorTxt = new StringBuilder(monitor.getLogin()).append(" (").append(monitor.getUserID()).append(") ") - .append(monitor.getFirstName()).append(" ").append(monitor.getLastName()); - StringBuilder learnerTxt = new StringBuilder(learner.getLogin()).append(" (").append(learner.getUserID()).append(") ") - .append(learner.getFirstName()).append(" ").append(learner.getLastName()); + StringBuilder instructorTxt = new StringBuilder(monitor.getLogin()).append(" (").append(monitor.getUserID()) + .append(") ").append(monitor.getFirstName()).append(" ").append(monitor.getLastName()); + StringBuilder learnerTxt = new StringBuilder(learner.getLogin()).append(" (").append(learner.getUserID()) + .append(") ").append(learner.getFirstName()).append(" ").append(learner.getLastName()); - String auditMsg = getLocalisedMessage(i18nKey, new Object[] { instructorTxt.toString(), detail.getFilePath(), - learnerTxt.toString() }); + String auditMsg = getLocalisedMessage(i18nKey, + new Object[] { instructorTxt.toString(), detail.getFilePath(), learnerTxt.toString() }); auditService.log(SbmtConstants.AUDIT_LOG_MODULE_NAME, auditMsg); } - @Override public IVersionedNode downloadFile(Long uuid, Long versionID) throws SubmitFilesException { ITicket ticket = getRepositoryLoginTicket(); @@ -824,14 +821,14 @@ Map notificationMessages = null; Object[] notificationMessageParameters = null; if (notifyLearnersOnMarkRelease) { - notificationMessages = new TreeMap(); + notificationMessages = new TreeMap<>(); notificationMessageParameters = new Object[3]; } while (iter.hasNext()) { details = (SubmissionDetails) iter.next(); report = details.getReport(); report.setDateMarksReleased(new Date()); - if (notifyLearnersOnMarkRelease && ! details.isRemoved()) { + if (notifyLearnersOnMarkRelease && !details.isRemoved()) { SubmitUser user = details.getLearner(); StringBuilder notificationMessage = notificationMessages.get(user.getUserID()); if (notificationMessage == null) { @@ -891,7 +888,7 @@ if (detailsList != null) { Float totalMark = null; for (SubmissionDetails details : detailsList) { - if ( ! details.isRemoved() ) { + if (!details.isRemoved()) { SubmitFilesReport report = details.getReport(); if (report != null) { if (totalMark == null) { @@ -973,10 +970,10 @@ public boolean isGroupedActivity(long toolContentID) { return toolService.isGroupedActivity(toolContentID); } - + @Override public void auditLogStartEditingActivityInMonitor(long toolContentID) { - toolService.auditLogStartEditingActivityInMonitor(toolContentID); + toolService.auditLogStartEditingActivityInMonitor(toolContentID); } @Override @@ -1198,11 +1195,11 @@ } public IAuditService getAuditService() { - return auditService; + return auditService; } public void setAuditService(IAuditService auditService) { - this.auditService = auditService; + this.auditService = auditService; } public void setGradebookService(IGradebookService gradebookService) { @@ -1222,7 +1219,7 @@ public void setSubmitFilesOutputFactory(SubmitFilesOutputFactory submitFilesOutputFactory) { this.submitFilesOutputFactory = submitFilesOutputFactory; } - + @Override public ToolCompletionStatus getCompletionStatus(Long learnerId, Long toolSessionId) { SubmitUser learner = getSessionUser(toolSessionId, learnerId.intValue()); @@ -1233,20 +1230,23 @@ Date startDate = null; Date endDate = null; List list = submissionDetailsDAO.getBySessionAndLearner(toolSessionId, learnerId.intValue()); - for ( SubmissionDetails detail : list ) { + for (SubmissionDetails detail : list) { Date newDate = detail.getDateOfSubmission(); - if ( newDate != null ) { - if ( startDate == null || newDate.before(startDate) ) + if (newDate != null) { + if (startDate == null || newDate.before(startDate)) { startDate = newDate; - if ( endDate == null || newDate.after(endDate) ) + } + if (endDate == null || newDate.after(endDate)) { endDate = newDate; + } } } - - if (learner.isFinished()) + + if (learner.isFinished()) { return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_COMPLETED, startDate, endDate); - else + } else { return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_ATTEMPTED, startDate, null); + } } // ****************** REST methods ************************* @@ -1255,35 +1255,35 @@ * Used by the Rest calls to create content. Mandatory fields in toolContentJSON: title, instructions */ @Override - public void createRestToolContent(Integer userID, Long toolContentID, JSONObject toolContentJSON) - throws JSONException { + public void createRestToolContent(Integer userID, Long toolContentID, ObjectNode toolContentJSON) { SubmitFilesContent content = new SubmitFilesContent(); Date updateDate = new Date(); content.setCreated(updateDate); content.setUpdated(updateDate); content.setContentID(toolContentID); - content.setTitle(toolContentJSON.getString(RestTags.TITLE)); - content.setInstruction(toolContentJSON.getString(RestTags.INSTRUCTIONS)); + content.setTitle(JsonUtil.optString(toolContentJSON, RestTags.TITLE)); + content.setInstruction(JsonUtil.optString(toolContentJSON, RestTags.INSTRUCTIONS)); content.setContentInUse(false); content.setDefineLater(false); content.setNotifyTeachersOnFileSubmit( - JsonUtil.opt(toolContentJSON, "notifyTeachersOnFileSubmit", Boolean.FALSE)); + JsonUtil.optBoolean(toolContentJSON, "notifyTeachersOnFileSubmit", Boolean.FALSE)); content.setNotifyLearnersOnMarkRelease( - JsonUtil.opt(toolContentJSON, "notifyLearnersOnMarkRelease", Boolean.FALSE)); - content.setReflectInstructions((String) JsonUtil.opt(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS, null)); - content.setReflectOnActivity(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); - content.setLockOnFinished(JsonUtil.opt(toolContentJSON, RestTags.LOCK_WHEN_FINISHED, Boolean.FALSE)); - content.setLimitUpload(JsonUtil.opt(toolContentJSON, "limitUpload", Boolean.FALSE)); - content.setLimitUploadNumber(JsonUtil.opt(toolContentJSON, "limitUploadNumber", 0)); + JsonUtil.optBoolean(toolContentJSON, "notifyLearnersOnMarkRelease", Boolean.FALSE)); + content.setReflectInstructions(JsonUtil.optString(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS)); + content.setReflectOnActivity(JsonUtil.optBoolean(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); + content.setLockOnFinished(JsonUtil.optBoolean(toolContentJSON, RestTags.LOCK_WHEN_FINISHED, Boolean.FALSE)); + content.setLimitUpload(JsonUtil.optBoolean(toolContentJSON, "limitUpload", Boolean.FALSE)); + content.setLimitUploadNumber(JsonUtil.optInt(toolContentJSON, "limitUploadNumber", 0)); // submissionDeadline is set in monitoring SubmitUser user = getContentUser(toolContentID, userID); if (user == null) { - user = createContentUser(userID, toolContentJSON.getString("firstName"), - toolContentJSON.getString("lastName"), toolContentJSON.getString("loginName"), toolContentID); + user = createContentUser(userID, JsonUtil.optString(toolContentJSON, "firstName"), + JsonUtil.optString(toolContentJSON, "lastName"), JsonUtil.optString(toolContentJSON, "loginName"), + toolContentID); } content.setCreatedBy(user); saveOrUpdateContent(content); Index: lams_tool_sbmt/src/java/org/lamsfoundation/lams/tool/sbmt/web/action/MonitoringAction.java =================================================================== diff -u -r60d9a173d5590295376322fc3e857ae2dca37717 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_sbmt/src/java/org/lamsfoundation/lams/tool/sbmt/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision 60d9a173d5590295376322fc3e857ae2dca37717) +++ lams_tool_sbmt/src/java/org/lamsfoundation/lams/tool/sbmt/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -49,9 +49,6 @@ import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.DynaActionForm; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.tool.sbmt.SbmtConstants; import org.lamsfoundation.lams.tool.sbmt.SubmissionDetails; import org.lamsfoundation.lams.tool.sbmt.SubmitFilesContent; @@ -73,6 +70,10 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * @author Manpreet Minhas */ @@ -154,7 +155,7 @@ /** Ajax call to populate the tablesorter */ public ActionForward getUsers(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws JSONException, IOException { + HttpServletResponse response) throws IOException { Long sessionID = new Long(WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID)); Long contentId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); @@ -183,40 +184,41 @@ List users = service.getUsersForTablesorter(sessionID, page, size, sorting, searchString, spreadsheet.isReflectOnActivity()); - JSONArray rows = new JSONArray(); - JSONObject responsedata = new JSONObject(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); + ObjectNode responsedata = JsonNodeFactory.instance.objectNode(); responsedata.put("total_rows", service.getCountUsersBySession(sessionID, searchString)); for (Object[] userAndReflection : users) { - JSONObject responseRow = new JSONObject(); + ObjectNode responseRow = JsonNodeFactory.instance.objectNode(); SubmitUser user = (SubmitUser) userAndReflection[0]; responseRow.put(SbmtConstants.ATTR_USER_UID, user.getUid()); responseRow.put(SbmtConstants.USER_ID, user.getUserID()); responseRow.put(SbmtConstants.ATTR_USER_FULLNAME, StringEscapeUtils.escapeHtml(user.getFullName())); - if (userAndReflection.length > 2) { + + if (userAndReflection.length > 2) { responseRow.put(SbmtConstants.ATTR_PORTRAIT_ID, (Integer)userAndReflection[1]); } - + if (userAndReflection.length > 3) { - responseRow.put(SbmtConstants.ATTR_USER_NUM_FILE, - (Integer)userAndReflection[2] - (Integer)userAndReflection[3]); + responseRow.put(SbmtConstants.ATTR_USER_NUM_FILE, + (Integer) userAndReflection[2] - (Integer) userAndReflection[3]); } if (userAndReflection.length > 4) { responseRow.put(SbmtConstants.ATTR_USER_FILE_MARKED, (Integer) userAndReflection[4] > 0); } if (userAndReflection.length > 5) { - responseRow.put(SbmtConstants.ATTR_USER_REFLECTION, userAndReflection[5]); + responseRow.put(SbmtConstants.ATTR_USER_REFLECTION, (String) userAndReflection[5]); } - rows.put(responseRow); + rows.add(responseRow); } - responsedata.put("rows", rows); + responsedata.set("rows", rows); response.setContentType("application/json;charset=utf-8"); response.getWriter().print(new String(responsedata.toString())); return null; @@ -513,7 +515,8 @@ .append("file as file does not exist. Requested by user ").append(currentUser.getUserID()) .append(" for file ").append(detailID).append(" for user ").append(learnerUserID); log.error(builder.toString()); - throw new ServletException("Invalid call to "+(remove ? "remove" : "restore")+" file. See the server log for more details."); + throw new ServletException("Invalid call to " + (remove ? "remove" : "restore") + + " file. See the server log for more details."); } else { if (!fileToProcess.getSubmitFileSession().getSessionID().equals(sessionID) @@ -523,17 +526,19 @@ .append(currentUser.getUserID()).append(" for file ").append(detailID).append(" for user ") .append(learnerUserID).append(" in session ").append(sessionID); log.error(builder.toString()); - throw new ServletException("Invalid call to "+(remove ? "remove" : "restore")+" file. See the server log for more details."); + throw new ServletException("Invalid call to " + (remove ? "remove" : "restore") + + " file. See the server log for more details."); } else { if (remove) { submitFilesService.removeLearnerFile(detailID, currentUser); - notifyRemoveRestore(fileToProcess, "event.file.restore.subject", "event.file.restore.body", "restore file"); + notifyRemoveRestore(fileToProcess, "event.file.restore.subject", "event.file.restore.body", + "restore file"); - } else { submitFilesService.restoreLearnerFile(detailID, currentUser); - notifyRemoveRestore(fileToProcess, "event.file.delete.subject", "event.file.delete.body", "delete file"); + notifyRemoveRestore(fileToProcess, "event.file.delete.subject", "event.file.delete.body", + "delete file"); } } @@ -546,36 +551,41 @@ return mapping.findForward("listMark"); } - /** Notify the user by email of the file change. Need to do it here rather than in the service so that any issues are caught and logged - * without stuffing up the transaction. + /** + * Notify the user by email of the file change. Need to do it here rather than in the service so that any issues are + * caught and logged + * without stuffing up the transaction. */ - public void notifyRemoveRestore(SubmissionDetails detail, String i18nSubjectKey, String i18nBodyKey, String errorSubject) { + public void notifyRemoveRestore(SubmissionDetails detail, String i18nSubjectKey, String i18nBodyKey, + String errorSubject) { Long contentID = detail.getSubmitFileSession().getContent().getContentID(); Integer learnerID = detail.getLearner().getUserID(); - // Can't just create a new subscription then call triggerForSingleUser() as - // it needs a subscription id, which doesn't exist for a subscription created in the same + // Can't just create a new subscription then call triggerForSingleUser() as + // it needs a subscription id, which doesn't exist for a subscription created in the same // transaction. So reuse the existing RELEASE MARKS event and subscription (created when // a file is uploaded) and override both the subject and the message. try { - boolean eventExists = submitFilesService.getEventNotificationService().eventExists(SbmtConstants.TOOL_SIGNATURE, - SbmtConstants.EVENT_NAME_NOTIFY_LEARNERS_ON_MARK_RELEASE, contentID); + boolean eventExists = submitFilesService.getEventNotificationService().eventExists( + SbmtConstants.TOOL_SIGNATURE, SbmtConstants.EVENT_NAME_NOTIFY_LEARNERS_ON_MARK_RELEASE, contentID); if (eventExists) { submitFilesService.getEventNotificationService().triggerForSingleUser(SbmtConstants.TOOL_SIGNATURE, SbmtConstants.EVENT_NAME_NOTIFY_LEARNERS_ON_MARK_RELEASE, contentID, learnerID, submitFilesService.getLocalisedMessage(i18nSubjectKey, null), submitFilesService.getLocalisedMessage(i18nBodyKey, new Object[] { detail.getFilePath() })); } else { - log.error("Unable to notify user of "+errorSubject+". contentID="+contentID+" learner="+learnerID+" file "+detail.getFilePath()+" as "+SbmtConstants.EVENT_NAME_NOTIFY_LEARNERS_ON_MARK_RELEASE+" event is missing"); + log.error("Unable to notify user of " + errorSubject + ". contentID=" + contentID + " learner=" + + learnerID + " file " + detail.getFilePath() + " as " + + SbmtConstants.EVENT_NAME_NOTIFY_LEARNERS_ON_MARK_RELEASE + " event is missing"); } - } catch ( Exception e) { - log.error("Unable to notify user of "+errorSubject+". contentID="+contentID+" learner="+learnerID+" file "+detail.getFilePath()+" due to exception "+e.getMessage(),e); - } + } catch (Exception e) { + log.error("Unable to notify user of " + errorSubject + ". contentID=" + contentID + " learner=" + learnerID + + " file " + detail.getFilePath() + " due to exception " + e.getMessage(), e); + } } - // ********************************************************** // Private methods // ********************************************************** @@ -631,5 +641,5 @@ // request.setAttribute(AttributeNames.PARAM_TOOL_SESSION_ID,sessionID); request.setAttribute("sessions", sessions); } - + } \ No newline at end of file Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java =================================================================== diff -u -r83ca314c18ea866bb79570b6e7da25eb8729b3b4 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java (.../ScratchieServiceImpl.java) (revision 83ca314c18ea866bb79570b6e7da25eb8729b3b4) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java (.../ScratchieServiceImpl.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -46,9 +46,6 @@ import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.events.IEventNotificationService; import org.lamsfoundation.lams.gradebook.service.IGradebookService; import org.lamsfoundation.lams.learning.service.ILearnerService; @@ -105,6 +102,9 @@ import org.quartz.Scheduler; import org.quartz.SchedulerException; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * @author Andrey Balan */ @@ -518,7 +518,7 @@ } @Override - public void setScratchingFinished(Long toolSessionId) throws JSONException, IOException { + public void setScratchingFinished(Long toolSessionId) throws IOException { ScratchieSession session = this.getScratchieSessionBySessionId(toolSessionId); session.setScratchingFinished(true); scratchieSessionDao.saveObject(session); @@ -2147,14 +2147,13 @@ /** * Rest call to create a new Scratchie content. Required fields in toolContentJSON: "title", "instructions", - * "questions". The questions entry should be JSONArray containing JSON objects, which in turn must contain - * "questionText", "displayOrder" (Integer) and a JSONArray "answers". The answers entry should be JSONArray + * "questions". The questions entry should be ArrayNode containing JSON objects, which in turn must contain + * "questionText", "displayOrder" (Integer) and a ArrayNode "answers". The answers entry should be ArrayNode * containing JSON objects, which in turn must contain "answerText", "displayOrder" (Integer), "correct" (Boolean). */ @SuppressWarnings("unchecked") @Override - public void createRestToolContent(Integer userID, Long toolContentID, JSONObject toolContentJSON) - throws JSONException { + public void createRestToolContent(Integer userID, Long toolContentID, ObjectNode toolContentJSON) { Scratchie scratchie = new Scratchie(); Date updateDate = new Date(); @@ -2164,43 +2163,44 @@ scratchie.setDefineLater(false); scratchie.setContentId(toolContentID); - scratchie.setTitle(toolContentJSON.getString(RestTags.TITLE)); - scratchie.setInstructions(toolContentJSON.getString(RestTags.INSTRUCTIONS)); + scratchie.setTitle(JsonUtil.optString(toolContentJSON, RestTags.TITLE)); + scratchie.setInstructions(JsonUtil.optString(toolContentJSON, RestTags.INSTRUCTIONS)); - scratchie.setBurningQuestionsEnabled(JsonUtil.opt(toolContentJSON, "burningQuestionsEnabled", false)); - scratchie.setTimeLimit(JsonUtil.opt(toolContentJSON, "timeLimit", 0)); - scratchie.setExtraPoint(JsonUtil.opt(toolContentJSON, "extraPoint", false)); - scratchie.setReflectOnActivity(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); - scratchie.setReflectInstructions(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS, (String) null)); + scratchie.setBurningQuestionsEnabled(JsonUtil.optBoolean(toolContentJSON, "burningQuestionsEnabled", false)); + scratchie.setTimeLimit(JsonUtil.optInt(toolContentJSON, "timeLimit", 0)); + scratchie.setExtraPoint(JsonUtil.optBoolean(toolContentJSON, "extraPoint", false)); + scratchie.setReflectOnActivity( + JsonUtil.optBoolean(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); + scratchie.setReflectInstructions(JsonUtil.optString(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS)); // Scratchie Items Set newItems = new LinkedHashSet<>(); - JSONArray questions = toolContentJSON.getJSONArray(RestTags.QUESTIONS); - for (int i = 0; i < questions.length(); i++) { - JSONObject questionData = (JSONObject) questions.get(i); + ArrayNode questions = JsonUtil.optArray(toolContentJSON, RestTags.QUESTIONS); + for (int i = 0; i < questions.size(); i++) { + ObjectNode questionData = (ObjectNode) questions.get(i); ScratchieItem item = new ScratchieItem(); item.setCreateDate(updateDate); item.setCreateByAuthor(true); - item.setOrderId(questionData.getInt(RestTags.DISPLAY_ORDER)); - item.setTitle(questionData.getString(RestTags.QUESTION_TITLE)); - item.setDescription(questionData.getString(RestTags.QUESTION_TEXT)); + item.setOrderId(JsonUtil.optInt(questionData, RestTags.DISPLAY_ORDER)); + item.setTitle(JsonUtil.optString(questionData, RestTags.QUESTION_TITLE)); + item.setDescription(JsonUtil.optString(questionData, RestTags.QUESTION_TEXT)); newItems.add(item); // set options Set newAnswers = new LinkedHashSet<>(); - JSONArray answersData = questionData.getJSONArray(RestTags.ANSWERS); - for (int j = 0; j < answersData.length(); j++) { - JSONObject answerData = (JSONObject) answersData.get(j); + ArrayNode answersData = JsonUtil.optArray(questionData, RestTags.ANSWERS); + for (int j = 0; j < answersData.size(); j++) { + ObjectNode answerData = (ObjectNode) answersData.get(j); ScratchieAnswer answer = new ScratchieAnswer(); // Removes redundant new line characters from options left by CKEditor (otherwise it will break // Javascript in monitor). Copied from AuthoringAction. - String answerDescription = answerData.getString(RestTags.ANSWER_TEXT); + String answerDescription = JsonUtil.optString(answerData, RestTags.ANSWER_TEXT); answer.setDescription(answerDescription != null ? answerDescription.replaceAll("[\n\r\f]", "") : ""); - answer.setCorrect(answerData.getBoolean(RestTags.CORRECT)); - answer.setOrderId(answerData.getInt(RestTags.DISPLAY_ORDER)); + answer.setCorrect(JsonUtil.optBoolean(answerData, RestTags.CORRECT)); + answer.setOrderId(JsonUtil.optInt(answerData, RestTags.DISPLAY_ORDER)); answer.setScratchieItem(item); newAnswers.add(answer); } @@ -2211,7 +2211,5 @@ scratchie.setScratchieItems(newItems); saveOrUpdateScratchie(scratchie); - } - -} +} \ No newline at end of file Index: lams_tool_spreadsheet/src/java/org/lamsfoundation/lams/tool/spreadsheet/web/action/MonitoringAction.java =================================================================== diff -u -r83ca314c18ea866bb79570b6e7da25eb8729b3b4 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_spreadsheet/src/java/org/lamsfoundation/lams/tool/spreadsheet/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision 83ca314c18ea866bb79570b6e7da25eb8729b3b4) +++ lams_tool_spreadsheet/src/java/org/lamsfoundation/lams/tool/spreadsheet/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -21,7 +21,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.tool.spreadsheet.web.action; import java.io.ByteArrayOutputStream; @@ -47,9 +46,6 @@ import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionMessages; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.tool.spreadsheet.SpreadsheetConstants; import org.lamsfoundation.lams.tool.spreadsheet.dto.StatisticDTO; import org.lamsfoundation.lams.tool.spreadsheet.dto.Summary; @@ -66,12 +62,16 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + public class MonitoringAction extends Action { public static Logger log = Logger.getLogger(MonitoringAction.class); @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException, JSONException { + HttpServletResponse response) throws IOException, ServletException { String param = mapping.getParameter(); request.setAttribute("initialTabId", WebUtil.readLongParam(request, AttributeNames.PARAM_CURRENT_TAB, true)); @@ -105,7 +105,7 @@ private ActionForward summary(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { - //initial Session Map + //initial Session Map SessionMap sessionMap = new SessionMap(); request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); request.setAttribute(SpreadsheetConstants.ATTR_SESSION_MAP_ID, sessionMap.getSessionID()); @@ -132,7 +132,7 @@ } private ActionForward getUsers(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws JSONException, IOException { + HttpServletResponse response) throws IOException { Long sessionID = new Long(WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID)); Long contentId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); @@ -159,13 +159,13 @@ List users = service.getUsersForTablesorter(sessionID, page, size, sorting, searchString, spreadsheet.isReflectOnActivity()); - JSONArray rows = new JSONArray(); - JSONObject responsedata = new JSONObject(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); + ObjectNode responsedata = JsonNodeFactory.instance.objectNode(); responsedata.put("total_rows", service.getCountUsersBySession(sessionID, searchString)); for (Object[] userAndReflection : users) { - JSONObject responseRow = new JSONObject(); + ObjectNode responseRow = JsonNodeFactory.instance.objectNode(); SpreadsheetUser user = (SpreadsheetUser) userAndReflection[0]; responseRow.put(SpreadsheetConstants.ATTR_USER_UID, user.getUid()); @@ -181,24 +181,20 @@ } if (userAndReflection.length > 1 && userAndReflection[1] != null) { - responseRow.put("reflection", userAndReflection[1]); + responseRow.put("reflection", (String) userAndReflection[1]); } - if (userAndReflection.length > 2 && userAndReflection[2] != null) { - responseRow.put("portraitId", userAndReflection[2]); - } - - rows.put(responseRow); + rows.add(responseRow); } - responsedata.put("rows", rows); + responsedata.set("rows", rows); response.setContentType("application/json;charset=utf-8"); response.getWriter().print(new String(responsedata.toString())); return null; } /** * AJAX call to refresh statistic page. - * + * * @param mapping * @param form * @param request @@ -219,7 +215,7 @@ /** * View mark of all learner from same tool content ID. - * + * * @param mapping * @param form * @param request @@ -236,15 +232,15 @@ List userList = service.getUserListBySessionId(sessionId); request.setAttribute(AttributeNames.PARAM_TOOL_SESSION_ID, sessionId); request.setAttribute(SpreadsheetConstants.ATTR_USER_LIST, userList); - request.setAttribute(SpreadsheetConstants.ATTR_SESSION_MAP_ID, + request.setAttribute(SpreadsheetConstants.ATTR_SESSION_MAP_ID, WebUtil.readStrParam(request, SpreadsheetConstants.ATTR_SESSION_MAP_ID)); - + return mapping.findForward("viewAllMarks"); } /** * Release mark - * + * * @param mapping * @param form * @param request @@ -277,7 +273,7 @@ /** * Download Spreadsheet marks by MS Excel file format. - * + * * @param mapping * @param form * @param request @@ -378,7 +374,7 @@ // if((user == null) || (user.getUserModifiedSpreadsheet() == null)){ // ActionErrors errors = new ActionErrors(); - // errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage(SpreadsheetConstants.ERROR_MSG_MARKS_BLANK)); + // errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage(SpreadsheetConstants.ERROR_MSG_MARKS_BLANK)); // this.addErrors(request,errors); // return mapping.findForward("error"); // } @@ -401,7 +397,7 @@ } request.setAttribute(SpreadsheetConstants.ATTR_CODE, code); - + return mapping.findForward(SpreadsheetConstants.SUCCESS); } @@ -440,7 +436,7 @@ Long userUid = markForm.getUserUid(); SpreadsheetUser user = getSpreadsheetService().getUser(userUid); if (user != null && user.getUserModifiedSpreadsheet() != null) { - //check whether it is "edit(old item)" or "add(new item)" + //check whether it is "edit(old item)" or "add(new item)" SpreadsheetMark mark; if (user.getUserModifiedSpreadsheet().getMark() == null) { //new mark mark = new SpreadsheetMark(); @@ -471,7 +467,7 @@ /** * Save statistic information into request - * + * * @param request * @param submitFilesSessionList */ Index: lams_tool_survey/src/java/org/lamsfoundation/lams/tool/survey/service/SurveyServiceImpl.java =================================================================== diff -u -r8e090b3ddf269cdffececa4bc55a9333da5b0858 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_survey/src/java/org/lamsfoundation/lams/tool/survey/service/SurveyServiceImpl.java (.../SurveyServiceImpl.java) (revision 8e090b3ddf269cdffececa4bc55a9333da5b0858) +++ lams_tool_survey/src/java/org/lamsfoundation/lams/tool/survey/service/SurveyServiceImpl.java (.../SurveyServiceImpl.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -38,9 +38,6 @@ import java.util.TreeSet; import org.apache.log4j.Logger; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.events.IEventNotificationService; import org.lamsfoundation.lams.learning.service.ILearnerService; import org.lamsfoundation.lams.learningdesign.service.ExportToolContentException; @@ -86,6 +83,9 @@ import org.lamsfoundation.lams.util.JsonUtil; import org.lamsfoundation.lams.util.MessageService; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * @author Dapeng.Ni */ @@ -225,13 +225,13 @@ @Override public Map> getReflectList(Long contentId, boolean setEntry) { - Map> map = new HashMap>(); + Map> map = new HashMap<>(); List sessionList = surveySessionDao.getByContentId(contentId); for (SurveySession session : sessionList) { Long sessionId = session.getSessionId(); boolean hasRefection = session.getSurvey().isReflectOnActivity(); - Set list = new TreeSet(new ReflectDTOComparator()); + Set list = new TreeSet<>(new ReflectDTOComparator()); // get all users in this session List users = surveyUserDao.getBySessionID(sessionId); for (SurveyUser user : users) { @@ -301,17 +301,17 @@ @Override public List getQuestionAnswers(Long sessionId, Long userUid) { - List questions = new ArrayList(); + List questions = new ArrayList<>(); SurveySession session = surveySessionDao.getSessionBySessionId(sessionId); if (session != null) { Survey survey = session.getSurvey(); if (survey != null) { - questions = new ArrayList(survey.getQuestions()); + questions = new ArrayList<>(survey.getQuestions()); } } // set answer for this question acoording - List answers = new ArrayList(); + List answers = new ArrayList<>(); for (SurveyQuestion question : questions) { AnswerDTO answerDTO = new AnswerDTO(question); SurveyAnswer answer = surveyAnswerDao.getAnswer(question.getUid(), userUid); @@ -351,7 +351,7 @@ AnswerDTO answerDto = new AnswerDTO(question); // create a map to hold Option UID and the counts for that choice - Map optMap = new HashMap(); + Map optMap = new HashMap<>(); // total number of answers - used for the percentage calculations int numberAnswers = 0; @@ -406,7 +406,7 @@ @Override public SortedMap> getSummary(Long toolContentId) { - SortedMap> summary = new TreeMap>( + SortedMap> summary = new TreeMap<>( new SurveySessionComparator()); Survey survey = surveyDao.getByContentId(toolContentId); @@ -415,7 +415,7 @@ List sessionList = surveySessionDao.getByContentId(toolContentId); // iterator all sessions under this survey content, and get all questions and its answers. for (SurveySession session : sessionList) { - List responseList = new ArrayList(); + List responseList = new ArrayList<>(); for (SurveyQuestion question : questionList) { AnswerDTO response = getQuestionResponse(session.getSessionId(), question.getUid()); responseList.add(response); @@ -428,7 +428,7 @@ @Override public SortedMap getStatistic(Long contentId) { - SortedMap result = new TreeMap(new SurveySessionComparator()); + SortedMap result = new TreeMap<>(new SurveySessionComparator()); List stats = surveyUserDao.getStatisticsBySession(contentId); for (Object[] stat : stats) { @@ -451,7 +451,7 @@ SurveySession session = surveySessionDao.getSessionBySessionId(toolSessionID); List users = surveyUserDao.getBySessionID(toolSessionID); - Map> sessionToUsersMap = new HashMap>(); + Map> sessionToUsersMap = new HashMap<>(); sessionToUsersMap.put(session, users); return getExportSummary(sessionToUsersMap); @@ -467,11 +467,11 @@ private SortedMap>> getExportSummary( Map> sessionToUsersMap) { - SortedMap>> summary = new TreeMap>>( + SortedMap>> summary = new TreeMap<>( new SurveySessionComparator()); // all questions - List questions = new ArrayList(); + List questions = new ArrayList<>(); if (!sessionToUsersMap.isEmpty()) { SurveySession session = sessionToUsersMap.keySet().iterator().next(); Survey survey = session.getSurvey(); @@ -481,14 +481,14 @@ // traverse all sessions for (SurveySession session : sessionToUsersMap.keySet()) { - SortedMap> questionMap = new TreeMap>( + SortedMap> questionMap = new TreeMap<>( new QuestionsComparator()); // traverse all questions for (SurveyQuestion question : questions) { List users = sessionToUsersMap.get(session); - List answerDtos = new ArrayList(); + List answerDtos = new ArrayList<>(); // if it's for a single user - query DB for only one answer for this current user if (users.size() == 1) { @@ -545,10 +545,10 @@ public boolean isGroupedActivity(long toolContentID) { return toolService.isGroupedActivity(toolContentID); } - + @Override public void auditLogStartEditingActivityInMonitor(long toolContentID) { - toolService.auditLogStartEditingActivityInMonitor(toolContentID); + toolService.auditLogStartEditingActivityInMonitor(toolContentID); } @Override @@ -851,10 +851,10 @@ public ToolOutput getToolOutput(String name, Long toolSessionId, Long learnerId) { return getSurveyOutputFactory().getToolOutput(name, this, toolSessionId, learnerId); } - + @Override public List getToolOutputs(String name, Long toolContentId) { - return new ArrayList(); + return new ArrayList<>(); } @Override @@ -956,7 +956,7 @@ return new ToolCompletionStatus(learner.isSessionFinished() ? ToolCompletionStatus.ACTIVITY_COMPLETED : ToolCompletionStatus.ACTIVITY_ATTEMPTED, null, null); } - + // ****************** REST methods ************************* /** @@ -966,62 +966,62 @@ * (default true), showOnePage (default true), notifyTeachersOnAnswerSumbit (default false), showOtherUsersAnswers * (default false), reflectOnActivity, reflectInstructions, submissionDeadline * - * Questions must contain a JSONArray of JSONObject objects, which have the following mandatory fields: - * questionText, type (1=one answer,2=multiple answers,3=free text entry) and answers. Answers is a JSONArray of + * Questions must contain a ArrayNode of ObjectNode objects, which have the following mandatory fields: + * questionText, type (1=one answer,2=multiple answers,3=free text entry) and answers. Answers is a ArrayNode of * strings, which are the answer text. A question may also have the optional fields: allowOtherTextEntry (default * false), required (default true) * * There should be at least one question object in the Questions array and at least one option in the Options array. */ @Override - public void createRestToolContent(Integer userID, Long toolContentID, JSONObject toolContentJSON) - throws JSONException { + public void createRestToolContent(Integer userID, Long toolContentID, ObjectNode toolContentJSON) { Survey survey = new Survey(); Date updateDate = new Date(); survey.setCreated(updateDate); survey.setUpdated(updateDate); survey.setContentId(toolContentID); - survey.setTitle(toolContentJSON.getString(RestTags.TITLE)); - survey.setInstructions(toolContentJSON.getString(RestTags.INSTRUCTIONS)); + survey.setTitle(JsonUtil.optString(toolContentJSON, RestTags.TITLE)); + survey.setInstructions(JsonUtil.optString(toolContentJSON, RestTags.INSTRUCTIONS)); survey.setContentInUse(false); survey.setDefineLater(false); - survey.setLockWhenFinished(JsonUtil.opt(toolContentJSON, RestTags.LOCK_WHEN_FINISHED, Boolean.TRUE)); - survey.setReflectInstructions((String) JsonUtil.opt(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS, null)); - survey.setReflectOnActivity(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); + survey.setLockWhenFinished(JsonUtil.optBoolean(toolContentJSON, RestTags.LOCK_WHEN_FINISHED, Boolean.TRUE)); + survey.setReflectInstructions(JsonUtil.optString(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS)); + survey.setReflectOnActivity(JsonUtil.optBoolean(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); survey.setNotifyTeachersOnAnswerSumbit( - JsonUtil.opt(toolContentJSON, "notifyTeachersOnAnswerSumbit", Boolean.FALSE)); - survey.setShowOnePage(JsonUtil.opt(toolContentJSON, "showOnePage", Boolean.TRUE)); - survey.setShowOtherUsersAnswers(JsonUtil.opt(toolContentJSON, "showOtherUsersAnswers", Boolean.FALSE)); + JsonUtil.optBoolean(toolContentJSON, "notifyTeachersOnAnswerSumbit", Boolean.FALSE)); + survey.setShowOnePage(JsonUtil.optBoolean(toolContentJSON, "showOnePage", Boolean.TRUE)); + survey.setShowOtherUsersAnswers(JsonUtil.optBoolean(toolContentJSON, "showOtherUsersAnswers", Boolean.FALSE)); // submissionDeadline is set in monitoring - SurveyUser surveyUser = new SurveyUser(userID.longValue(), toolContentJSON.getString("firstName"), - toolContentJSON.getString("lastName"), toolContentJSON.getString("loginName"), survey); + SurveyUser surveyUser = new SurveyUser(userID.longValue(), JsonUtil.optString(toolContentJSON, "firstName"), + JsonUtil.optString(toolContentJSON, "lastName"), JsonUtil.optString(toolContentJSON, "loginName"), + survey); survey.setCreatedBy(surveyUser); // **************************** Handle Survey Questions ********************* - JSONArray questions = toolContentJSON.getJSONArray(RestTags.QUESTIONS); - for (int i = 0; i < questions.length(); i++) { - JSONObject questionData = (JSONObject) questions.get(i); + ArrayNode questions = JsonUtil.optArray(toolContentJSON, RestTags.QUESTIONS); + for (int i = 0; i < questions.size(); i++) { + ObjectNode questionData = (ObjectNode) questions.get(i); SurveyQuestion newQuestion = new SurveyQuestion(); newQuestion.setCreateBy(surveyUser); newQuestion.setCreateDate(updateDate); - newQuestion.setDescription(questionData.getString(RestTags.QUESTION_TEXT)); - newQuestion.setType((short) questionData.getInt("type")); - newQuestion.setAppendText(JsonUtil.opt(questionData, "allowOtherTextEntry", Boolean.FALSE)); - Boolean required = JsonUtil.opt(questionData, "required", Boolean.TRUE); + newQuestion.setDescription(JsonUtil.optString(questionData, RestTags.QUESTION_TEXT)); + newQuestion.setType((short) questionData.get("type").asInt()); + newQuestion.setAppendText(JsonUtil.optBoolean(questionData, "allowOtherTextEntry", Boolean.FALSE)); + Boolean required = JsonUtil.optBoolean(questionData, "required", Boolean.TRUE); newQuestion.setOptional(!required); newQuestion.setSequenceId(i + 1); // sequence number starts at 1 - Set newOptions = new HashSet(); - JSONArray options = questionData.getJSONArray(RestTags.ANSWERS); - for (int j = 0; j < options.length(); j++) { + Set newOptions = new HashSet<>(); + ArrayNode options = JsonUtil.optArray(questionData, RestTags.ANSWERS); + for (int j = 0; j < options.size(); j++) { SurveyOption newOption = new SurveyOption(); - newOption.setDescription(options.getString(j)); + newOption.setDescription(options.get(j).asText()); newOption.setSequenceId(j); // sequence number starts at 0 newOptions.add(newOption); } Index: lams_tool_survey/src/java/org/lamsfoundation/lams/tool/survey/web/action/MonitoringAction.java =================================================================== diff -u -r8e090b3ddf269cdffececa4bc55a9333da5b0858 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_survey/src/java/org/lamsfoundation/lams/tool/survey/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision 8e090b3ddf269cdffececa4bc55a9333da5b0858) +++ lams_tool_survey/src/java/org/lamsfoundation/lams/tool/survey/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -21,7 +21,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.tool.survey.web.action; import java.io.IOException; @@ -53,9 +52,6 @@ import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionMessage; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.tool.survey.SurveyConstants; import org.lamsfoundation.lams.tool.survey.dto.AnswerDTO; import org.lamsfoundation.lams.tool.survey.model.Survey; @@ -67,6 +63,7 @@ import org.lamsfoundation.lams.tool.survey.util.SurveyWebUtils; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; import org.lamsfoundation.lams.util.DateUtil; +import org.lamsfoundation.lams.util.JsonUtil; import org.lamsfoundation.lams.util.MessageService; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.session.SessionManager; @@ -75,6 +72,10 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + public class MonitoringAction extends Action { public ISurveyService surveyService; @@ -89,7 +90,7 @@ @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException, JSONException { + HttpServletResponse response) throws IOException, ServletException { String param = mapping.getParameter(); if (param.equals("summary")) { @@ -123,7 +124,7 @@ /** * Summary page action. - * + * * @param mapping * @param form * @param request @@ -178,7 +179,8 @@ MonitoringAction.log.info("Time:" + tzSubmissionDeadline.getTime()); // store submission deadline to sessionMap sessionMap.put(SurveyConstants.ATTR_SUBMISSION_DEADLINE, tzSubmissionDeadline.getTime()); - sessionMap.put(SurveyConstants.ATTR_SUBMISSION_DEADLINE_DATESTRING, DateUtil.convertToStringForJSON(submissionDeadline, request.getLocale())); + sessionMap.put(SurveyConstants.ATTR_SUBMISSION_DEADLINE_DATESTRING, + DateUtil.convertToStringForJSON(submissionDeadline, request.getLocale())); } return mapping.findForward(SurveyConstants.SUCCESS); @@ -198,7 +200,7 @@ } private ActionForward getAnswersJSON(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws JSONException, IOException { + HttpServletResponse response) throws IOException { Long sessionId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); Long questionUid = WebUtil.readLongParam(request, SurveyConstants.ATTR_QUESTION_UID); @@ -220,21 +222,22 @@ List users = service.getQuestionAnswersForTablesorter(sessionId, questionUid, page, size, sorting, searchString); - JSONArray rows = new JSONArray(); - JSONObject responsedata = new JSONObject(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); + ObjectNode responsedata = JsonNodeFactory.instance.objectNode(); responsedata.put("total_rows", service.getCountUsersBySession(sessionId, searchString)); for (Object[] userAndAnswers : users) { - JSONObject responseRow = new JSONObject(); + ObjectNode responseRow = JsonNodeFactory.instance.objectNode(); SurveyUser user = (SurveyUser) userAndAnswers[0]; responseRow.put(SurveyConstants.ATTR_USER_NAME, StringEscapeUtils.escapeHtml(user.getLastName() + " " + user.getFirstName())); responseRow.put(SurveyConstants.ATTR_USER_ID, user.getUserId()); if (userAndAnswers.length > 1 && userAndAnswers[1] != null) { - responseRow.put("choices", SurveyWebUtils.getChoiceList((String) userAndAnswers[1])); + responseRow.put("choices", + JsonUtil.readArray(SurveyWebUtils.getChoiceList((String) userAndAnswers[1]))); } if (userAndAnswers.length > 2 && userAndAnswers[2] != null) { // Data is handled differently in learner depending on whether @@ -257,9 +260,9 @@ if (userAndAnswers.length > 3 && userAndAnswers[3] != null) { responseRow.put(SurveyConstants.ATTR_PORTRAIT_ID, ((Number)userAndAnswers[3]).longValue()); } - rows.put(responseRow); + rows.add(responseRow); } - responsedata.put("rows", rows); + responsedata.set("rows", rows); response.setContentType("application/json;charset=utf-8"); response.getWriter().print(new String(responsedata.toString())); return null; @@ -278,7 +281,7 @@ } private ActionForward getReflectionsJSON(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws JSONException, IOException { + HttpServletResponse response) throws IOException { Long sessionId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); @@ -297,19 +300,19 @@ ISurveyService service = getSurveyService(); List users = service.getUserReflectionsForTablesorter(sessionId, page, size, sorting, searchString); - JSONArray rows = new JSONArray(); - JSONObject responsedata = new JSONObject(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); + ObjectNode responsedata = JsonNodeFactory.instance.objectNode(); responsedata.put("total_rows", service.getCountUsersBySession(sessionId, searchString)); for (Object[] userAndReflection : users) { - JSONObject responseRow = new JSONObject(); + ObjectNode responseRow = JsonNodeFactory.instance.objectNode(); SurveyUser user = (SurveyUser) userAndReflection[0]; responseRow.put(SurveyConstants.ATTR_USER_NAME, StringEscapeUtils.escapeHtml(user.getLastName() + " " + user.getFirstName())); responseRow.put(SurveyConstants.ATTR_USER_ID, user.getUserId()); - + if (userAndReflection.length > 1 && userAndReflection[1] != null) { String reflection = StringEscapeUtils.escapeHtml((String) userAndReflection[1]); responseRow.put(SurveyConstants.ATTR_REFLECTION, reflection.replaceAll("\n", "
")); @@ -319,17 +322,17 @@ responseRow.put(SurveyConstants.ATTR_PORTRAIT_ID, ((Number)userAndReflection[2]).longValue()); } - rows.put(responseRow); + rows.add(responseRow); } - responsedata.put("rows", rows); + responsedata.set("rows", rows); response.setContentType("application/json;charset=utf-8"); response.getWriter().print(new String(responsedata.toString())); return null; } /** * Export Excel format survey data. - * + * * @param mapping * @param form * @param request @@ -526,13 +529,13 @@ /** * Set Submission Deadline - * + * * @param mapping * @param form * @param request * @param response * @return - * @throws IOException + * @throws IOException */ public ActionForward setSubmissionDeadline(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException { @@ -562,7 +565,7 @@ /** * Removes all the html tags from a string - * + * * @param string * @return */ Index: lams_tool_task/src/java/org/lamsfoundation/lams/tool/taskList/web/action/MonitoringAction.java =================================================================== diff -u -r83ca314c18ea866bb79570b6e7da25eb8729b3b4 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_task/src/java/org/lamsfoundation/lams/tool/taskList/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision 83ca314c18ea866bb79570b6e7da25eb8729b3b4) +++ lams_tool_task/src/java/org/lamsfoundation/lams/tool/taskList/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -21,7 +21,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.tool.taskList.web.action; import java.io.IOException; @@ -47,9 +46,6 @@ import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.tool.taskList.TaskListConstants; import org.lamsfoundation.lams.tool.taskList.dto.ReflectDTO; import org.lamsfoundation.lams.tool.taskList.dto.SessionDTO; @@ -72,14 +68,18 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + public class MonitoringAction extends Action { public static Logger log = Logger.getLogger(MonitoringAction.class); private static String TOOL_URL = Configuration.get(ConfigurationKeys.SERVER_URL) + "/tool/" + TaskListConstants.TOOL_SIGNATURE + "/"; @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException, JSONException { + HttpServletResponse response) throws IOException, ServletException { String param = mapping.getParameter(); if (param.equals("summary")) { @@ -108,7 +108,7 @@ HttpServletResponse response) { // initial Session Map - SessionMap sessionMap = new SessionMap(); + SessionMap sessionMap = new SessionMap<>(); request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); request.setAttribute(TaskListConstants.ATTR_SESSION_MAP_ID, sessionMap.getSessionID()); @@ -138,7 +138,8 @@ TimeZone teacherTimeZone = teacher.getTimeZone(); Date tzSubmissionDeadline = DateUtil.convertToTimeZoneFromDefault(teacherTimeZone, submissionDeadline); sessionMap.put(TaskListConstants.ATTR_SUBMISSION_DEADLINE, tzSubmissionDeadline.getTime()); - sessionMap.put(TaskListConstants.ATTR_SUBMISSION_DEADLINE_DATESTRING, DateUtil.convertToStringForJSON(submissionDeadline, request.getLocale())); + sessionMap.put(TaskListConstants.ATTR_SUBMISSION_DEADLINE_DATESTRING, + DateUtil.convertToStringForJSON(submissionDeadline, request.getLocale())); } // Create reflectList if reflection is enabled. @@ -165,7 +166,7 @@ TaskListItem item = service.getTaskListItemByUid(itemUid); // create sessionList depending on whether the item was created by author or by learner - List sessionDtos = new ArrayList(); + List sessionDtos = new ArrayList<>(); if (item.isCreateByAuthor()) { List sessionList = service.getSessionsByContentId(contentId); for (TaskListSession session : sessionList) { @@ -189,7 +190,7 @@ * Refreshes user list. */ public ActionForward getPagedUsers(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse res) throws IOException, ServletException, JSONException { + HttpServletResponse res) throws IOException, ServletException { ITaskListService service = getTaskListService(); String sessionMapID = request.getParameter(TaskListConstants.ATTR_SESSION_MAP_ID); @@ -227,48 +228,46 @@ Math.ceil(new Integer(countSessionUsers).doubleValue() / new Integer(rowLimit).doubleValue())) .intValue(); - JSONArray rows = new JSONArray(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); int i = 1; for (TaskListUserDTO userDto : userDtos) { - JSONArray userData = new JSONArray(); - userData.put(userDto.getUserId()); + ArrayNode userData = JsonNodeFactory.instance.arrayNode(); + userData.add(userDto.getUserId()); String fullName = StringEscapeUtils.escapeHtml(userDto.getFullName()); - userData.put(fullName); + userData.add(fullName); Set completedTaskUids = userDto.getCompletedTaskUids(); for (TaskListItem item : items) { - String completionImage = completedTaskUids.contains(item.getUid()) - ? "" + String completionImage = completedTaskUids.contains(item.getUid()) ? "" : ""; - userData.put(completionImage); + userData.add(completionImage); } if (tasklist.isMonitorVerificationRequired()) { String label = StringEscapeUtils.escapeHtml(service.getMessage("label.confirm")); - String verificationStatus = userDto.isVerifiedByMonitor() - ? "" + String verificationStatus = userDto.isVerifiedByMonitor() ? "" : "" + label + ""; - userData.put(verificationStatus); + userData.add(verificationStatus); } - userData.put(userDto.getPortraitId()); + userData.add(userDto.getPortraitId()); - JSONObject userRow = new JSONObject(); + ObjectNode userRow = JsonNodeFactory.instance.objectNode(); userRow.put("id", i++); userRow.put("cell", userData); - rows.put(userRow); + rows.add(userRow); } - JSONObject responseJSON = new JSONObject(); + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); responseJSON.put("total", totalPages); responseJSON.put("page", page); responseJSON.put("records", countSessionUsers); - responseJSON.put("rows", rows); + responseJSON.set("rows", rows); res.setContentType("application/json;charset=utf-8"); res.getWriter().print(new String(responseJSON.toString())); @@ -279,7 +278,7 @@ * Refreshes user list. */ public ActionForward getPagedUsersByItem(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse res) throws IOException, ServletException, JSONException { + HttpServletResponse res) throws IOException, ServletException { ITaskListService service = getTaskListService(); Long sessionId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); @@ -317,28 +316,27 @@ String label = StringEscapeUtils.escapeHtml(service.getMessage("label.download")); int i = 0; - JSONArray rows = new JSONArray(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); for (TaskListUserDTO userDto : userDtos) { - JSONArray userData = new JSONArray(); + ArrayNode userData = JsonNodeFactory.instance.arrayNode(); String fullName = StringEscapeUtils.escapeHtml(userDto.getFullName()); - userData.put(fullName); + userData.add(fullName); - String completionImage = userDto.isCompleted() - ? "" + String completionImage = userDto.isCompleted() ? "" : ""; - userData.put(completionImage); + userData.add(completionImage); String accessDate = (userDto.getAccessDate() == null) ? "" : dateFormatter .format(DateUtil.convertToTimeZoneFromDefault(monitorTimeZone, userDto.getAccessDate())); - userData.put(accessDate); + userData.add(accessDate); // fill up with comments and attachments made by this user if (item.isCommentsAllowed() || item.isFilesAllowed()) { String commentsFiles = "
    "; - ArrayList userComments = new ArrayList(); + ArrayList userComments = new ArrayList<>(); for (TaskListItemComment comment : itemComments) { if (userDto.getUserId().equals(comment.getCreateBy().getUserId())) { userComments.add(comment.getComment()); @@ -352,7 +350,7 @@ commentsFiles += ""; } - ArrayList userAttachments = new ArrayList(); + ArrayList userAttachments = new ArrayList<>(); for (TaskListItemAttachment attachment : itemAttachments) { if (userDto.getUserId().equals(attachment.getCreateBy().getUserId())) { userAttachments.add(attachment); @@ -385,21 +383,21 @@ // // // - userData.put(commentsFiles); + userData.add(commentsFiles); } - JSONObject userRow = new JSONObject(); + ObjectNode userRow = JsonNodeFactory.instance.objectNode(); userRow.put("id", i++); - userRow.put("cell", userData); + userRow.set("cell", userData); - rows.put(userRow); + rows.add(userRow); } - JSONObject responseJSON = new JSONObject(); + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); responseJSON.put("total", totalPages); responseJSON.put("page", page); responseJSON.put("records", countSessionUsers); - responseJSON.put("rows", rows); + responseJSON.set("rows", rows); res.setContentType("application/json;charset=utf-8"); res.getWriter().print(new String(responseJSON.toString())); Index: lams_tool_vote/src/java/org/lamsfoundation/lams/tool/vote/service/VoteService.java =================================================================== diff -u -r83ca314c18ea866bb79570b6e7da25eb8729b3b4 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_vote/src/java/org/lamsfoundation/lams/tool/vote/service/VoteService.java (.../VoteService.java) (revision 83ca314c18ea866bb79570b6e7da25eb8729b3b4) +++ lams_tool_vote/src/java/org/lamsfoundation/lams/tool/vote/service/VoteService.java (.../VoteService.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -43,9 +43,6 @@ import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.contentrepository.client.IToolContentHandler; import org.lamsfoundation.lams.learning.service.ILearnerService; import org.lamsfoundation.lams.learningdesign.DataFlowObject; @@ -104,6 +101,9 @@ import org.lamsfoundation.lams.web.util.AttributeNames; import org.springframework.dao.DataAccessException; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * The POJO implementation of Voting service. All business logic of Voting tool is implemented in this class. It * translates the request from presentation layer and performs appropriate database operation. @@ -270,7 +270,7 @@ Map mapStandardNominationsContent = new TreeMap(new VoteComparator()); Map mapVoteRates = new TreeMap(new VoteComparator()); - for (VoteQueContent question : (Set) voteContent.getVoteQueContents()) { + for (VoteQueContent question : voteContent.getVoteQueContents()) { mapStandardNominationsHTMLedContent.put(mapIndex, question.getQuestion()); String noHTMLNomination = VoteUtils.stripHTML(question.getQuestion()); @@ -326,7 +326,7 @@ LinkedList sessionDTOs = new LinkedList(); VoteContent voteContent = this.getVoteContent(toolContentID); - for (VoteSession session : (Set) voteContent.getVoteSessions()) { + for (VoteSession session : voteContent.getVoteSessions()) { SessionDTO sessionDTO = new SessionDTO(); sessionDTO.setSessionId(session.getVoteSessionId().toString()); @@ -343,7 +343,7 @@ Map mapStandardQuestionUid = new TreeMap(new VoteComparator()); Map mapStandardToolSessionUid = new TreeMap(new VoteComparator()); - for (VoteQueContent question : (Set) voteContent.getVoteQueContents()) { + for (VoteQueContent question : voteContent.getVoteQueContents()) { mapStandardNominationsHTMLedContent.put(mapIndex, question.getQuestion()); int votesCount = voteUsrAttemptDAO.getStandardAttemptsForQuestionContentAndSessionUid(question.getUid(), @@ -406,10 +406,11 @@ totalCompletedSessionUserCount += sessionDTO.getCompletedSessionUserCount(); Long mapIndex = 1L; - for (VoteQueContent question : (Set) voteContent.getVoteQueContents()) { + for (VoteQueContent question : voteContent.getVoteQueContents()) { Long votesCount = sessionDTO.getMapStandardUserCount().get(mapIndex); Long oldTotalVotesCount = (totalMapStandardUserCount.get(mapIndex) != null) - ? totalMapStandardUserCount.get(mapIndex) : 0L; + ? totalMapStandardUserCount.get(mapIndex) + : 0L; totalMapStandardUserCount.put(mapIndex, oldTotalVotesCount + votesCount); allSessionsVotesCount += votesCount; @@ -422,7 +423,8 @@ if (voteContent.isAllowText()) { Long votesCount = sessionDTO.getMapStandardUserCount().get(mapIndex); Long oldTotalVotesCount = (totalMapStandardUserCount.get(mapIndex) != null) - ? totalMapStandardUserCount.get(mapIndex) : 0L; + ? totalMapStandardUserCount.get(mapIndex) + : 0L; totalMapStandardUserCount.put(mapIndex, oldTotalVotesCount + votesCount); allSessionsVotesCount += votesCount; @@ -445,7 +447,7 @@ Long mapIndex = 1L; Map totalMapVoteRates = new TreeMap(new VoteComparator()); int totalStandardVotesCount = 0; - for (VoteQueContent question : (Set) voteContent.getVoteQueContents()) { + for (VoteQueContent question : voteContent.getVoteQueContents()) { Long votesCount = totalMapStandardUserCount.get(mapIndex); @@ -478,7 +480,7 @@ SortedSet sessionDTOs = new TreeSet(); VoteContent voteContent = this.getVoteContent(toolContentID); - for (VoteSession session : (Set) voteContent.getVoteSessions()) { + for (VoteSession session : voteContent.getVoteSessions()) { SummarySessionDTO sessionDTO = new SummarySessionDTO(); sessionDTO.setSessionName(session.getSession_name()); @@ -490,7 +492,7 @@ int totalStandardVotesCount = 0; - for (VoteQueContent question : (Set) voteContent.getVoteQueContents()) { + for (VoteQueContent question : voteContent.getVoteQueContents()) { SessionNominationDTO nominationDTO = new SessionNominationDTO(); nominationDTO.setQuestionUid(question.getUid()); @@ -1314,7 +1316,7 @@ return; } - for (VoteSession session : (Set) voteContent.getVoteSessions()) { + for (VoteSession session : voteContent.getVoteSessions()) { List entries = coreNotebookService.getEntry(session.getVoteSessionId(), CoreNotebookConstants.NOTEBOOK_TOOL, VoteAppConstants.MY_SIGNATURE); for (NotebookEntry entry : entries) { @@ -1338,7 +1340,7 @@ return; } - for (VoteSession session : (Set) voteContent.getVoteSessions()) { + for (VoteSession session : voteContent.getVoteSessions()) { VoteQueUsr user = voteUserDAO.getVoteUserBySession(userId.longValue(), session.getUid()); if (user != null) { voteUsrAttemptDAO.removeAttemptsForUserandSession(user.getUid(), session.getUid()); @@ -1554,10 +1556,10 @@ public boolean isGroupedActivity(long toolContentID) { return toolService.isGroupedActivity(toolContentID); } - + @Override public void auditLogStartEditingActivityInMonitor(long toolContentID) { - toolService.auditLogStartEditingActivityInMonitor(toolContentID); + toolService.auditLogStartEditingActivityInMonitor(toolContentID); } @Override @@ -1584,7 +1586,7 @@ @Override public boolean isReadOnly(Long toolContentId) { VoteContent voteContent = voteContentDAO.getVoteContentByContentId(toolContentId); - for (VoteSession session : (Set) voteContent.getVoteSessions()) { + for (VoteSession session : voteContent.getVoteSessions()) { if (!session.getVoteQueUsers().isEmpty()) { return true; } @@ -1961,35 +1963,36 @@ return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_NOT_ATTEMPTED, null, null); } - Date startDate = null; Date endDate = null; Set attempts = learner.getVoteUsrAttempts(); // expect only one for (VoteUsrAttempt item : attempts) { Date newDate = item.getAttemptTime(); if (newDate != null) { - if (startDate == null || newDate.before(startDate)) + if (startDate == null || newDate.before(startDate)) { startDate = newDate; - if (endDate == null || newDate.after(endDate)) + } + if (endDate == null || newDate.after(endDate)) { endDate = newDate; + } } } - if (learner.isResponseFinalised()) + if (learner.isResponseFinalised()) { return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_COMPLETED, startDate, endDate); - else + } else { return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_ATTEMPTED, startDate, null); + } } // ****************** REST methods ************************* /** * Rest call to create a new Vote content. Required fields in toolContentJSON: "title", "instructions", "answers". - * The "answers" entry should be a JSONArray of Strings. + * The "answers" entry should be a ArrayNode of Strings. */ @Override - public void createRestToolContent(Integer userID, Long toolContentID, JSONObject toolContentJSON) - throws JSONException { + public void createRestToolContent(Integer userID, Long toolContentID, ObjectNode toolContentJSON) { if (logger.isDebugEnabled()) { logger.debug("Rest call to create a new Vote content for userID" + userID + " and toolContentID " + toolContentID); @@ -1998,39 +2001,42 @@ VoteContent vote = new VoteContent(); vote.setVoteContentId(toolContentID); - vote.setTitle(toolContentJSON.getString(RestTags.TITLE)); - vote.setInstructions(toolContentJSON.getString(RestTags.INSTRUCTIONS)); + vote.setTitle(JsonUtil.optString(toolContentJSON, RestTags.TITLE)); + vote.setInstructions(JsonUtil.optString(toolContentJSON, RestTags.INSTRUCTIONS)); vote.setCreatedBy(userID); vote.setCreationDate(updateDate); vote.setUpdateDate(updateDate); - vote.setAllowText(JsonUtil.opt(toolContentJSON, "allowText", Boolean.FALSE)); + vote.setAllowText(JsonUtil.optBoolean(toolContentJSON, "allowText", Boolean.FALSE)); vote.setDefineLater(false); - vote.setLockOnFinish(JsonUtil.opt(toolContentJSON, RestTags.LOCK_WHEN_FINISHED, Boolean.FALSE)); - vote.setMaxNominationCount(JsonUtil.opt(toolContentJSON, "maxNominations", "1")); - vote.setMinNominationCount(JsonUtil.opt(toolContentJSON, "minNominations", "1")); - vote.setReflect(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); - vote.setReflectionSubject(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS, (String) null)); - vote.setShowResults(JsonUtil.opt(toolContentJSON, "showResults", Boolean.TRUE)); + vote.setLockOnFinish(JsonUtil.optBoolean(toolContentJSON, RestTags.LOCK_WHEN_FINISHED, Boolean.FALSE)); + vote.setMaxNominationCount(JsonUtil.optString(toolContentJSON, "maxNominations", "1")); + vote.setMinNominationCount(JsonUtil.optString(toolContentJSON, "minNominations", "1")); + vote.setReflect(JsonUtil.optBoolean(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); + vote.setReflectionSubject(JsonUtil.optString(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS)); + vote.setShowResults(JsonUtil.optBoolean(toolContentJSON, "showResults", Boolean.TRUE)); vote.setUseSelectLeaderToolOuput( - JsonUtil.opt(toolContentJSON, RestTags.USE_SELECT_LEADER_TOOL_OUTPUT, Boolean.FALSE)); + JsonUtil.optBoolean(toolContentJSON, RestTags.USE_SELECT_LEADER_TOOL_OUTPUT, Boolean.FALSE)); // Is the data flow functionality actually used anywhere? - vote.setAssignedDataFlowObject((Boolean) JsonUtil.opt(toolContentJSON, "assignedDataFlowObject", null)); - vote.setExternalInputsAdded((Short) JsonUtil.opt(toolContentJSON, "externalInputsAdded", null)); - vote.setMaxExternalInputs(JsonUtil.opt(toolContentJSON, "maxInputs", Short.valueOf("0"))); + vote.setAssignedDataFlowObject(JsonUtil.optBoolean(toolContentJSON, "assignedDataFlowObject")); + Integer externalInputsAdded = JsonUtil.optInt(toolContentJSON, "externalInputsAdded"); + if (externalInputsAdded != null) { + vote.setExternalInputsAdded(externalInputsAdded.shortValue()); + } + vote.setMaxExternalInputs(JsonUtil.optInt(toolContentJSON, "maxInputs", 0).shortValue()); // submissionDeadline is set in monitoring // **************************** Nomination entries ********************* - JSONArray answers = toolContentJSON.getJSONArray(RestTags.ANSWERS); + ArrayNode answers = JsonUtil.optArray(toolContentJSON, RestTags.ANSWERS); //Set newAnswersSet = vote.getVoteQueContents(); - for (int i = 0; i < answers.length(); i++) { + for (int i = 0; i < answers.size(); i++) { // String answerJSONData = (String) answers.get(i); VoteQueContent answer = new VoteQueContent(); answer.setDisplayOrder(i + 1); answer.setMcContent(vote); - answer.setQuestion((String) answers.get(i)); + answer.setQuestion(answers.get(i).asText()); answer.setVoteContent(vote); vote.getVoteQueContents().add(answer); } Index: lams_tool_vote/src/java/org/lamsfoundation/lams/tool/vote/web/action/MonitoringAction.java =================================================================== diff -u -r83ca314c18ea866bb79570b6e7da25eb8729b3b4 -rbdb4be0c50cd46304d96bc83f11283866445f1c0 --- lams_tool_vote/src/java/org/lamsfoundation/lams/tool/vote/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision 83ca314c18ea866bb79570b6e7da25eb8729b3b4) +++ lams_tool_vote/src/java/org/lamsfoundation/lams/tool/vote/web/action/MonitoringAction.java (.../MonitoringAction.java) (revision bdb4be0c50cd46304d96bc83f11283866445f1c0) @@ -42,9 +42,6 @@ import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; -import org.apache.tomcat.util.json.JSONArray; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.notebook.model.NotebookEntry; import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; import org.lamsfoundation.lams.tool.exception.ToolException; @@ -73,6 +70,10 @@ import org.lamsfoundation.lams.web.util.AttributeNames; import org.lamsfoundation.lams.web.util.SessionMap; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * @author Ozgur Demirtas */ @@ -90,17 +91,17 @@ } public ActionForward hideOpenVote(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException, ToolException, JSONException { + HttpServletResponse response) throws IOException, ServletException, ToolException { return toggleHideShow(request, response, false); } public ActionForward showOpenVote(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException, ToolException, JSONException { + HttpServletResponse response) throws IOException, ServletException, ToolException { return toggleHideShow(request, response, true); } private ActionForward toggleHideShow(HttpServletRequest request, HttpServletResponse response, boolean show) - throws IOException, ServletException, ToolException, JSONException { + throws IOException, ServletException, ToolException { IVoteService voteService = VoteServiceProxy.getVoteService(getServlet().getServletContext()); @@ -120,7 +121,7 @@ voteService.hideOpenVote(voteUsrAttempt); } - JSONObject responsedata = new JSONObject(); + ObjectNode responsedata = JsonNodeFactory.instance.objectNode(); responsedata.put("currentUid", currentUid); responsedata.put("nextActionMethod", nextActionMethod); response.setContentType("application/json;charset=utf-8"); @@ -154,7 +155,7 @@ } public ActionForward getVoteNominationsJSON(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException, ToolException, JSONException { + HttpServletResponse response) throws IOException, ServletException, ToolException { Long sessionUid = WebUtil.readLongParam(request, VoteAppConstants.ATTR_SESSION_UID, true); if (sessionUid == 0L) { @@ -183,30 +184,30 @@ List users = voteService.getUserAttemptsForTablesorter(sessionUid, questionUid, page, size, sorting, searchString); - JSONArray rows = new JSONArray(); - JSONObject responsedata = new JSONObject(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); + ObjectNode responsedata = JsonNodeFactory.instance.objectNode(); responsedata.put("total_rows", voteService.getCountUsersBySession(sessionUid, questionUid, searchString)); for (Object[] userAndAnswers : users) { - JSONObject responseRow = new JSONObject(); - responseRow.put(VoteAppConstants.ATTR_USER_ID, userAndAnswers[0]); + ObjectNode responseRow = JsonNodeFactory.instance.objectNode(); + responseRow.put(VoteAppConstants.ATTR_USER_ID, (Integer) userAndAnswers[0]); responseRow.put(VoteAppConstants.ATTR_USER_NAME, StringEscapeUtils.escapeHtml((String) userAndAnswers[2])); responseRow.put(VoteAppConstants.ATTR_ATTEMPT_TIME, DateUtil.convertToStringForJSON((Date) userAndAnswers[3], request.getLocale())); responseRow.put(VoteAppConstants.ATTR_ATTEMPT_TIME_TIMEAGO, DateUtil.convertToStringForTimeagoJSON((Date) userAndAnswers[3])); - responseRow.put(VoteAppConstants.ATTR_PORTRAIT_ID, userAndAnswers[4]); - rows.put(responseRow); + responseRow.put(VoteAppConstants.ATTR_PORTRAIT_ID, (Integer) userAndAnswers[4]); + rows.add(responseRow); } - responsedata.put("rows", rows); + responsedata.set("rows", rows); response.setContentType("application/json;charset=utf-8"); response.getWriter().print(new String(responsedata.toString())); return null; } public ActionForward getReflectionsJSON(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException, ToolException, JSONException { + HttpServletResponse response) throws IOException, ServletException, ToolException { Long sessionUid = WebUtil.readLongParam(request, VoteAppConstants.ATTR_SESSION_UID, true); @@ -226,25 +227,25 @@ List users = voteService.getUserReflectionsForTablesorter(sessionUid, page, size, sorting, searchString); - JSONArray rows = new JSONArray(); - JSONObject responsedata = new JSONObject(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); + ObjectNode responsedata = JsonNodeFactory.instance.objectNode(); responsedata.put("total_rows", voteService.getCountUsersBySession(sessionUid, null, searchString)); for (Object[] userAndReflection : users) { - JSONObject responseRow = new JSONObject(); - responseRow.put(VoteAppConstants.ATTR_USER_ID, userAndReflection[0]); + ObjectNode responseRow = JsonNodeFactory.instance.objectNode(); + responseRow.put(VoteAppConstants.ATTR_USER_ID, (Integer) userAndReflection[0]); responseRow.put(VoteAppConstants.ATTR_USER_NAME, StringEscapeUtils.escapeHtml((String) userAndReflection[2])); if (userAndReflection.length > 3 && userAndReflection[3] != null) { String reflection = StringEscapeUtils.escapeHtml((String) userAndReflection[3]); responseRow.put(VoteAppConstants.NOTEBOOK, reflection.replaceAll("\n", "
    ")); } if (userAndReflection.length > 4) { - responseRow.put(VoteAppConstants.ATTR_PORTRAIT_ID, userAndReflection[4]); + responseRow.put(VoteAppConstants.ATTR_PORTRAIT_ID, (Integer) userAndReflection[4]); } - rows.put(responseRow); + rows.add(responseRow); } - responsedata.put("rows", rows); + responsedata.set("rows", rows); response.setContentType("application/json;charset=utf-8"); response.getWriter().print(new String(responsedata.toString())); return null; @@ -262,7 +263,7 @@ } public ActionForward getOpenTextNominationsJSON(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException, ToolException, JSONException { + HttpServletResponse response) throws IOException, ServletException, ToolException { Long sessionUid = WebUtil.readLongParam(request, VoteAppConstants.ATTR_SESSION_UID, true); if (sessionUid == 0L) { @@ -300,13 +301,13 @@ List users = voteService.getUserOpenTextAttemptsForTablesorter(sessionUid, contentUid, page, size, sorting, searchStringVote, searchStringUsername); - JSONArray rows = new JSONArray(); - JSONObject responsedata = new JSONObject(); + ArrayNode rows = JsonNodeFactory.instance.arrayNode(); + ObjectNode responsedata = JsonNodeFactory.instance.objectNode(); responsedata.put("total_rows", voteService.getCountUsersForOpenTextEntries(sessionUid, contentUid, searchStringVote, searchStringUsername)); for (OpenTextAnswerDTO userAndAttempt : users) { - JSONObject responseRow = new JSONObject(); + ObjectNode responseRow = JsonNodeFactory.instance.objectNode(); responseRow.put("uid", userAndAttempt.getUserUid()); responseRow.put(VoteAppConstants.ATTR_USER_NAME, @@ -321,9 +322,9 @@ responseRow.put("visible", userAndAttempt.isVisible()); responseRow.put("portraitId", userAndAttempt.getPortraitId()); - rows.put(responseRow); + rows.add(responseRow); } - responsedata.put("rows", rows); + responsedata.set("rows", rows); response.setContentType("application/json;charset=utf-8"); response.getWriter().print(new String(responsedata.toString())); return null; @@ -483,7 +484,7 @@ while (queIterator.hasNext()) { VoteQuestionDTO voteQuestionDTO = new VoteQuestionDTO(); - VoteQueContent voteQueContent = (VoteQueContent) queIterator.next(); + VoteQueContent voteQueContent = queIterator.next(); if (voteQueContent != null) { voteQuestionDTO.setQuestion(voteQueContent.getQuestion());