Index: lams_admin/src/java/org/lamsfoundation/lams/admin/web/controller/LogEventController.java =================================================================== diff -u -r8e2e72a36d57288787cf76af6484e25c82b385c1 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_admin/src/java/org/lamsfoundation/lams/admin/web/controller/LogEventController.java (.../LogEventController.java) (revision 8e2e72a36d57288787cf76af6484e25c82b385c1) +++ lams_admin/src/java/org/lamsfoundation/lams/admin/web/controller/LogEventController.java (.../LogEventController.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -62,7 +62,7 @@ @Autowired private ILogEventService logEventService; - + @Autowired @Qualifier("adminMessageService") private MessageService messageService; @@ -121,11 +121,12 @@ int sorting = ILogEventService.SORT_BY_DATE_DESC; if (isSortDate != null) { - sorting = isSortDate.equals(1) ? ILogEventService.SORT_BY_DATE_DESC : ILogEventService.SORT_BY_DATE_ASC; + sorting = isSortDate.equals(1) ? ILogEventService.SORT_BY_DATE_DESC : ILogEventService.SORT_BY_DATE_ASC; } else if (isSortUser != null) { - sorting = isSortUser.equals(1) ? ILogEventService.SORT_BY_USER_DESC : ILogEventService.SORT_BY_USER_ASC; + sorting = isSortUser.equals(1) ? ILogEventService.SORT_BY_USER_DESC : ILogEventService.SORT_BY_USER_ASC; } else if (isSortTarget != null) { - sorting = isSortTarget.equals(1) ? ILogEventService.SORT_BY_TARGET_DESC : ILogEventService.SORT_BY_TARGET_ASC; + sorting = isSortTarget.equals(1) ? ILogEventService.SORT_BY_TARGET_DESC + : ILogEventService.SORT_BY_TARGET_ASC; } Long dateParameter = WebUtil.readLongParam(request, "startDate", true); @@ -161,8 +162,10 @@ LogEvent event = (LogEvent) eventDetails[0]; ObjectNode responseRow = JsonNodeFactory.instance.objectNode(); - responseRow.put("dateOccurred", event.getOccurredDateTime() != null ? - DateUtil.convertToStringForJSON(event.getOccurredDateTime(), request.getLocale()) : ""); + responseRow.put("dateOccurred", + event.getOccurredDateTime() != null + ? DateUtil.convertToStringForJSON(event.getOccurredDateTime(), request.getLocale()) + : ""); responseRow.put("typeId", event.getLogEventTypeId()); responseRow.put("description", event.getDescription()); if (event.getLessonId() != null) { @@ -174,13 +177,15 @@ User user = event.getUser(); if (user != null) { - responseRow.put("userPortraitId", user.getPortraitUuid()); + responseRow.put("userPortraitId", + user.getPortraitUuid() == null ? null : user.getPortraitUuid().toString()); responseRow.put("userId", user.getUserId()); responseRow.put("userName", user.getLogin()); } User targetUser = event.getTargetUser(); if (targetUser != null) { - responseRow.put("targetUserPortraitId", targetUser.getPortraitUuid()); + responseRow.put("targetUserPortraitId", + targetUser.getPortraitUuid() == null ? null : targetUser.getPortraitUuid().toString()); responseRow.put("targetUserId", targetUser.getUserId()); responseRow.put("targetUserName", targetUser.getLogin()); } Index: lams_admin/src/java/org/lamsfoundation/lams/admin/web/controller/UserController.java =================================================================== diff -u -r1ef1213820fe7ff7c6f4a9238b3f489a25012c63 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_admin/src/java/org/lamsfoundation/lams/admin/web/controller/UserController.java (.../UserController.java) (revision 1ef1213820fe7ff7c6f4a9238b3f489a25012c63) +++ lams_admin/src/java/org/lamsfoundation/lams/admin/web/controller/UserController.java (.../UserController.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -173,7 +173,7 @@ userSelectedTheme = themeService.getDefaultTheme().getThemeId(); } userForm.setUserTheme(userSelectedTheme); - userForm.setInitialPortraitId(user.getPortraitUuid()); + userForm.setInitialPortraitId(user.getPortraitUuid() == null ? null : user.getPortraitUuid().toString()); //property available for modification only to sysadmins userForm.setTwoFactorAuthenticationEnabled(user.isTwoFactorAuthenticationEnabled()); Index: lams_admin/src/java/org/lamsfoundation/lams/admin/web/form/UserForm.java =================================================================== diff -u -r550e1b37b507779064955267ef47e9085f791357 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_admin/src/java/org/lamsfoundation/lams/admin/web/form/UserForm.java (.../UserForm.java) (revision 550e1b37b507779064955267ef47e9085f791357) +++ lams_admin/src/java/org/lamsfoundation/lams/admin/web/form/UserForm.java (.../UserForm.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -53,7 +53,7 @@ private Long userTheme; private boolean twoFactorAuthenticationEnabled = false; // - private Long initialPortraitId = null; + private String initialPortraitId = null; public Integer getOrgId() { return orgId; @@ -279,11 +279,11 @@ this.twoFactorAuthenticationEnabled = twoFactorAuthenticationEnabled; } - public Long getInitialPortraitId() { + public String getInitialPortraitId() { return initialPortraitId; } - public void setInitialPortraitId(Long initialPortraitId) { + public void setInitialPortraitId(String initialPortraitId) { this.initialPortraitId = initialPortraitId; } Index: lams_central/src/java/org/lamsfoundation/lams/web/PortraitActionForm.java =================================================================== diff -u -r792f30e164500b758d9eeac2dcf19853be4dfd9f -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_central/src/java/org/lamsfoundation/lams/web/PortraitActionForm.java (.../PortraitActionForm.java) (revision 792f30e164500b758d9eeac2dcf19853be4dfd9f) +++ lams_central/src/java/org/lamsfoundation/lams/web/PortraitActionForm.java (.../PortraitActionForm.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -30,14 +30,14 @@ */ public class PortraitActionForm { - private Long portraitUuid; + private String portraitUuid; private MultipartFile file; - public Long getPortraitUuid() { + public String getPortraitUuid() { return portraitUuid; } - public void setPortraitUuid(Long uuid) { + public void setPortraitUuid(String uuid) { this.portraitUuid = uuid; } Index: lams_central/src/java/org/lamsfoundation/lams/web/PortraitController.java =================================================================== diff -u -r40de3afab4e8d589660daffb6efd6e568e87f8fa -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_central/src/java/org/lamsfoundation/lams/web/PortraitController.java (.../PortraitController.java) (revision 40de3afab4e8d589660daffb6efd6e568e87f8fa) +++ lams_central/src/java/org/lamsfoundation/lams/web/PortraitController.java (.../PortraitController.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -23,6 +23,8 @@ package org.lamsfoundation.lams.web; +import java.util.UUID; + import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger; @@ -42,11 +44,12 @@ private IUserManagementService userManagementService; @RequestMapping("/portrait") - public String execute(@ModelAttribute("PortraitActionForm") PortraitActionForm portraitForm, HttpServletRequest request) { - Long portraitUuid = userManagementService.getUserByLogin(request.getRemoteUser()).getPortraitUuid(); + public String execute(@ModelAttribute("PortraitActionForm") PortraitActionForm portraitForm, + HttpServletRequest request) { + UUID portraitUuid = userManagementService.getUserByLogin(request.getRemoteUser()).getPortraitUuid(); log.debug("using portraitUuid=" + portraitUuid); // if no portrait has been uploaded, set the uuid to 0 - portraitForm.setPortraitUuid(portraitUuid == null ? 0 : portraitUuid); + portraitForm.setPortraitUuid(portraitUuid == null ? "0" : portraitUuid.toString()); return "profile/portrait"; } } Index: lams_central/src/java/org/lamsfoundation/lams/web/PortraitSaveController.java =================================================================== diff -u -r40de3afab4e8d589660daffb6efd6e568e87f8fa -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_central/src/java/org/lamsfoundation/lams/web/PortraitSaveController.java (.../PortraitSaveController.java) (revision 40de3afab4e8d589660daffb6efd6e568e87f8fa) +++ lams_central/src/java/org/lamsfoundation/lams/web/PortraitSaveController.java (.../PortraitSaveController.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.InputStream; +import java.util.UUID; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -67,7 +68,7 @@ public class PortraitSaveController { private static Logger log = Logger.getLogger(PortraitSaveController.class); private static final String PORTRAIT_DELETE_AUDIT_KEY = "audit.delete.portrait"; - + @Autowired private IUserManagementService userManagementService; @Autowired @@ -126,10 +127,10 @@ // upload to the content repository originalFileNode = centralToolContentHandler.uploadFile(is, fileNameWithoutExt + "_original.jpg", - "image/jpeg"); + "image/jpeg", true); is.close(); - log.debug("saved file with uuid: " + originalFileNode.getUuid() + " and version: " - + originalFileNode.getVersion()); + log.debug("saved file with uuid: " + originalFileNode.getUuid() + " and portrait uuid " + + originalFileNode.getPortraitUuid() + " and version: " + originalFileNode.getVersion()); //resize to the large size is = ResizePictureUtil.resize(file.getInputStream(), CommonConstants.PORTRAIT_LARGEST_DIMENSION_LARGE); @@ -158,7 +159,7 @@ if (user.getPortraitUuid() != null) { centralToolContentHandler.deleteFile(user.getPortraitUuid()); } - user.setPortraitUuid(originalFileNode.getUuid()); + user.setPortraitUuid(UUID.fromString(originalFileNode.getPortraitUuid())); userManagementService.saveUser(user); return "forward:/index.do?redirect=portrait"; Index: lams_central/src/java/org/lamsfoundation/lams/web/tag/PortraitTag.java =================================================================== diff -u -r0133bd53e11418a8235d232d9de4f92a553575e6 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_central/src/java/org/lamsfoundation/lams/web/tag/PortraitTag.java (.../PortraitTag.java) (revision 0133bd53e11418a8235d232d9de4f92a553575e6) +++ lams_central/src/java/org/lamsfoundation/lams/web/tag/PortraitTag.java (.../PortraitTag.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -48,18 +48,18 @@ private static final String CSS_ROUND = " portrait-round"; private static final String PORTRAIT_VERSION_SUFFIX = " portrait-color-"; - + private static final String STYLE_SMALL = "small"; - private static final String CSS_SMALL[] = {"portrait-sm", "&version=4"}; + private static final String CSS_SMALL[] = { "portrait-sm", "&version=4" }; private static final String CSS_GENERIC_SMALL = "portrait-generic-sm"; private static final String STYLE_MEDIUM = "medium"; - private static final String CSS_MEDIUM[] = {"portrait-md", "&version=3"}; + private static final String CSS_MEDIUM[] = { "portrait-md", "&version=3" }; private static final String CSS_GENERIC_MEDIUM = "portrait-generic-md"; private static final String STYLE_LARGE = "large"; - private static final String CSS_LARGE[] = {"portrait-lg", "&version=2"};; + private static final String CSS_LARGE[] = { "portrait-lg", "&version=2" };; private static final String CSS_GENERIC_LARGE = "portrait-generic-lg"; private static final String STYLE_XLARGE = "xlarge"; - private static final String CSS_XLARGE[] = {"portrait-xl", "&version=1"}; + private static final String CSS_XLARGE[] = { "portrait-xl", "&version=1" }; private static final String CSS_GENERIC_XLARGE = "portrait-generic-xl"; /* Attributes */ @@ -94,7 +94,7 @@ Integer userIdInt = Integer.decode(userId); User user = (User) getUserManagementService().findById(User.class, userIdInt); boolean isHover = (hover != null ? Boolean.valueOf(hover) : false); - if ( isHover ) { + if (isHover) { code = buildHoverUrl(user); } else { code = buildDivUrl(user); @@ -120,7 +120,7 @@ } private String buildDivUrl(User user) { - Long portraitId = user != null ? user.getPortraitUuid() : null; + String portraitId = user == null || user.getPortraitUuid() == null ? null : user.getPortraitUuid().toString(); if (portraitId != null) { boolean isRound = (round != null ? Boolean.valueOf(round) : true); String[] sizes = getSizeClass(); @@ -142,22 +142,23 @@ } private String buildHoverUrl(User user) { - Long portraitId = user != null ? user.getPortraitUuid() : null; + String portraitId = user == null || user.getPortraitUuid() == null ? null : user.getPortraitUuid().toString(); String linkText = getBodyContent() != null ? getBodyContent().getString() : null; if (portraitId != null) { String fullName = user.getFullName(); - if ( linkText == null || linkText.length() == 0) + if (linkText == null || linkText.length() == 0) { linkText = fullName; + } return new StringBuilder( "") - .append(linkText).append("").toString(); + .append("\" data-fullname=\"").append(fullName).append("\">").append(linkText) + .append("").toString(); } else { return linkText != null ? linkText : ""; } } - + private IUserManagementService getUserManagementService() { if (userManagementService == null) { WebApplicationContext ctx = WebApplicationContextUtils @@ -170,33 +171,39 @@ private HashMap getPortraitCache() { HashMap cache = (HashMap) pageContext.getAttribute("portraitCache"); if (cache == null) { - cache = new HashMap(); + cache = new HashMap<>(); pageContext.setAttribute("portraitCache", cache); } return cache; } /* Get String[size css class, version id] based on size attribute */ - private String[] getSizeClass() { + private String[] getSizeClass() { if (size != null) { - if (size.equalsIgnoreCase(STYLE_MEDIUM)) + if (size.equalsIgnoreCase(STYLE_MEDIUM)) { return CSS_MEDIUM; - if (size.equalsIgnoreCase(STYLE_LARGE)) + } + if (size.equalsIgnoreCase(STYLE_LARGE)) { return CSS_LARGE; - if (size.equalsIgnoreCase(STYLE_XLARGE)) + } + if (size.equalsIgnoreCase(STYLE_XLARGE)) { return CSS_XLARGE; + } } return CSS_SMALL; } private String getGenericSizeClass() { if (size != null) { - if (size.equalsIgnoreCase(STYLE_MEDIUM)) + if (size.equalsIgnoreCase(STYLE_MEDIUM)) { return CSS_GENERIC_MEDIUM; - if (size.equalsIgnoreCase(STYLE_LARGE)) + } + if (size.equalsIgnoreCase(STYLE_LARGE)) { return CSS_GENERIC_LARGE; - if (size.equalsIgnoreCase(STYLE_XLARGE)) + } + if (size.equalsIgnoreCase(STYLE_XLARGE)) { return CSS_GENERIC_XLARGE; + } } return CSS_GENERIC_SMALL; } Index: lams_common/src/java/org/lamsfoundation/lams/confidencelevel/ConfidenceLevelDTO.java =================================================================== diff -u -r6b89d0c84a5695fb1ad02d5525eb240a9f4d3134 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_common/src/java/org/lamsfoundation/lams/confidencelevel/ConfidenceLevelDTO.java (.../ConfidenceLevelDTO.java) (revision 6b89d0c84a5695fb1ad02d5525eb240a9f4d3134) +++ lams_common/src/java/org/lamsfoundation/lams/confidencelevel/ConfidenceLevelDTO.java (.../ConfidenceLevelDTO.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -1,27 +1,27 @@ package org.lamsfoundation.lams.confidencelevel; public class ConfidenceLevelDTO { - + // confidence levels can be of different types: public static final int CONFIDENCE_LEVELS_TYPE_0_TO_100 = 1; public static final int CONFIDENCE_LEVELS_TYPE_CONFIDENT = 2; public static final int CONFIDENCE_LEVELS_TYPE_SURE = 3; private Integer userId; - + private String userName; - - private Long portraitUuid; + private String portraitUuid; + private int level; - + //confidenceLevel's type: 1)0 to 100, 2)Confident or 3)Sure private int type; - + private Long qbQuestionUid; - + private Long qbOptionUid; - + /** */ public Integer getUserId() { @@ -31,7 +31,7 @@ public void setUserId(Integer userId) { this.userId = userId; } - + /** */ public void setUserName(String userName) { @@ -44,11 +44,11 @@ /** */ - public Long getPortraitUuid() { + public String getPortraitUuid() { return portraitUuid; } - public void setPortraitUuid(Long portraitUuid) { + public void setPortraitUuid(String portraitUuid) { this.portraitUuid = portraitUuid; } @@ -61,15 +61,15 @@ public int getLevel() { return this.level; } - + public Integer getType() { return type; } public void setType(Integer type) { this.type = type; } - + /** */ public void setQbQuestionUid(Long qbQuestionUid) { @@ -79,7 +79,7 @@ public Long getQbQuestionUid() { return this.qbQuestionUid; } - + /** */ public void setQbOptionUid(Long qbOptionUid) { Index: lams_common/src/java/org/lamsfoundation/lams/contentrepository/NodeKey.java =================================================================== diff -u -r46fe95e04d6fbe8fec9e41f054a711e23c1e064c -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_common/src/java/org/lamsfoundation/lams/contentrepository/NodeKey.java (.../NodeKey.java) (revision 46fe95e04d6fbe8fec9e41f054a711e23c1e064c) +++ lams_common/src/java/org/lamsfoundation/lams/contentrepository/NodeKey.java (.../NodeKey.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -21,7 +21,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.contentrepository; import org.apache.commons.lang.builder.EqualsBuilder; @@ -38,13 +37,15 @@ private Long uuid = null; private Long version = null; + private String portraitUuid; /** - * + * */ - public NodeKey(Long uuid, Long version) { + public NodeKey(Long uuid, Long version, String portraitUuid) { this.uuid = uuid; this.version = version; + this.portraitUuid = portraitUuid; } /** @@ -61,9 +62,14 @@ return version; } + public String getPortraitUuid() { + return portraitUuid; + } + @Override public String toString() { - return new ToStringBuilder(this).append("uuid", uuid).append("version", version).toString(); + return new ToStringBuilder(this).append("uuid", uuid).append("version", version) + .append("portraitUuid", portraitUuid).toString(); } @Override Index: lams_common/src/java/org/lamsfoundation/lams/contentrepository/client/IToolContentHandler.java =================================================================== diff -u -r9d017688cf84d7a7c26203a3b0e13a5301b9c756 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_common/src/java/org/lamsfoundation/lams/contentrepository/client/IToolContentHandler.java (.../IToolContentHandler.java) (revision 9d017688cf84d7a7c26203a3b0e13a5301b9c756) +++ lams_common/src/java/org/lamsfoundation/lams/contentrepository/client/IToolContentHandler.java (.../IToolContentHandler.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -21,11 +21,11 @@ * **************************************************************** */ - package org.lamsfoundation.lams.contentrepository.client; import java.io.IOException; import java.io.InputStream; +import java.util.UUID; import org.lamsfoundation.lams.contentrepository.NodeKey; import org.lamsfoundation.lams.contentrepository.exception.FileException; @@ -65,13 +65,16 @@ public NodeKey uploadFile(InputStream stream, String fileName, String mimeType) throws RepositoryCheckedException, InvalidParameterException, RepositoryCheckedException; + public NodeKey uploadFile(InputStream stream, String fileName, String mimeType, boolean generatePortraitUuid) + throws RepositoryCheckedException, InvalidParameterException, RepositoryCheckedException; + /** * Update an existing file in the repository. This will create a new version of this file (its version number will * be equal to the current one incremented by 1). * * @param uuid * unique id of the updated file. Mandatory - * + * * @param stream * Input filestream. Mandatory. * @param fileName @@ -91,7 +94,7 @@ /** * Save a directory of files in the content repository. - * + * * @param ticket * ticket issued on login. Identifies tool and workspace - mandatory * @param dirPath @@ -111,7 +114,7 @@ /** * Delete a file node. If the node does not exist, then nothing happens (ie ItemNotFoundException is NOT thrown). - * + * * @param uuid * id of the file node. Mandatory * @throws InvalidParameterException @@ -122,8 +125,13 @@ public void deleteFile(Long uuid) throws InvalidParameterException, RepositoryCheckedException; /** + * Delete a file node using portrait UUID + */ + public void deleteFile(UUID portraitUuid) throws InvalidParameterException, RepositoryCheckedException; + + /** * Get the file, as an inputstream. - * + * * @param uuid * id of the file node. Mandatory * @throws FileException Index: lams_common/src/java/org/lamsfoundation/lams/usermanagement/User.java =================================================================== diff -u -r1ee503e3d0e0228ea8a45025fddf15d9623c0377 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_common/src/java/org/lamsfoundation/lams/usermanagement/User.java (.../User.java) (revision 1ee503e3d0e0228ea8a45025fddf15d9623c0377) +++ lams_common/src/java/org/lamsfoundation/lams/usermanagement/User.java (.../User.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -30,6 +30,7 @@ import java.util.LinkedHashSet; import java.util.Set; import java.util.TimeZone; +import java.util.UUID; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -162,7 +163,7 @@ private AuthenticationMethod authenticationMethod; @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) - private Set userOrganisations = new HashSet(); + private Set userOrganisations = new HashSet<>(); @Column(name = "last_visited_organisation_id") private Integer lastVisitedOrganisationId; @@ -173,16 +174,16 @@ @OneToMany(mappedBy = "user") @LazyCollection(LazyCollectionOption.EXTRA) - private Set learnerProgresses = new HashSet(); + private Set learnerProgresses = new HashSet<>(); @OneToMany(mappedBy = "user") - private Set learningDesigns = new HashSet(); + private Set learningDesigns = new HashSet<>(); @OneToMany(mappedBy = "user") - private Set lessons = new HashSet(); + private Set lessons = new HashSet<>(); @Column(name = "portrait_uuid") - private Long portraitUuid; + private UUID portraitUuid; @Column(name = "change_password") private Boolean changePassword; @@ -194,7 +195,7 @@ @JoinTable(name = "lams_planner_recent_learning_designs", joinColumns = @JoinColumn(name = "user_id")) @Column(name = "learning_design_id") @OrderBy("learning_design_id") - private Set recentlyModifiedLearningDesigns = new LinkedHashSet(); + private Set recentlyModifiedLearningDesigns = new LinkedHashSet<>(); @Column(name = "modified_date") private Date modifiedDate; @@ -522,7 +523,7 @@ return new UserDTO(userId, firstName, lastName, login, languageIsoCode, countryIsoCode, direction, email, theme != null ? new ThemeDTO(theme) : null, timeZone, authenticationMethod.getAuthenticationMethodId(), fckLanguageMapping, (firstLogin == null || firstLogin ? true : false), // assume no firstLogin value means they haven't logged in - lastVisitedOrganisationId, portraitUuid); + lastVisitedOrganisationId, portraitUuid == null ? null : portraitUuid.toString()); } public UserBasicDTO getUserBasicDTO() { @@ -590,11 +591,11 @@ this.locale = locale; } - public Long getPortraitUuid() { + public UUID getPortraitUuid() { return portraitUuid; } - public void setPortraitUuid(Long portraitUuid) { + public void setPortraitUuid(UUID portraitUuid) { this.portraitUuid = portraitUuid; } Index: lams_common/src/java/org/lamsfoundation/lams/usermanagement/dao/hibernate/UserDAO.java =================================================================== diff -u -r62aaf160878735888d077bf28fac3c1989bb8fbd -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_common/src/java/org/lamsfoundation/lams/usermanagement/dao/hibernate/UserDAO.java (.../UserDAO.java) (revision 62aaf160878735888d077bf28fac3c1989bb8fbd) +++ lams_common/src/java/org/lamsfoundation/lams/usermanagement/dao/hibernate/UserDAO.java (.../UserDAO.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.UUID; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; @@ -82,17 +83,16 @@ List list = query.list(); //group by userId as long as it returns all completed visitLogs for each user - List userDtos = new ArrayList(); + List userDtos = new ArrayList<>(); for (Object[] element : list) { Integer userId = ((Number) element[0]).intValue(); String login = (String) element[1]; String firstName = (String) element[2]; String lastName = (String) element[3]; String email = (String) element[4]; - Long portraitUuid = element[5] != null ? ((Number) element[5]).longValue() : null; - + byte[] portraitUuid = (byte[]) element[5]; UserDTO userDto = new UserDTO(userId, firstName, lastName, login, null, null, null, email, null, null, null, - null, false, null, portraitUuid); + null, false, null, portraitUuid == null ? null : UUID.nameUUIDFromBytes(portraitUuid).toString()); userDtos.add(userDto); } Index: lams_common/src/java/org/lamsfoundation/lams/usermanagement/dto/UserDTO.java =================================================================== diff -u -r62aaf160878735888d077bf28fac3c1989bb8fbd -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_common/src/java/org/lamsfoundation/lams/usermanagement/dto/UserDTO.java (.../UserDTO.java) (revision 62aaf160878735888d077bf28fac3c1989bb8fbd) +++ lams_common/src/java/org/lamsfoundation/lams/usermanagement/dto/UserDTO.java (.../UserDTO.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -50,12 +50,12 @@ private Integer authenticationMethodId; private Boolean firstLogin; private Integer lastVisitedOrganisationId; - private Long portraitUuid; + private String portraitUuid; public UserDTO(Integer userID, String firstName, String lastName, String login, String localeLanguage, String localeCountry, String direction, String email, ThemeDTO htmlTheme, TimeZone timezone, Integer authenticationMethodId, String fckLanguageMapping, Boolean firstLogin, - Integer lastVisitedOrganisationId, Long portraitUuid) { + Integer lastVisitedOrganisationId, String portraitUuid) { this.userID = userID; this.firstName = firstName; this.lastName = lastName; @@ -183,11 +183,11 @@ return lastVisitedOrganisationId; } - public Long getPortraitUuid() { + public String getPortraitUuid() { return portraitUuid; } - public void setPortraitUuid(Long portraitUuid) { + public void setPortraitUuid(String portraitUuid) { this.portraitUuid = portraitUuid; } } \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/usermanagement/service/UserManagementService.java =================================================================== diff -u -r47f01daecb191d1ca81eaf131b1d063b2bc640b5 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_common/src/java/org/lamsfoundation/lams/usermanagement/service/UserManagementService.java (.../UserManagementService.java) (revision 47f01daecb191d1ca81eaf131b1d063b2bc640b5) +++ lams_common/src/java/org/lamsfoundation/lams/usermanagement/service/UserManagementService.java (.../UserManagementService.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -39,6 +39,7 @@ import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.UUID; import java.util.Vector; import java.util.stream.Collectors; @@ -306,7 +307,7 @@ } return true; } - + @Override public Organisation getOrganisationById(Integer organisationId) { return (Organisation) findById(Organisation.class, organisationId); @@ -371,7 +372,7 @@ properties.put("organisation.parentOrganisation.organisationId", parentOrgId); return baseDAO.findByProperties(UserOrganisation.class, properties); } - + @Override public UserOrganisationCollapsed getUserOrganisationCollapsed(Integer userId, Integer orgId) { Map properties = new HashMap<>(); @@ -380,9 +381,10 @@ List results = baseDAO.findByProperties(UserOrganisationCollapsed.class, properties); return results.isEmpty() ? null : (UserOrganisationCollapsed) results.get(0); } - + @Override - public List getChildOrganisationsCollapsedByUser(Integer parentOrganisationId, Integer userId) { + public List getChildOrganisationsCollapsedByUser(Integer parentOrganisationId, + Integer userId) { return organisationDAO.getChildOrganisationsCollapsedByUser(parentOrganisationId, userId); } @@ -1133,7 +1135,7 @@ FileInputStream is = new FileInputStream(portraitFile); String fileNameWithoutExt = login; NodeKey originalFileNode = centralToolContentHandler.uploadFile(is, - fileNameWithoutExt + "_original.jpg", "image/jpeg"); + fileNameWithoutExt + "_original.jpg", "image/jpeg", true); is.close(); log.debug("Saved original portrait with uuid: " + originalFileNode.getUuid() + " and version: " + originalFileNode.getVersion()); @@ -1180,7 +1182,7 @@ if (user.getPortraitUuid() != null) { centralToolContentHandler.deleteFile(user.getPortraitUuid()); } - user.setPortraitUuid(originalFileNode.getUuid()); + user.setPortraitUuid(UUID.fromString(originalFileNode.getPortraitUuid())); saveUser(user); log.info("Uploaded portrait for user " + userId + " with login \"" + login + "\""); Index: lams_common/src/java/org/lamsfoundation/lams/util/WebUtil.java =================================================================== diff -u -re6dc4db4137cfd6b07a4aa79711b9d12b39fb78e -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_common/src/java/org/lamsfoundation/lams/util/WebUtil.java (.../WebUtil.java) (revision e6dc4db4137cfd6b07a4aa79711b9d12b39fb78e) +++ lams_common/src/java/org/lamsfoundation/lams/util/WebUtil.java (.../WebUtil.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -1,539 +1,539 @@ -package org.lamsfoundation.lams.util; - -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; -import java.util.HashMap; -import java.util.Map.Entry; - -import javax.servlet.http.HttpServletRequest; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.apache.commons.lang.StringUtils; -import org.apache.log4j.Logger; -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 org.w3c.dom.Document; - -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; - -/** - * helper methods useful for servlets - */ -public class WebUtil { - - // --------------------------------------------------------------------- - // Class level constants - Session attributs - // --------------------------------------------------------------------- - - private static Logger log = Logger.getLogger(WebUtil.class); - /** - * A regular expression pattern that matches HTML tags. - */ - private static final String HTML_TAG_REGEX = "\\<.*?>"; - /** - * A regular expression pattern that matches end-of-line and space tags. If needed, BR tags can be extented to - * (?:
|
|
|
)
. Right now CKeditor creates only the first option. - */ - private static final String SPACE_TAG_REGEX = "(?:
)|(?: )|(?:
)"; - - private static final String URL_SHORTENING_CYPHER = "jbdnuteywk"; - - /** - * @exception IllegalArgumentException - * - if not set - */ - private static void checkObject(String paramName, Object paramValue) throws IllegalArgumentException { - boolean isNull = paramValue == null; - if (!isNull && String.class.isInstance(paramValue)) { - String str = (String) paramValue; - isNull = str.trim().length() == 0; - } - if (isNull) { - throw new IllegalArgumentException(paramName + " is required '" + paramValue + "'"); - } - } - - /** - * @return integer value of paramValue - * @exception IllegalArgumentException - * - if (a) not set and is not optional or (b) not integer - */ - public static Integer checkInteger(String paramName, String paramValue, boolean isOptional) - throws IllegalArgumentException { - try { - if (!isOptional) { - WebUtil.checkObject(paramName, paramValue); - } - String value = paramValue != null ? StringUtils.trimToNull(paramValue) : null; - return value != null ? Integer.valueOf(value) : null; - - } catch (NumberFormatException e) { - throw new IllegalArgumentException(paramName + " should be an integer '" + paramValue + "'"); - } - } - - /** - * @return long value of paramValue - * @exception IllegalArgumentException - * - if (a) not set and is not optional or (b) not long - */ - public static Long checkLong(String paramName, String paramValue, boolean isOptional) - throws IllegalArgumentException { - try { - if (!isOptional) { - WebUtil.checkObject(paramName, paramValue); - } - String value = paramValue != null ? StringUtils.trimToNull(paramValue) : null; - return value != null ? Long.valueOf(value) : null; - - } catch (NumberFormatException e) { - throw new IllegalArgumentException(paramName + " should be a long '" + paramValue + "'"); - } - } - - /** - * Get a long version of paramValue, throwing an IllegalArgumentException if isOptional = false and the is value is - * null - * - * @return long value of paramValue - * @exception IllegalArgumentException - * - if not set or not long - */ - public static long checkLong(String paramName, Long paramValue, boolean isOptional) - throws IllegalArgumentException { - if (!isOptional) { - WebUtil.checkObject(paramName, paramValue); - } - return paramValue.longValue(); - } - - /** - * @return boolean value of paramValue - * @exception IllegalArgumentException - * - if not set or not boolean - */ - public static boolean checkBoolean(String paramName, String paramValue) throws IllegalArgumentException { - WebUtil.checkObject(paramName, paramValue); - return Boolean.valueOf(paramValue.trim()).booleanValue(); - } - - /** - * Read an int parameter, throwing exception if null or not a integer - * - * @param req - * - - * @param paramName - * - - * @return parameter value - */ - public static int readIntParam(HttpServletRequest req, String paramName) { - return WebUtil.checkInteger(paramName, req.getParameter(paramName), false).intValue(); - } - - /** - * Read an int parameter, throwing exception if ( not optional and null ) or not a integer - * - * @param req - * - - * @param paramName - * - - * @param isOptional - * @return parameter value - */ - public static Integer readIntParam(HttpServletRequest req, String paramName, boolean isOptional) { - return WebUtil.checkInteger(paramName, req.getParameter(paramName), isOptional); - } - - /** - * Read an long parameter, throwing exception if null or not a long - * - * @param req - * - - * @param paramName - * - - * @return parameter value - */ - public static long readLongParam(HttpServletRequest req, String paramName) { - return WebUtil.checkLong(paramName, req.getParameter(paramName), false).longValue(); - } - - /** - * Read an long parameter, throwing exception if ( not optional and null ) or not a long - * - * @param req - * - - * @param paramName - * - - * @param isOptional - * @return parameter value - */ - public static Long readLongParam(HttpServletRequest req, String paramName, boolean isOptional) { - return WebUtil.checkLong(paramName, req.getParameter(paramName), isOptional); - } - - /** - * @param req - * - - * @param paramName - * - - * @return parameter value - */ - public static String readStrParam(HttpServletRequest req, String paramName) { - return WebUtil.readStrParam(req, paramName, false); - } - - /** - * @param req - * - - * @param paramName - * - - * @param isOptional - * @return parameter value - */ - public static String readStrParam(HttpServletRequest req, String paramName, boolean isOptional) { - if (!isOptional) { - WebUtil.checkObject(paramName, req.getParameter(paramName)); - } - return req.getParameter(paramName); - } - - /** - * @param req - * - - * @param paramName - * - - * @return parameter value - * @exception IllegalArgumentException - * - if valid boolean parameter value is not found - */ - public static boolean readBooleanParam(HttpServletRequest req, String paramName) throws IllegalArgumentException { - return WebUtil.checkBoolean(paramName, req.getParameter(paramName)); - } - - /** - * @param req - * - - * @param paramName - * - - * @param defaultValue - * - if valid boolean parameter value is not found, return this value - * @return parameter value - */ - public static boolean readBooleanParam(HttpServletRequest req, String paramName, boolean defaultValue) { - try { - return WebUtil.checkBoolean(paramName, req.getParameter(paramName)); - } catch (IllegalArgumentException e) { - return defaultValue; - } - } - - public static boolean readBooleanAttr(HttpServletRequest req, String attrName) { - return WebUtil.checkBoolean(attrName, (String) req.getSession().getAttribute(attrName)); - } - - /** - * Retrieve the tool access mode from http request. This is a utility used by the tools that share an implementation - * for the learner screen. They use mode=learner, mode=author and mode=teacher for learning, preview and monitoring - * respectively. Only used if the tool programmer wants to have one call that supports all three ways of looking at - * a learner screen. - * - * @param request - * @param param_mode - * @return the ToolAccessMode object - */ - public static ToolAccessMode readToolAccessModeParam(HttpServletRequest request, String param_mode, - boolean optional) { - String mode = WebUtil.readStrParam(request, param_mode, optional); - if (mode == null) { - return null; - } else if (mode.equals(ToolAccessMode.AUTHOR.toString())) { - return ToolAccessMode.AUTHOR; - } else if (mode.equals(ToolAccessMode.LEARNER.toString())) { - return ToolAccessMode.LEARNER; - } else if (mode.equals(ToolAccessMode.TEACHER.toString())) { - return ToolAccessMode.TEACHER; - } else { - throw new IllegalArgumentException("[" + mode + "] is not a legal mode" + "in LAMS"); - } - } - - /** - * Retrieve the tool access mode from a string value, presumably from a Form. This is a utility used by the tools - * that share an implementation for the learner screen. They use mode=learner, mode=author and mode=teacher for - * learning, preview and monitoring respectively. Only used if the tool programmer wants to have one call that - * supports all three ways of looking at a learner screen. - * - * @param request - * @return the ToolAccessMode object - */ - public static ToolAccessMode getToolAccessMode(String modeValue) { - if (modeValue != null) { - if (modeValue.equals(ToolAccessMode.AUTHOR.toString())) { - return ToolAccessMode.AUTHOR; - } else if (modeValue.equals(ToolAccessMode.LEARNER.toString())) { - return ToolAccessMode.LEARNER; - } else if (modeValue.equals(ToolAccessMode.TEACHER.toString())) { - return ToolAccessMode.TEACHER; - } - } - throw new IllegalArgumentException("[" + modeValue + "] is not a legal mode" + "in LAMS"); - } - - /** - * Get ToolAccessMode from HttpRequest parameters. Default value is AUTHOR mode. - * - * @param request - * @return - */ - 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; - } else { - mode = ToolAccessMode.AUTHOR; - } - return mode; - } - - /** - * Append a parameter to a requested url. - * - * @param parameterName - * the name of the parameter - * @param parameterValue - * the value of the parameter - * @param learnerUrl - * the target url - * @return the url with parameter appended. - */ - public static String appendParameterToURL(String url, String parameterName, String parameterValue) { - return WebUtil.appendParameterDeliminator(url) + parameterName + "=" + parameterValue; - } - - /** - *

- * This helper append the parameter deliminator for a url. - *

- * It is using a null safe String util method to checkup the url String and append proper deliminator if necessary. - * - * @param url - * the url needs to append deliminator. - * @return target url with the deliminator; - */ - public static String appendParameterDeliminator(String url) { - if (url == null) { - return null; - } else if (StringUtils.containsNone(url, "?")) { - return url + "?"; - } else { - return url + "&"; - } - } - - /** - * Converts a url (such as one from a tool) to a complete url. If the url starts with "http" then it is assumed to - * be a complete url and is returned as is. Otherwise it assumes starts with the path of the webapp so it is - * appended to the server url from the LAMS Configuration. - * - * @param url - * e.g. tool/lanb11/starter/learner.do - * @return complete url - */ - public static String convertToFullURL(String url) { - if (url == null) { - return null; - } else if (url.startsWith("http")) { - return url; - } else { - String serverURL = Configuration.get(ConfigurationKeys.SERVER_URL); - if (url.charAt(0) == '/') { - return serverURL + url; - } else { - return serverURL + '/' + url; - } - } - } - - /** - * Convert any newslines in a string to
- * . If input = null, returns null. - */ - public static String convertNewlines(String input) { - if (input != null) { - return input.replaceAll("[\n\r\f]", "
"); - } else { - return null; - } - } - - /** - * Strips HTML tags and leave "pure" text. Useful for CKeditor created text. - * - * @param text - * string to process - * @return string after stripping - */ - public static String removeHTMLtags(String text) { - return text == null ? null - : text.replaceAll(WebUtil.SPACE_TAG_REGEX, " ").replaceAll(WebUtil.HTML_TAG_REGEX, ""); - } - - /** - * Makes a request to the specified url with the specified parameters and returns the response inputstream - * - * @param urlStr - * @param params - * @return - * @throws ToolException - * @throws IOException - */ - public static InputStream getResponseInputStreamFromExternalServer(String urlStr, HashMap params) - throws IOException { - if (!urlStr.contains("?")) { - urlStr += "?"; - } - - for (Entry entry : params.entrySet()) { - urlStr += "&" + entry.getKey() + "=" + entry.getValue(); - } - - WebUtil.log.info("Making request to external servlet: " + urlStr); - - URL url = new URL(urlStr); - URLConnection conn = url.openConnection(); - if (!(conn instanceof HttpURLConnection)) { - WebUtil.log.error("Fail to connect to external server though url: " + urlStr); - throw new RuntimeException("Fail to connect to external server though url: " + urlStr); - } - - HttpURLConnection httpConn = (HttpURLConnection) conn; - if (httpConn.getResponseCode() != HttpURLConnection.HTTP_OK) { - WebUtil.log.error("Response code from external server: " + httpConn.getResponseCode() + " Url: " + urlStr); - } - - InputStream is = url.openConnection().getInputStream(); - if (is == null) { - WebUtil.log.error("Fail to fetch data from external server, return InputStream null: " + urlStr); - throw new RuntimeException("Fail to fetch data from external server, return inputStream null: " + urlStr); - } - - return is; - } - - public static String extractParameterValue(String url, String param) { - if (!StringUtils.isBlank(url) && !StringUtils.isBlank(param)) { - int quotationMarkIndex = url.indexOf("?"); - String queryPart = quotationMarkIndex > -1 ? url.substring(quotationMarkIndex + 1) : url; - String[] paramEntries = queryPart.split("&"); - for (String paramEntry : paramEntries) { - String[] paramEntrySplitted = paramEntry.split("="); - if ((paramEntrySplitted.length > 1) && param.equalsIgnoreCase(paramEntrySplitted[0])) { - return paramEntrySplitted[1]; - } - } - } - return null; - } - - /** - * Produces JSON object with basic user details. - */ - 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()); - userJSON.put("login", user.getLogin()); - userJSON.put("portraitId", user.getPortraitUuid()); - return userJSON; - } - - public static String getBaseServerURL() { - String serverURL = Configuration.get(ConfigurationKeys.SERVER_URL); - // "https://" is 8 characters, so next "/" should be context - return serverURL.substring(0, serverURL.indexOf('/', 9)); - } - - /** - * Converse lessonId into alphabetic sequence for using it in URL shortening - * - * @param lessonId - * @return - */ - public static String encodeLessonId(Long lessonId) { - String encodedLessonId = lessonId.toString(); - encodedLessonId = encodedLessonId.replace('0', URL_SHORTENING_CYPHER.charAt(0)); - encodedLessonId = encodedLessonId.replace('1', URL_SHORTENING_CYPHER.charAt(1)); - encodedLessonId = encodedLessonId.replace('2', URL_SHORTENING_CYPHER.charAt(2)); - encodedLessonId = encodedLessonId.replace('3', URL_SHORTENING_CYPHER.charAt(3)); - encodedLessonId = encodedLessonId.replace('4', URL_SHORTENING_CYPHER.charAt(4)); - encodedLessonId = encodedLessonId.replace('5', URL_SHORTENING_CYPHER.charAt(5)); - encodedLessonId = encodedLessonId.replace('6', URL_SHORTENING_CYPHER.charAt(6)); - encodedLessonId = encodedLessonId.replace('7', URL_SHORTENING_CYPHER.charAt(7)); - encodedLessonId = encodedLessonId.replace('8', URL_SHORTENING_CYPHER.charAt(8)); - encodedLessonId = encodedLessonId.replace('9', URL_SHORTENING_CYPHER.charAt(9)); - - return encodedLessonId; - } - - /** - * Decodes alphabetic sequence (that is lessonId encoded for URL shortening purposes) - * - * @param encodedlessonId - * @return - */ - public static String decodeLessonId(String encodedLessonId) throws IllegalArgumentException { - - // it should contain only the characters from URL_SHORTENING_CYPHER - if (!encodedLessonId.matches("[" + URL_SHORTENING_CYPHER + "]*")) { - throw new IllegalArgumentException("LessonId: " + encodedLessonId + " has wrong format."); - } - - String decodedLessonId = encodedLessonId; - decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(0), '0'); - decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(1), '1'); - decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(2), '2'); - decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(3), '3'); - decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(4), '4'); - decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(5), '5'); - decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(6), '6'); - decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(7), '7'); - decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(8), '8'); - decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(9), '9'); - - return decodedLessonId; - } - - public static Document getDocument() throws ParserConfigurationException { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); - Document document = builder.newDocument(); - return document; - } - - public static String getStringFromDocument(Document document) throws TransformerException { - DOMSource domSource = new DOMSource(document); - StringWriter writer = new StringWriter(); - StreamResult result = new StreamResult(writer); - TransformerFactory tf = TransformerFactory.newInstance(); - Transformer transformer = tf.newTransformer(); - transformer.transform(domSource, result); - return writer.toString(); - } +package org.lamsfoundation.lams.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.util.HashMap; +import java.util.Map.Entry; + +import javax.servlet.http.HttpServletRequest; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +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 org.w3c.dom.Document; + +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * helper methods useful for servlets + */ +public class WebUtil { + + // --------------------------------------------------------------------- + // Class level constants - Session attributs + // --------------------------------------------------------------------- + + private static Logger log = Logger.getLogger(WebUtil.class); + /** + * A regular expression pattern that matches HTML tags. + */ + private static final String HTML_TAG_REGEX = "\\<.*?>"; + /** + * A regular expression pattern that matches end-of-line and space tags. If needed, BR tags can be extented to + * (?:
|
|
|
)
. Right now CKeditor creates only the first option. + */ + private static final String SPACE_TAG_REGEX = "(?:
)|(?: )|(?:
)"; + + private static final String URL_SHORTENING_CYPHER = "jbdnuteywk"; + + /** + * @exception IllegalArgumentException + * - if not set + */ + private static void checkObject(String paramName, Object paramValue) throws IllegalArgumentException { + boolean isNull = paramValue == null; + if (!isNull && String.class.isInstance(paramValue)) { + String str = (String) paramValue; + isNull = str.trim().length() == 0; + } + if (isNull) { + throw new IllegalArgumentException(paramName + " is required '" + paramValue + "'"); + } + } + + /** + * @return integer value of paramValue + * @exception IllegalArgumentException + * - if (a) not set and is not optional or (b) not integer + */ + public static Integer checkInteger(String paramName, String paramValue, boolean isOptional) + throws IllegalArgumentException { + try { + if (!isOptional) { + WebUtil.checkObject(paramName, paramValue); + } + String value = paramValue != null ? StringUtils.trimToNull(paramValue) : null; + return value != null ? Integer.valueOf(value) : null; + + } catch (NumberFormatException e) { + throw new IllegalArgumentException(paramName + " should be an integer '" + paramValue + "'"); + } + } + + /** + * @return long value of paramValue + * @exception IllegalArgumentException + * - if (a) not set and is not optional or (b) not long + */ + public static Long checkLong(String paramName, String paramValue, boolean isOptional) + throws IllegalArgumentException { + try { + if (!isOptional) { + WebUtil.checkObject(paramName, paramValue); + } + String value = paramValue != null ? StringUtils.trimToNull(paramValue) : null; + return value != null ? Long.valueOf(value) : null; + + } catch (NumberFormatException e) { + throw new IllegalArgumentException(paramName + " should be a long '" + paramValue + "'"); + } + } + + /** + * Get a long version of paramValue, throwing an IllegalArgumentException if isOptional = false and the is value is + * null + * + * @return long value of paramValue + * @exception IllegalArgumentException + * - if not set or not long + */ + public static long checkLong(String paramName, Long paramValue, boolean isOptional) + throws IllegalArgumentException { + if (!isOptional) { + WebUtil.checkObject(paramName, paramValue); + } + return paramValue.longValue(); + } + + /** + * @return boolean value of paramValue + * @exception IllegalArgumentException + * - if not set or not boolean + */ + public static boolean checkBoolean(String paramName, String paramValue) throws IllegalArgumentException { + WebUtil.checkObject(paramName, paramValue); + return Boolean.valueOf(paramValue.trim()).booleanValue(); + } + + /** + * Read an int parameter, throwing exception if null or not a integer + * + * @param req + * - + * @param paramName + * - + * @return parameter value + */ + public static int readIntParam(HttpServletRequest req, String paramName) { + return WebUtil.checkInteger(paramName, req.getParameter(paramName), false).intValue(); + } + + /** + * Read an int parameter, throwing exception if ( not optional and null ) or not a integer + * + * @param req + * - + * @param paramName + * - + * @param isOptional + * @return parameter value + */ + public static Integer readIntParam(HttpServletRequest req, String paramName, boolean isOptional) { + return WebUtil.checkInteger(paramName, req.getParameter(paramName), isOptional); + } + + /** + * Read an long parameter, throwing exception if null or not a long + * + * @param req + * - + * @param paramName + * - + * @return parameter value + */ + public static long readLongParam(HttpServletRequest req, String paramName) { + return WebUtil.checkLong(paramName, req.getParameter(paramName), false).longValue(); + } + + /** + * Read an long parameter, throwing exception if ( not optional and null ) or not a long + * + * @param req + * - + * @param paramName + * - + * @param isOptional + * @return parameter value + */ + public static Long readLongParam(HttpServletRequest req, String paramName, boolean isOptional) { + return WebUtil.checkLong(paramName, req.getParameter(paramName), isOptional); + } + + /** + * @param req + * - + * @param paramName + * - + * @return parameter value + */ + public static String readStrParam(HttpServletRequest req, String paramName) { + return WebUtil.readStrParam(req, paramName, false); + } + + /** + * @param req + * - + * @param paramName + * - + * @param isOptional + * @return parameter value + */ + public static String readStrParam(HttpServletRequest req, String paramName, boolean isOptional) { + if (!isOptional) { + WebUtil.checkObject(paramName, req.getParameter(paramName)); + } + return req.getParameter(paramName); + } + + /** + * @param req + * - + * @param paramName + * - + * @return parameter value + * @exception IllegalArgumentException + * - if valid boolean parameter value is not found + */ + public static boolean readBooleanParam(HttpServletRequest req, String paramName) throws IllegalArgumentException { + return WebUtil.checkBoolean(paramName, req.getParameter(paramName)); + } + + /** + * @param req + * - + * @param paramName + * - + * @param defaultValue + * - if valid boolean parameter value is not found, return this value + * @return parameter value + */ + public static boolean readBooleanParam(HttpServletRequest req, String paramName, boolean defaultValue) { + try { + return WebUtil.checkBoolean(paramName, req.getParameter(paramName)); + } catch (IllegalArgumentException e) { + return defaultValue; + } + } + + public static boolean readBooleanAttr(HttpServletRequest req, String attrName) { + return WebUtil.checkBoolean(attrName, (String) req.getSession().getAttribute(attrName)); + } + + /** + * Retrieve the tool access mode from http request. This is a utility used by the tools that share an implementation + * for the learner screen. They use mode=learner, mode=author and mode=teacher for learning, preview and monitoring + * respectively. Only used if the tool programmer wants to have one call that supports all three ways of looking at + * a learner screen. + * + * @param request + * @param param_mode + * @return the ToolAccessMode object + */ + public static ToolAccessMode readToolAccessModeParam(HttpServletRequest request, String param_mode, + boolean optional) { + String mode = WebUtil.readStrParam(request, param_mode, optional); + if (mode == null) { + return null; + } else if (mode.equals(ToolAccessMode.AUTHOR.toString())) { + return ToolAccessMode.AUTHOR; + } else if (mode.equals(ToolAccessMode.LEARNER.toString())) { + return ToolAccessMode.LEARNER; + } else if (mode.equals(ToolAccessMode.TEACHER.toString())) { + return ToolAccessMode.TEACHER; + } else { + throw new IllegalArgumentException("[" + mode + "] is not a legal mode" + "in LAMS"); + } + } + + /** + * Retrieve the tool access mode from a string value, presumably from a Form. This is a utility used by the tools + * that share an implementation for the learner screen. They use mode=learner, mode=author and mode=teacher for + * learning, preview and monitoring respectively. Only used if the tool programmer wants to have one call that + * supports all three ways of looking at a learner screen. + * + * @param request + * @return the ToolAccessMode object + */ + public static ToolAccessMode getToolAccessMode(String modeValue) { + if (modeValue != null) { + if (modeValue.equals(ToolAccessMode.AUTHOR.toString())) { + return ToolAccessMode.AUTHOR; + } else if (modeValue.equals(ToolAccessMode.LEARNER.toString())) { + return ToolAccessMode.LEARNER; + } else if (modeValue.equals(ToolAccessMode.TEACHER.toString())) { + return ToolAccessMode.TEACHER; + } + } + throw new IllegalArgumentException("[" + modeValue + "] is not a legal mode" + "in LAMS"); + } + + /** + * Get ToolAccessMode from HttpRequest parameters. Default value is AUTHOR mode. + * + * @param request + * @return + */ + 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; + } else { + mode = ToolAccessMode.AUTHOR; + } + return mode; + } + + /** + * Append a parameter to a requested url. + * + * @param parameterName + * the name of the parameter + * @param parameterValue + * the value of the parameter + * @param learnerUrl + * the target url + * @return the url with parameter appended. + */ + public static String appendParameterToURL(String url, String parameterName, String parameterValue) { + return WebUtil.appendParameterDeliminator(url) + parameterName + "=" + parameterValue; + } + + /** + *

+ * This helper append the parameter deliminator for a url. + *

+ * It is using a null safe String util method to checkup the url String and append proper deliminator if necessary. + * + * @param url + * the url needs to append deliminator. + * @return target url with the deliminator; + */ + public static String appendParameterDeliminator(String url) { + if (url == null) { + return null; + } else if (StringUtils.containsNone(url, "?")) { + return url + "?"; + } else { + return url + "&"; + } + } + + /** + * Converts a url (such as one from a tool) to a complete url. If the url starts with "http" then it is assumed to + * be a complete url and is returned as is. Otherwise it assumes starts with the path of the webapp so it is + * appended to the server url from the LAMS Configuration. + * + * @param url + * e.g. tool/lanb11/starter/learner.do + * @return complete url + */ + public static String convertToFullURL(String url) { + if (url == null) { + return null; + } else if (url.startsWith("http")) { + return url; + } else { + String serverURL = Configuration.get(ConfigurationKeys.SERVER_URL); + if (url.charAt(0) == '/') { + return serverURL + url; + } else { + return serverURL + '/' + url; + } + } + } + + /** + * Convert any newslines in a string to
+ * . If input = null, returns null. + */ + public static String convertNewlines(String input) { + if (input != null) { + return input.replaceAll("[\n\r\f]", "
"); + } else { + return null; + } + } + + /** + * Strips HTML tags and leave "pure" text. Useful for CKeditor created text. + * + * @param text + * string to process + * @return string after stripping + */ + public static String removeHTMLtags(String text) { + return text == null ? null + : text.replaceAll(WebUtil.SPACE_TAG_REGEX, " ").replaceAll(WebUtil.HTML_TAG_REGEX, ""); + } + + /** + * Makes a request to the specified url with the specified parameters and returns the response inputstream + * + * @param urlStr + * @param params + * @return + * @throws ToolException + * @throws IOException + */ + public static InputStream getResponseInputStreamFromExternalServer(String urlStr, HashMap params) + throws IOException { + if (!urlStr.contains("?")) { + urlStr += "?"; + } + + for (Entry entry : params.entrySet()) { + urlStr += "&" + entry.getKey() + "=" + entry.getValue(); + } + + WebUtil.log.info("Making request to external servlet: " + urlStr); + + URL url = new URL(urlStr); + URLConnection conn = url.openConnection(); + if (!(conn instanceof HttpURLConnection)) { + WebUtil.log.error("Fail to connect to external server though url: " + urlStr); + throw new RuntimeException("Fail to connect to external server though url: " + urlStr); + } + + HttpURLConnection httpConn = (HttpURLConnection) conn; + if (httpConn.getResponseCode() != HttpURLConnection.HTTP_OK) { + WebUtil.log.error("Response code from external server: " + httpConn.getResponseCode() + " Url: " + urlStr); + } + + InputStream is = url.openConnection().getInputStream(); + if (is == null) { + WebUtil.log.error("Fail to fetch data from external server, return InputStream null: " + urlStr); + throw new RuntimeException("Fail to fetch data from external server, return inputStream null: " + urlStr); + } + + return is; + } + + public static String extractParameterValue(String url, String param) { + if (!StringUtils.isBlank(url) && !StringUtils.isBlank(param)) { + int quotationMarkIndex = url.indexOf("?"); + String queryPart = quotationMarkIndex > -1 ? url.substring(quotationMarkIndex + 1) : url; + String[] paramEntries = queryPart.split("&"); + for (String paramEntry : paramEntries) { + String[] paramEntrySplitted = paramEntry.split("="); + if ((paramEntrySplitted.length > 1) && param.equalsIgnoreCase(paramEntrySplitted[0])) { + return paramEntrySplitted[1]; + } + } + } + return null; + } + + /** + * Produces JSON object with basic user details. + */ + 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()); + userJSON.put("login", user.getLogin()); + userJSON.put("portraitId", user.getPortraitUuid() == null ? null : user.getPortraitUuid().toString()); + return userJSON; + } + + public static String getBaseServerURL() { + String serverURL = Configuration.get(ConfigurationKeys.SERVER_URL); + // "https://" is 8 characters, so next "/" should be context + return serverURL.substring(0, serverURL.indexOf('/', 9)); + } + + /** + * Converse lessonId into alphabetic sequence for using it in URL shortening + * + * @param lessonId + * @return + */ + public static String encodeLessonId(Long lessonId) { + String encodedLessonId = lessonId.toString(); + encodedLessonId = encodedLessonId.replace('0', URL_SHORTENING_CYPHER.charAt(0)); + encodedLessonId = encodedLessonId.replace('1', URL_SHORTENING_CYPHER.charAt(1)); + encodedLessonId = encodedLessonId.replace('2', URL_SHORTENING_CYPHER.charAt(2)); + encodedLessonId = encodedLessonId.replace('3', URL_SHORTENING_CYPHER.charAt(3)); + encodedLessonId = encodedLessonId.replace('4', URL_SHORTENING_CYPHER.charAt(4)); + encodedLessonId = encodedLessonId.replace('5', URL_SHORTENING_CYPHER.charAt(5)); + encodedLessonId = encodedLessonId.replace('6', URL_SHORTENING_CYPHER.charAt(6)); + encodedLessonId = encodedLessonId.replace('7', URL_SHORTENING_CYPHER.charAt(7)); + encodedLessonId = encodedLessonId.replace('8', URL_SHORTENING_CYPHER.charAt(8)); + encodedLessonId = encodedLessonId.replace('9', URL_SHORTENING_CYPHER.charAt(9)); + + return encodedLessonId; + } + + /** + * Decodes alphabetic sequence (that is lessonId encoded for URL shortening purposes) + * + * @param encodedlessonId + * @return + */ + public static String decodeLessonId(String encodedLessonId) throws IllegalArgumentException { + + // it should contain only the characters from URL_SHORTENING_CYPHER + if (!encodedLessonId.matches("[" + URL_SHORTENING_CYPHER + "]*")) { + throw new IllegalArgumentException("LessonId: " + encodedLessonId + " has wrong format."); + } + + String decodedLessonId = encodedLessonId; + decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(0), '0'); + decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(1), '1'); + decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(2), '2'); + decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(3), '3'); + decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(4), '4'); + decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(5), '5'); + decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(6), '6'); + decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(7), '7'); + decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(8), '8'); + decodedLessonId = decodedLessonId.replace(URL_SHORTENING_CYPHER.charAt(9), '9'); + + return decodedLessonId; + } + + public static Document getDocument() throws ParserConfigurationException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.newDocument(); + return document; + } + + public static String getStringFromDocument(Document document) throws TransformerException { + DOMSource domSource = new DOMSource(document); + StringWriter writer = new StringWriter(); + StreamResult result = new StreamResult(writer); + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer transformer = tf.newTransformer(); + transformer.transform(domSource, result); + return writer.toString(); + } } Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/CrNode.java =================================================================== diff -u -r1ee503e3d0e0228ea8a45025fddf15d9623c0377 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/CrNode.java (.../CrNode.java) (revision 1ee503e3d0e0228ea8a45025fddf15d9623c0377) +++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/CrNode.java (.../CrNode.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -21,7 +21,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.contentrepository; import java.io.Serializable; @@ -31,6 +30,7 @@ import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; +import java.util.UUID; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -57,6 +57,9 @@ @GeneratedValue(strategy = GenerationType.IDENTITY) private Long nodeId; + @Column(name = "portrait_uuid") + private UUID portraitUuid; + @Column private String path; @@ -69,18 +72,15 @@ @Column(name = "next_version_id") private Long nextVersionId; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "workspace_id") + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "workspace_id") private org.lamsfoundation.lams.contentrepository.CrWorkspace crWorkspace; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "parent_nv_id") + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "parent_nv_id") private org.lamsfoundation.lams.contentrepository.CrNodeVersion parentNodeVersion; - @OneToMany(mappedBy = "node", - cascade = CascadeType.ALL, - orphanRemoval = true, - fetch = FetchType.EAGER) + @OneToMany(mappedBy = "node", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER) private Set crNodeVersions; /** default constructor - used by Hibernate */ @@ -133,6 +133,14 @@ this.nodeId = nodeId; } + public UUID getPortraitUuid() { + return portraitUuid; + } + + public void setPortraitUuid(UUID portraitUuid) { + this.portraitUuid = portraitUuid; + } + public String getPath() { return this.path; } @@ -192,7 +200,7 @@ /** Add a version to this node */ public void addCrNodeVersion(CrNodeVersion version) { if (getCrNodeVersions() == null) { - Set set = new HashSet(); + Set set = new HashSet<>(); set.add(version); setCrNodeVersions(set); } else { @@ -264,12 +272,12 @@ * Get the history for this node. Quite intensive operation * as it has to build all the data structures. Can't cache * it as can't tell easily when the versions are changed. - * + * * @return SortedSet of IVersionDetail objects, ordered by version */ public SortedSet getVersionHistory() { - SortedSet history = new TreeSet(); + SortedSet history = new TreeSet<>(); Set versions = getCrNodeVersions(); if (versions != null) { @@ -285,7 +293,7 @@ /** * Indicates whether this node is of the specified node type. - * + * * @param nodeTypeName * the name of a node type. * @return true if this node is of the specified node type Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/IVersionedNode.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/IVersionedNode.java (.../IVersionedNode.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/IVersionedNode.java (.../IVersionedNode.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -21,7 +21,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.contentrepository; import java.io.InputStream; @@ -62,14 +61,14 @@ /** * Returns an Set of all child nodes of node. Returns an empty * set if no nodes found. - * + * * @return Set of nodes. */ public Set getChildNodes(); /** * Does this node have a parent node? - * + * * @return boolean */ public boolean hasParentNode(); @@ -120,6 +119,8 @@ */ public Long getUUID(); + public String getPortraitUuid(); + /** * Indicates whether a property exists for this name * Returns true if a property exists and false otherwise. @@ -211,23 +212,23 @@ /** * Get the date/time of when this node was created. - * + * * @return date/time stamp of creation */ public Date getCreatedDateTime(); /** * Get the file, as an inputstream. It is the responsibility * of the caller to close the stream. - * + * * If the node is a package node, it will get the input stream * of the first file. */ public InputStream getFile() throws FileException; /** * Get the user_id of the user who created this node. - * + * * @return userId */ public Integer getUserId(); Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/Download.java =================================================================== diff -u -r1e26200cec472e799b29f548270b1a67027e9167 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/Download.java (.../Download.java) (revision 1e26200cec472e799b29f548270b1a67027e9167) +++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/Download.java (.../Download.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -138,8 +138,6 @@ private void handleCall(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, RepositoryCheckedException { - long start = System.currentTimeMillis(); - ITicket ticket = null; String toolContentHandlerName = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_HANDLER_NAME); if (StringUtils.isBlank(toolContentHandlerName)) { @@ -152,18 +150,15 @@ throw new RepositoryCheckedException("Unable to get ticket - getTicket(false) returned null"); } - Long uuid = Download.getLong(request.getParameter(Download.UUID_NAME)); + String uuid = request.getParameter(Download.UUID_NAME); Long version = null; boolean saveFile = Download.getBoolean(request.getParameter(Download.PREFER_DOWNLOAD)); - String callId = null; - if (uuid != null) { version = Download.getLong(request.getParameter(Download.VERSION_NAME)); - - IVersionedNode node = getFileItem(ticket, uuid, version, null); - + IVersionedNode node = uuid.contains("-") ? getRepositoryService().getFileItem(ticket, uuid, version) + : getRepositoryService().getFileItem(ticket, Long.valueOf(uuid), version); // update versionId in case it was null and we got the latest version... version = node.getVersion(); @@ -200,12 +195,10 @@ // using the /download// format - must be a file node! String pathString = request.getPathInfo(); String[] strings = deriveIdFile(pathString); - uuid = Download.getLong(strings[0]); + uuid = strings[0]; version = Download.getLong(strings[1]); String relPathString = strings[2]; - callId = "download " + Math.random() + " " + uuid; - if (uuid == null) { throw new RepositoryCheckedException("UUID value is missing. " + Download.expectedFormat); } @@ -218,7 +211,8 @@ throw new RepositoryCheckedException("Filename is missing. " + Download.expectedFormat); } - IVersionedNode node = getFileItem(ticket, uuid, version, relPathString); + IVersionedNode node = uuid.contains("-") ? getRepositoryService().getFileItem(ticket, uuid, version) + : getRepositoryService().getFileItem(ticket, Long.valueOf(uuid), version); if (!node.isNodeType(NodeType.FILENODE)) { throw new RepositoryCheckedException( "Unexpected type of node " + node.getNodeType() + " Expected File node. Data is " + node); @@ -229,29 +223,6 @@ } /** - * The call getFileItem was throwing a runtime hibernate/jdbc error when being thrash tested, and I couldn't work - * out the context, so I've wrapped the call here so it can be debugged. - */ - private IVersionedNode getFileItem(ITicket ticket, Long uuid, Long version, String relPathString) - throws RepositoryCheckedException { - try { - IVersionedNode node = null; - if (relPathString != null) { - // get file in package - node = getRepositoryService().getFileItem(ticket, uuid, version, relPathString); - } else { - // get node - node = getRepositoryService().getFileItem(ticket, uuid, version); - } - return node; - } catch (RuntimeException e) { - Download.log.error("Exception thrown calling repository.getFileItem(," + uuid + "," + version + "," - + relPathString + "). " + e.getMessage(), e); - throw e; - } - } - - /** * @param response * @param aNode * @throws IOException Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/ToolContentHandler.java =================================================================== diff -u -r783f965b1bb2251474d01f32a53e4ccb28d5473b -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/ToolContentHandler.java (.../ToolContentHandler.java) (revision 783f965b1bb2251474d01f32a53e4ccb28d5473b) +++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/client/ToolContentHandler.java (.../ToolContentHandler.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.InputStream; +import java.util.UUID; import org.apache.log4j.Logger; import org.lamsfoundation.lams.contentrepository.ICredentials; @@ -172,16 +173,18 @@ } @Override - public NodeKey uploadFile(InputStream stream, String fileName, String mimeType) + public NodeKey uploadFile(InputStream stream, String fileName, String mimeType, boolean generatePortraitUuid) throws RepositoryCheckedException, InvalidParameterException, RepositoryCheckedException { NodeKey nodeKey = null; try { try { - nodeKey = repositoryService.addFileItem(getTicket(false), stream, fileName, mimeType, null); + nodeKey = repositoryService.addFileItem(getTicket(false), stream, fileName, mimeType, null, + generatePortraitUuid); } catch (AccessDeniedException e) { log.warn("Unable to access repository to add file " + fileName + "AccessDeniedException: " + e.getMessage() + " Retrying login."); - nodeKey = repositoryService.addFileItem(getTicket(true), stream, fileName, mimeType, null); + nodeKey = repositoryService.addFileItem(getTicket(true), stream, fileName, mimeType, null, + generatePortraitUuid); } } catch (RepositoryCheckedException e2) { @@ -194,6 +197,12 @@ } @Override + public NodeKey uploadFile(InputStream stream, String fileName, String mimeType) + throws RepositoryCheckedException, InvalidParameterException, RepositoryCheckedException { + return uploadFile(stream, fileName, mimeType, false); + } + + @Override public NodeKey updateFile(Long uuid, InputStream stream, String fileName, String mimeType) throws RepositoryCheckedException, InvalidParameterException, RepositoryCheckedException { NodeKey nodeKey = null; @@ -353,6 +362,25 @@ } @Override + public void deleteFile(UUID portraitUuid) throws InvalidParameterException, RepositoryCheckedException { + try { + try { + repositoryService.deleteNode(getTicket(false), portraitUuid); + } catch (AccessDeniedException e) { + log.warn("Unable to access repository to delete file id" + portraitUuid + "AccessDeniedException: " + + e.getMessage() + " Retrying login."); + repositoryService.deleteNode(getTicket(true), portraitUuid); + } + } catch (ItemNotFoundException e1) { + // didn't exist so don't need to delete. Ignore problem. + } catch (RepositoryCheckedException e2) { + log.error("Unable delete file id" + portraitUuid + "Repository Exception: " + e2.getMessage() + + " Retry not possible."); + throw e2; + } + } + + @Override public InputStream getFileInputStream(Long uuid) throws ItemNotFoundException, FileException, RepositoryCheckedException { try { Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/INodeFactory.java =================================================================== diff -u -rea80430beb4497f12c92db2580341f21750a5a43 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/INodeFactory.java (.../INodeFactory.java) (revision ea80430beb4497f12c92db2580341f21750a5a43) +++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/INodeFactory.java (.../INodeFactory.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -21,10 +21,10 @@ * **************************************************************** */ - package org.lamsfoundation.lams.contentrepository.service; import java.io.InputStream; +import java.util.UUID; import org.lamsfoundation.lams.contentrepository.CrNode; import org.lamsfoundation.lams.contentrepository.CrWorkspace; @@ -43,7 +43,7 @@ /** * Create a new file node (which is assumed to be a newly created Spring * bean) with relPath and node type. - * + * * @param relPath * The path of the new Node that is to be created, * the last item of this path will be the name of the new Node. @@ -54,12 +54,13 @@ */ public abstract SimpleVersionedNode createFileNode(CrWorkspace workspace, SimpleVersionedNode parentNode, String relPath, InputStream istream, String filename, String mimeType, String versionDescription, - Integer userId) throws org.lamsfoundation.lams.contentrepository.exception.InvalidParameterException; + Integer userId, boolean generatePortraitUuid) + throws org.lamsfoundation.lams.contentrepository.exception.InvalidParameterException; /** * Create a new package node (which is assumed to be a newly created Spring * bean) with the default file and node type. Package node cannot have a parent node. - * + * * @param initialPath * The path of the default content. * @throws org.lamsfoundation.lams.contentrepository.exception.InvalidParameterException @@ -74,7 +75,7 @@ /** * Create a new data node (which is assumed to be a newly created Spring * bean). This node may have a parent node. - * + * * @throws org.lamsfoundation.lams.contentrepository.exception.InvalidParameterException * if the file parameters are invalid * @throws RepositoryRuntimeException @@ -87,7 +88,7 @@ /** * Build a SimpleVersionedNode, given a CrNode from the database. If versionId == null * then gets the latest version. - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#getNode(String relPath) */ public abstract SimpleVersionedNode getNode(CrNode databaseNode, Long versionId); @@ -97,17 +98,20 @@ * Creates the CrNode and CrNodeVersion objects. * Equivalent of createFileNode/createPackageNode for existing nodes * Checks that the workspace found in the database is the expected workspace. - * + * * If this node object is returned to a web app, then the * crNode and crNodeVersion objects will be disconnected * from the session, as the session will have been ended * with the Spring transaction. - * + * * If versionId is null, then gets the latest version */ public abstract SimpleVersionedNode getNode(Long workspaceId, Long uuid, Long versionId) throws ItemNotFoundException; + public abstract SimpleVersionedNode getNode(Long workspaceId, UUID portraitUuid, Long versionId) + throws ItemNotFoundException; + /** * Build a SimpleVersionedNode, reading the data from the database. * Creates a new (empty) version ready for updating. @@ -118,9 +122,9 @@ * crNode and crNodeVersion objects will be disconnected * from the session, as the session will have been ended * with the Spring transaction. - * + * * @throws ItemNotFoundException - * + * * @throws RepositoryRuntimeException * if an internal error occurs. * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#createNewVersion(java.lang.String, @@ -132,11 +136,11 @@ /** * Copy the supplied node/version to a new node. Does not copy the history * of the node. Copies any child nodes of the current version. All files are duplicated. - * + * * This method only works as we know that we have two levels of nodes - the * childNodes can't have their own childNodes. If this is no longer the case, * this method and SimpleVersionedNode.save() will need to be changed. - * + * * @throws FileException * will occur if there is a problem reading a file from the repository * @throws InvalidParameterException Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/IRepositoryService.java =================================================================== diff -u -rea80430beb4497f12c92db2580341f21750a5a43 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/IRepositoryService.java (.../IRepositoryService.java) (revision ea80430beb4497f12c92db2580341f21750a5a43) +++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/IRepositoryService.java (.../IRepositoryService.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -28,6 +28,7 @@ import java.util.List; import java.util.SortedMap; import java.util.SortedSet; +import java.util.UUID; import org.lamsfoundation.lams.contentrepository.CrWorkspace; import org.lamsfoundation.lams.contentrepository.ICredentials; @@ -170,7 +171,8 @@ * if any internal errors have occured */ public abstract NodeKey addFileItem(ITicket ticket, InputStream istream, String filename, String mimeType, - String versionDescription) throws FileException, AccessDeniedException, InvalidParameterException; + String versionDescription, boolean generatePortraitUuid) + throws FileException, AccessDeniedException, InvalidParameterException; /** * Add a new package of files to the repository. If startFile @@ -329,6 +331,9 @@ public abstract IVersionedNode getFileItem(ITicket ticket, Long uuid, Long version) throws AccessDeniedException, ItemNotFoundException, FileException; + IVersionedNode getFileItem(ITicket ticket, String portraitUuid, Long version) + throws AccessDeniedException, ItemNotFoundException, FileException; + /** * Get an item from the repository based on the UUID and relative * path. Only used to get the content from a package. The @@ -441,6 +446,9 @@ public String[] deleteNode(ITicket ticket, Long uuid) throws AccessDeniedException, InvalidParameterException, ItemNotFoundException; + public String[] deleteNode(ITicket ticket, UUID portraitUuid) + throws AccessDeniedException, InvalidParameterException, ItemNotFoundException; + /** * Finish using this ticket. No more updates may be used with this ticket * after logout(). Allows any resources to be freed. Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/NodeFactory.java =================================================================== diff -u -rc1c22cae1f9de439732bbb93eed949b583917af9 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/NodeFactory.java (.../NodeFactory.java) (revision c1c22cae1f9de439732bbb93eed949b583917af9) +++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/NodeFactory.java (.../NodeFactory.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -21,13 +21,14 @@ * **************************************************************** */ - package org.lamsfoundation.lams.contentrepository.service; import java.io.InputStream; import java.util.Date; import java.util.Iterator; +import java.util.List; import java.util.Set; +import java.util.UUID; import org.apache.log4j.Logger; import org.lamsfoundation.lams.contentrepository.CrNode; @@ -68,26 +69,26 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#createFileNode(org.lamsfoundation.lams. * contentrepository.CrWorkspace, org.lamsfoundation.lams.contentrepository.service.SimpleVersionedNode, * java.lang.String, java.io.InputStream, java.lang.String, java.lang.String, java.lang.String) */ @Override public SimpleVersionedNode createFileNode(CrWorkspace workspace, SimpleVersionedNode parentNode, String relPath, - InputStream istream, String filename, String mimeType, String versionDescription, Integer userId) - throws InvalidParameterException { + InputStream istream, String filename, String mimeType, String versionDescription, Integer userId, + boolean generatePortraitUuid) throws InvalidParameterException { SimpleVersionedNode initialNodeVersion = createBasicNode(NodeType.FILENODE, workspace, parentNode, relPath, - versionDescription, userId); + versionDescription, userId, generatePortraitUuid); initialNodeVersion.setFile(istream, filename, mimeType); return initialNodeVersion; } /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#createPackageNode(org.lamsfoundation.lams. * contentrepository.CrWorkspace, java.lang.String, java.lang.String) */ @@ -96,15 +97,15 @@ Integer userId) throws org.lamsfoundation.lams.contentrepository.exception.InvalidParameterException { SimpleVersionedNode initialNodeVersion = createBasicNode(NodeType.PACKAGENODE, workspace, null, null, - versionDescription, userId); + versionDescription, userId, false); initialNodeVersion.setProperty(PropertyName.INITIALPATH, initialPath); return initialNodeVersion; } /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#createDataNode(org.lamsfoundation.lams. * contentrepository.CrWorkspace, org.lamsfoundation.lams.contentrepository.service.SimpleVersionedNode, * java.lang.String) @@ -115,21 +116,24 @@ throws org.lamsfoundation.lams.contentrepository.exception.InvalidParameterException { SimpleVersionedNode initialNodeVersion = createBasicNode(NodeType.DATANODE, workspace, parentNode, null, - versionDescription, userId); + versionDescription, userId, false); return initialNodeVersion; } /** Create the core part of a node */ private SimpleVersionedNode createBasicNode(String nodeType, CrWorkspace workspace, SimpleVersionedNode parentNode, - String relPath, String versionDescription, Integer userId) { + String relPath, String versionDescription, Integer userId, boolean generatePortraitUuid) { SimpleVersionedNode initialNodeVersion = beanFactory.getBean("node", SimpleVersionedNode.class); Date createdDate = new Date(System.currentTimeMillis()); CrNodeVersion parentNodeVersion = parentNode != null ? parentNode.getNodeVersion() : null; CrNode node = new CrNode(relPath, nodeType, createdDate, userId, workspace, parentNodeVersion, versionDescription); + if (generatePortraitUuid) { + node.setPortraitUuid(UUID.randomUUID()); + } CrNodeVersion nodeVersion = node.getNodeVersion(null); initialNodeVersion.setNode(node); @@ -144,7 +148,7 @@ /* * (non-Javadoc) - * + * * @see * org.lamsfoundation.lams.contentrepository.service.INodeFactory#getNode(org.lamsfoundation.lams.contentrepository. * CrNode, java.lang.Long) @@ -159,7 +163,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#getNode(java.lang.Long, java.lang.Long, * java.lang.Long) */ @@ -176,7 +180,7 @@ CrNode node = null; - node = (CrNode) nodeDAO.find(CrNode.class, uuid); + node = nodeDAO.find(CrNode.class, uuid); if (node == null) { throw new ItemNotFoundException("Node " + uuid + " not found."); @@ -192,9 +196,39 @@ return getNode(node, versionId); } + @Override + public SimpleVersionedNode getNode(Long workspaceId, UUID portraitUuid, Long versionId) + throws ItemNotFoundException { + + if (portraitUuid == null) { + throw new ItemNotFoundException("UUID is null, unable to find node."); + } + + if (workspaceId == null) { + throw new ItemNotFoundException("Workspace Id is null, unable to find node."); + } + + CrNode node = null; + List result = nodeDAO.findByProperty(CrNode.class, "portraitUuid", portraitUuid); + node = result.isEmpty() ? null : result.get(0); + if (node == null) { + + throw new ItemNotFoundException("Node " + portraitUuid + " not found."); + + } else if (!workspaceId.equals(node.getCrWorkspace().getWorkspaceId())) { + + log.error("Security warning. User of workspace " + workspaceId + " is trying to access node " + portraitUuid + + " which is in workspace " + node.getCrWorkspace().getWorkspaceId() + + " Request for node will be rejected."); + throw new ItemNotFoundException("Node " + portraitUuid + " does not exist in workspace " + workspaceId); + } + + return getNode(node, versionId); + } + /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#getNode(java.lang.Long, java.lang.Long, * java.lang.Long, java.lang.String) */ @@ -220,7 +254,7 @@ /* * (non-Javadoc) - * + * * @see * org.lamsfoundation.lams.contentrepository.service.INodeFactory#copy(org.lamsfoundation.lams.contentrepository. * service.SimpleVersionedNode) @@ -235,7 +269,7 @@ /** * Private method to handle the recursive copy. The parent node is needed to set up the * node -> parent link in the CrNode object. - * + * * @param originalNode * @param parentNode * @return new Node @@ -268,7 +302,7 @@ } } - // copy any attached file. don't actually copy the file - set up + // copy any attached file. don't actually copy the file - set up // and input stream and the file will be copied when the node is saved. // this is likely to recopy the Filename and Mimetype properties. if (originalNode.isNodeType(NodeType.FILENODE)) { @@ -300,7 +334,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#getNodeDAO() */ @Override @@ -310,7 +344,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.service.INodeFactory#setNodeDAO(org.lamsfoundation.lams. * contentrepository.dao.INodeDAO) */ @@ -322,7 +356,7 @@ /* **** Method for BeanFactoryAware interface *****************/ /* * (non-Javadoc) - * + * * @see * org.lamsfoundation.lams.contentrepository.service.INodeFactory#setBeanFactory(org.springframework.beans.factory. * BeanFactory) Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/SimpleRepository.java =================================================================== diff -u -rea80430beb4497f12c92db2580341f21750a5a43 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/SimpleRepository.java (.../SimpleRepository.java) (revision ea80430beb4497f12c92db2580341f21750a5a43) +++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/SimpleRepository.java (.../SimpleRepository.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -21,7 +21,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.contentrepository.service; import java.io.FileNotFoundException; @@ -37,6 +36,7 @@ import java.util.SortedMap; import java.util.SortedSet; import java.util.TreeMap; +import java.util.UUID; import javax.servlet.http.HttpSession; @@ -87,7 +87,7 @@ * run separately and without suitable AOP support then * each transaction method must check that the credential is okay * or that the ticket is a known ticket (isTicketOkay() method). - * + * * This class also depends on the transactions defined in the * application context for the hibernate sessions to work properly. * If the method isn't transactioned, then there won't be a proper @@ -134,10 +134,10 @@ } return user.getUserID(); } - throw new AccessDeniedException( - "Cannot get user details for content repository. No session found - user not logged in or the webservice call has not set up the session details."); + throw new AccessDeniedException( + "Cannot get user details for content repository. No session found - user not logged in or the webservice call has not set up the session details."); - } + } /** * @param workspaceId @@ -155,7 +155,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IRepository#login(org.lamsfoundation.lams.contentrepository. * ICredentials, java.lang.String) */ @@ -182,7 +182,7 @@ } // okay, we should now be able to create a ticket - // make ticket, create new credentials without the password + // make ticket, create new credentials without the password ITicket ticket = new SimpleTicket(workspace.getWorkspaceId()); ticketIdSet.add(ticket.getTicketId()); return ticket; @@ -191,7 +191,7 @@ /** * Add a workspace, giving the credentials as the user of this workspace. * It does not clear the password in the credentials - * + * * @param credentials * this user/password must already exist in the repository. Password will be checked. * @param workspaceName @@ -266,7 +266,7 @@ * The password must be at least 6 chars. * Possibly this should only be available to an internal management tool * *** Security Risk - I'm converting the password to a string... *** - * + * * @throws LoginException * if the oldCredential fails login test (e.g. wrong password) * @throws RepositoryCheckedException @@ -304,9 +304,9 @@ /** * Checks that a password meets our password criteria. This could be implemented * as a Strategy, but that's overkill! - * + * * Checks that the password is six or more characters. - * + * * @param password * @throws RepositoryCheckedException * if @@ -404,7 +404,7 @@ /* * (non-Javadoc) - * + * * @see * org.lamsfoundation.lams.contentrepository.IRepository#logout(org.lamsfoundation.lams.contentrepository.ITicket) */ @@ -426,19 +426,20 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IRepository#addFileItem(org.lamsfoundation.lams.contentrepository. * ITicket, java.io.InputStream, java.lang.String, java.lang.String, java.lang.String) */ @Override public NodeKey addFileItem(ITicket ticket, InputStream istream, String filename, String mimeType, - String versionDescription) throws FileException, AccessDeniedException, InvalidParameterException { + String versionDescription, boolean generatePortraitUUid) + throws FileException, AccessDeniedException, InvalidParameterException { try { CrWorkspace workspace = getWorkspace(ticket.getWorkspaceId()); Integer userId = getCurrentUserId(); SimpleVersionedNode initialNodeVersion = nodeFactory.createFileNode(workspace, null, null, istream, - filename, mimeType, versionDescription, userId); + filename, mimeType, versionDescription, userId, generatePortraitUUid); initialNodeVersion.save(); return initialNodeVersion.getNodeKey(); } catch (ValidationException e) { @@ -452,7 +453,7 @@ /* * (non-Javadoc) - * + * * @see * org.lamsfoundation.lams.contentrepository.IRepository#addPackageItem(org.lamsfoundation.lams.contentrepository. * ITicket, java.lang.String, java.lang.String, java.lang.String) @@ -486,7 +487,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IRepository#getFileItem(org.lamsfoundation.lams.contentrepository. * ITicket, java.lang.Long, java.lang.Long) */ @@ -497,9 +498,15 @@ return nodeFactory.getNode(ticket.getWorkspaceId(), uuid, version); } + @Override + public IVersionedNode getFileItem(ITicket ticket, String portraitUuid, Long version) + throws AccessDeniedException, ItemNotFoundException, FileException { + return nodeFactory.getNode(ticket.getWorkspaceId(), UUID.fromString(portraitUuid), version); + } + /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IRepository#getFileItem(org.lamsfoundation.lams.contentrepository. * ITicket, java.lang.Long, java.lang.Long, java.lang.String) */ @@ -530,7 +537,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IRepository#getFileItem(org.lamsfoundation.lams.contentrepository. * ITicket, java.lang.Long, java.lang.Long, java.lang.String) */ @@ -556,7 +563,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IRepository#getNodeList(org.lamsfoundation.lams.contentrepository. * ITicket) */ @@ -582,7 +589,7 @@ /* * (non-Javadoc) - * + * * @see * org.lamsfoundation.lams.contentrepository.IRepository#getVersionHistory(org.lamsfoundation.lams.contentrepository * .ITicket, java.lang.Long) @@ -596,7 +603,7 @@ /* * (non-Javadoc) - * + * * @see * org.lamsfoundation.lams.contentrepository.IRepository#updateFileItem(org.lamsfoundation.lams.contentrepository. * ITicket, java.lang.Long, java.lang.String, java.io.InputStream, java.lang.String, java.lang.String) @@ -627,7 +634,7 @@ /* * (non-Javadoc) - * + * * @see * org.lamsfoundation.lams.contentrepository.IRepository#updatePackageItem(org.lamsfoundation.lams.contentrepository * .ITicket, java.lang.Long, java.lang.String, java.lang.String, java.lang.String) @@ -690,7 +697,7 @@ /* * (non-Javadoc) - * + * * @see * org.lamsfoundation.lams.contentrepository.IRepository#copyNodeVersion(org.lamsfoundation.lams.contentrepository. * ITicket, java.lang.Long, java.lang.Long) @@ -723,7 +730,7 @@ /* * (non-Javadoc) - * + * * @see * org.lamsfoundation.lams.contentrepository.IRepository#saveFile(org.lamsfoundation.lams.contentrepository.ITicket, * java.lang.Long, java.lang.String, java.lang.String, java.lang.String) @@ -804,7 +811,7 @@ /* * (non-Javadoc) - * + * * @see * org.lamsfoundation.lams.contentrepository.IRepository#updatePackageItem(org.lamsfoundation.lams.contentrepository * .ITicket, java.lang.Long, java.lang.String, java.lang.String, java.lang.String) @@ -828,9 +835,28 @@ } + @Override + public String[] deleteNode(ITicket ticket, UUID portraitUuid) + throws AccessDeniedException, InvalidParameterException, ItemNotFoundException { + + if (portraitUuid == null) { + throw new InvalidParameterException("UUID is required for deleteItem."); + } + + // get the first version of the node and delete from there. + SimpleVersionedNode latestNodeVersion = nodeFactory.getNode(ticket.getWorkspaceId(), portraitUuid, new Long(1)); + if (latestNodeVersion.hasParentNode()) { + throw new InvalidParameterException("You cannot delete a node that is in a package (ie has a parent). " + + "Please delete the parent. Node UUID " + portraitUuid); + } + List problemPaths = latestNodeVersion.deleteNode(); + return problemPaths != null ? (String[]) problemPaths.toArray(new String[problemPaths.size()]) : new String[0]; + + } + /* * (non-Javadoc) - * + * * @see * org.lamsfoundation.lams.contentrepository.IRepository#updatePackageItem(org.lamsfoundation.lams.contentrepository * .ITicket, java.lang.Long, java.lang.String, java.lang.String, java.lang.String) @@ -850,10 +876,12 @@ } + @Override public boolean workspaceExists(ICredentials credentials, Long workspaceId) { return workspaceDAO.find(CrWorkspace.class, workspaceId) != null; } + @Override public boolean workspaceExists(ICredentials credentials, String workspaceName) { return workspaceDAO.findByName(workspaceName) != null; } Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/SimpleVersionedNode.java =================================================================== diff -u -rc1c22cae1f9de439732bbb93eed949b583917af9 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/SimpleVersionedNode.java (.../SimpleVersionedNode.java) (revision c1c22cae1f9de439732bbb93eed949b583917af9) +++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/service/SimpleVersionedNode.java (.../SimpleVersionedNode.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -21,7 +21,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.contentrepository.service; import java.io.ByteArrayInputStream; @@ -145,12 +144,12 @@ @Override public NodeKey getNodeKey() { - return new NodeKey(getUUID(), getVersion()); + return new NodeKey(getUUID(), getVersion(), getPortraitUuid()); } /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, java.lang.String, * int) */ @@ -162,7 +161,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, java.lang.String) */ @Override @@ -173,7 +172,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, boolean) */ @Override @@ -184,7 +183,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, double) */ @Override @@ -195,7 +194,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, long) */ @Override @@ -206,7 +205,7 @@ /* * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#setProperty(java.lang.String, java.util.Calendar) */ @Override @@ -244,6 +243,12 @@ return node.getNodeId(); } + @Override + public String getPortraitUuid() { + nodeObjectInitilised("Unable to get portrait UUID"); + return node.getPortraitUuid() == null ? null : node.getPortraitUuid().toString(); + } + /** * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#hasProperty(java.lang.String) */ @@ -273,7 +278,7 @@ /** * (non-Javadoc) - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#isNodeType(java.lang.String) */ @Override @@ -286,7 +291,7 @@ * Get the history for this node. Quite intensive operation * as it has to build all the data structures. Can't be easily * cached. - * + * * @return SortedSet of IVersionDetail objects, ordered by version */ @Override @@ -382,7 +387,7 @@ * of the caller to close the stream. Note: this should only be * called once the node is saved - do not call it directly after * setting the file stream - * + * * If the node is a package node, it will get the input stream * of the first file. */ @@ -418,7 +423,7 @@ /** * Set the file, passed in as an inputstream. The stream will be closed * when the file is saved. Only nodes of type FILENODE can have a file! - * + * * @param iStream * mandatory * @param filename @@ -494,7 +499,7 @@ * we could just be doing a setProperty save, in which case the file * will already exist. *
  • Package nodes must not have a file, must have a INITIALPATH property - * + * * @throws ValidationException * if problems exist. */ @@ -557,19 +562,19 @@ * Save the changes to this node. This method must be called when saving a file * or package node for the first time - it does both the database and the file * saves. - * + * * If it is a file node, then it writes out the db changes and then saves * the file. - * + * * If is is a package node, then it writes out the db changes for all the nodes, * then saves all the file. Why do it this way - we want to do all the file * changes at the end as they cannot be rolled back if there is a db error. - * + * * This method only works as we know that we have two levels of nodes - the * childNodes can't have their own childNodes. If this is no longer the case, * this method and copy() will need to be changed. - * * + * * TODO This needs a lot of testing */ protected Long save() throws ValidationException, FileException { @@ -631,7 +636,8 @@ : element.getFilePath(); } else { failedDeleted = failedDeleted != null - ? failedDeleted + File.pathSeparator + element.getFilePath() : element.getFilePath(); + ? failedDeleted + File.pathSeparator + element.getFilePath() + : element.getFilePath(); } } String msg = "Result of rolling back file changes:"; @@ -683,7 +689,7 @@ /** * Write the file out (if one exists). Sets the private attribute filePath. - * + * * @return the path to which the file was written */ private void writeFile() throws FileException { @@ -711,7 +717,7 @@ /** * Another case for the factory? - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#getNode(String relPath) */ @Override @@ -735,7 +741,7 @@ /** * If no nodes are found, returns an empty set. - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNode#getChildNodes() */ @Override @@ -798,13 +804,13 @@ /** * Delete all versions of this node, returning the number of nodes * deleted. If it is a package node, all child nodes will be deleted. - * + * * @see org.lamsfoundation.lams.contentrepository.IVersionedNodeAdmin#deleteNode() */ @Override public List deleteNode() { - // first make a list of all the versions to delete. + // first make a list of all the versions to delete. // don't iterate over the set, deleting as we go so that // we can't run into any issues trying to access something // that is deleted or belongs to an iterator. @@ -838,7 +844,7 @@ // doing file system changes if the db would fail later. deleteVersionFromDB(nodeKeysDeleted); - // now delete the files. If it fails due to the file not being found, then + // now delete the files. If it fails due to the file not being found, then // that's fine. ArrayList failedList = new ArrayList(); Iterator iter = nodeKeysDeleted.iterator(); @@ -906,7 +912,7 @@ /** * Process files in the package. Create a List of file nodes but do not persist * the nodes. - * + * * @param dirPath: * the directory from which to get files. Mandatory. * @param packageNode: @@ -1001,7 +1007,7 @@ // no need to the new node as a child node, as createFileNode will do it. FileInputStream istream = new FileInputStream(file); nodeFactory.createFileNode(workspace, this, relPath, istream, filename, null, versionDescription, - userId); + userId, false); } } @@ -1025,11 +1031,11 @@ /** * Copy the supplied node/version to a new node. Does not copy the history * of the node. Copies any child nodes of the current version. All files are duplicated. - * + * * This method only works as we know that we have two levels of nodes - the * childNodes can't have their own childNodes. If this is no longer the case, * this method and SimpleVersionedNode.save() will need to be changed. - * + * * @throws FileException * will occur if there is a problem reading a file from the repository * @throws InvalidParameterException Index: lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/dto/GBUserGridRowDTO.java =================================================================== diff -u -rfd2cfad55c7c517931f69334ce644d509ec28140 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/dto/GBUserGridRowDTO.java (.../GBUserGridRowDTO.java) (revision fd2cfad55c7c517931f69334ce644d509ec28140) +++ lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/dto/GBUserGridRowDTO.java (.../GBUserGridRowDTO.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -41,7 +41,7 @@ private String lastName; private String login; private String currentActivity; - private Long portraitId; + private String portraitId; private boolean hasArchivedMarks; @@ -54,12 +54,12 @@ this.firstName = user.getFirstName(); this.lastName = user.getLastName(); this.login = user.getLogin(); - this.setPortraitId(user.getPortraitUuid()); + this.setPortraitId(user.getPortraitUuid() == null ? null : user.getPortraitUuid().toString()); } @Override public ArrayList toStringArray(GBGridView view) { - ArrayList ret = new ArrayList(); + ArrayList ret = new ArrayList<>(); ret.add(id.toString()); @@ -150,11 +150,11 @@ this.currentActivity = currentActivity; } - public Long getPortraitId() { + public String getPortraitId() { return portraitId; } - public void setPortraitId(Long portraitId) { + public void setPortraitId(String portraitId) { this.portraitId = portraitId; } Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentResultDAOHibernate.java =================================================================== diff -u -r02ce40b60524aa33d326fbda824dcd43f566ab94 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentResultDAOHibernate.java (.../AssessmentResultDAOHibernate.java) (revision 02ce40b60524aa33d326fbda824dcd43f566ab94) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentResultDAOHibernate.java (.../AssessmentResultDAOHibernate.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -258,15 +258,15 @@ @Override public List getLastFinishedAssessmentResultsBySession(Long sessionId) { - final String FIND_LAST_FINISHED_RESULTS_BY_SESSION_ID = "SELECT r, u.portraitUuid FROM " + AssessmentResult.class.getName() + final String FIND_LAST_FINISHED_RESULTS_BY_SESSION_ID = "SELECT r, BIN_TO_UUID(u.portraitUuid) FROM " + AssessmentResult.class.getName() + " AS r, " + User.class.getName() + " as u WHERE r.sessionId=? AND (r.finishDate != null) AND r.latest=1 AND u.userId=r.user.userId"; return (List) doFind(FIND_LAST_FINISHED_RESULTS_BY_SESSION_ID, new Object[] { sessionId }); } @Override public List getLeadersLastFinishedAssessmentResults(Long contentId) { - final String FIND_LAST_FINISHED_RESULTS_BY_SESSION_ID = "SELECT r, u.portraitUuid FROM " + AssessmentResult.class.getName() + final String FIND_LAST_FINISHED_RESULTS_BY_SESSION_ID = "SELECT r, BIN_TO_UUID(u.portraitUuid) FROM " + AssessmentResult.class.getName() + " AS r, " + User.class.getName() + " as u WHERE r.user=r.user.session.groupLeader AND r.assessment.contentId=? AND (r.finishDate != null) AND r.latest=1 AND u.userId=r.user.userId"; return (List) doFind(FIND_LAST_FINISHED_RESULTS_BY_SESSION_ID, new Object[] { contentId }); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentUserDAOHibernate.java =================================================================== diff -u -rb41c8a8bc5134e78088378360a37f3906fadb3de -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentUserDAOHibernate.java (.../AssessmentUserDAOHibernate.java) (revision b41c8a8bc5134e78088378360a37f3906fadb3de) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentUserDAOHibernate.java (.../AssessmentUserDAOHibernate.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -25,6 +25,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.UUID; import org.hibernate.query.NativeQuery; import org.hibernate.query.Query; @@ -50,12 +51,12 @@ private static final String FIND_MARK_STATS_FOR_SESSION = "SELECT MIN(grade) min_grade, AVG(grade) avg_grade, MAX(grade) max_grade FROM tl_laasse10_assessment_result " + " WHERE finish_date IS NOT NULL AND latest = 1 AND session_id = :sessionId"; - private static final String LOAD_MARKS_FOR_LEADERS = "SELECT r.grade FROM tl_laasse10_assessment_result r " + private static final String LOAD_MARKS_FOR_LEADERS = "SELECT r.grade FROM tl_laasse10_assessment_result r " + " JOIN tl_laasse10_session s ON r.session_id = s.session_id AND r.user_uid = s.group_leader_uid " + " JOIN tl_laasse10_assessment a ON s.assessment_uid = a.uid " + " WHERE r.finish_date IS NOT NULL AND r.latest = 1 AND a.content_id = :toolContentId"; private static final String FIND_MARK_STATS_FOR_LEADERS = "SELECT MIN(grade) min_grade, AVG(grade) avg_grade, MAX(grade) max_grade, COUNT(grade) num_complete " - + " FROM tl_laasse10_assessment_result r " + + " FROM tl_laasse10_assessment_result r " + " JOIN tl_laasse10_session s ON r.session_id = s.session_id AND r.user_uid = s.group_leader_uid " + " JOIN tl_laasse10_assessment a ON s.assessment_uid = a.uid " + " WHERE r.finish_date IS NOT NULL AND r.latest = 1 AND a.content_id = :toolContentId"; @@ -98,16 +99,16 @@ @Override @SuppressWarnings("unchecked") public List getBySessionID(Long sessionId) { - return (List) this.doFind(FIND_BY_SESSION_ID, sessionId); + return this.doFind(FIND_BY_SESSION_ID, sessionId); } private static String LOAD_USERS_ORDERED_BY_SESSION_SELECT = "SELECT DISTINCT user.user_id, user.last_name, user.first_name, user.login_name, result.grade "; private static String LOAD_USERS_ORDERED_BY_SESSION_FROM = " FROM tl_laasse10_user user "; private static String LOAD_USERS_ORDERED_BY_SESSION_JOIN = " INNER JOIN tl_laasse10_session session" - + " ON user.session_uid=session.uid LEFT OUTER JOIN tl_laasse10_assessment_result result " - + " ON result.user_uid = user.uid AND result.finish_date IS NOT NULL" - + " AND result.latest = 1 WHERE session.session_id = :sessionId " - + " AND (CONCAT(user.last_name, ' ', user.first_name) LIKE CONCAT('%', :searchString, '%')) "; + + " ON user.session_uid=session.uid LEFT OUTER JOIN tl_laasse10_assessment_result result " + + " ON result.user_uid = user.uid AND result.finish_date IS NOT NULL" + + " AND result.latest = 1 WHERE session.session_id = :sessionId " + + " AND (CONCAT(user.last_name, ' ', user.first_name) LIKE CONCAT('%', :searchString, '%')) "; private static String LOAD_USERS_ORDERED_ORDER_BY_NAME = "ORDER BY (CONCAT(user.last_name, ' ', user.first_name)) "; private static String LOAD_USERS_ORDERED_ORDER_BY_TOTAL = "ORDER BY result.grade "; @@ -116,18 +117,17 @@ public List getPagedUsersBySession(Long sessionId, int page, int size, String sortBy, String sortOrder, String searchString, IUserManagementService userManagementService) { String[] portraitStrings = userManagementService.getPortraitSQL("user.user_id"); - - StringBuilder bldr = new StringBuilder(LOAD_USERS_ORDERED_BY_SESSION_SELECT) - .append(portraitStrings[0]) - .append(LOAD_USERS_ORDERED_BY_SESSION_FROM) - .append(portraitStrings[1]) + + StringBuilder bldr = new StringBuilder(LOAD_USERS_ORDERED_BY_SESSION_SELECT).append(portraitStrings[0]) + .append(LOAD_USERS_ORDERED_BY_SESSION_FROM).append(portraitStrings[1]) .append(LOAD_USERS_ORDERED_BY_SESSION_JOIN); - if ( "total".equalsIgnoreCase(sortBy) ) + if ("total".equalsIgnoreCase(sortBy)) { bldr.append(LOAD_USERS_ORDERED_ORDER_BY_TOTAL); - else + } else { bldr.append(LOAD_USERS_ORDERED_ORDER_BY_NAME); + } bldr.append(sortOrder); - + NativeQuery query = getSession().createNativeQuery(bldr.toString()); query.setParameter("sessionId", sessionId); // support for custom search from a toolbar @@ -137,7 +137,7 @@ query.setMaxResults(size); List list = query.list(); - ArrayList userDtos = new ArrayList(); + ArrayList userDtos = new ArrayList<>(); if (list != null && list.size() > 0) { for (Object[] element : list) { @@ -146,15 +146,15 @@ String lastName = (String) element[2]; String login = (String) element[3]; float grade = element[4] == null ? 0 : ((Number) element[4]).floatValue(); - Long portraitId = element[5] == null ? null : ((Number) element[5]).longValue(); + byte[] portraitId = (byte[]) element[5]; AssessmentUserDTO userDto = new AssessmentUserDTO(); userDto.setUserId(userId); userDto.setFirstName(firstName); userDto.setLastName(lastName); userDto.setLogin(login); userDto.setGrade(grade); - userDto.setPortraitId(portraitId); + userDto.setPortraitId(portraitId == null ? null : UUID.nameUUIDFromBytes(portraitId).toString()); userDtos.add(userDto); } @@ -183,7 +183,7 @@ return ((Number) list.get(0)).intValue(); } } - + @Override public int getCountUsersByContentId(Long contentId) { final String LOAD_USERS_ORDERED_BY_NAME = "SELECT COUNT(*) FROM " + AssessmentUser.class.getName() + " user" @@ -198,8 +198,7 @@ @Override public Object[] getStatsMarksBySession(Long sessionId) { Query query = getSession().createNativeQuery(FIND_MARK_STATS_FOR_SESSION) - .addScalar("min_grade", FloatType.INSTANCE) - .addScalar("avg_grade", FloatType.INSTANCE) + .addScalar("min_grade", FloatType.INSTANCE).addScalar("avg_grade", FloatType.INSTANCE) .addScalar("max_grade", FloatType.INSTANCE); query.setParameter("sessionId", sessionId); List list = query.list(); @@ -214,10 +213,8 @@ @Override public Object[] getStatsMarksForLeaders(Long toolContentId) { NativeQuery query = getSession().createNativeQuery(FIND_MARK_STATS_FOR_LEADERS) - .addScalar("min_grade", FloatType.INSTANCE) - .addScalar("avg_grade", FloatType.INSTANCE) - .addScalar("max_grade", FloatType.INSTANCE) - .addScalar("num_complete", IntegerType.INSTANCE); + .addScalar("min_grade", FloatType.INSTANCE).addScalar("avg_grade", FloatType.INSTANCE) + .addScalar("max_grade", FloatType.INSTANCE).addScalar("num_complete", IntegerType.INSTANCE); query.setParameter("toolContentId", toolContentId); List list = query.list(); if ((list == null) || (list.size() == 0)) { @@ -230,36 +227,36 @@ private static String LOAD_USERS_ORDERED_BY_SESSION_QUESTION_SELECT = "SELECT DISTINCT question_result.uid, user.last_name, user.first_name, user.login_name, question_result.mark"; private static String LOAD_USERS_ORDERED_BY_SESSION_QUESTION_FROM = " FROM tl_laasse10_user user"; private static String LOAD_USERS_ORDERED_BY_SESSION_QUESTION_JOIN = " INNER JOIN tl_laasse10_session session" - + " ON user.session_uid=session.uid" + + + " ON user.session_uid=session.uid" + - " LEFT OUTER JOIN tl_laasse10_assessment_result result " + " ON result.user_uid = user.uid" - + " AND result.finish_date IS NOT NULL" + " AND result.latest = 1" + + " LEFT OUTER JOIN tl_laasse10_assessment_result result " + " ON result.user_uid = user.uid" + + " AND result.finish_date IS NOT NULL" + " AND result.latest = 1" + - " INNER JOIN lams_qb_tool_answer qbToolAnswer " + " ON qbToolAnswer.tool_question_uid = :questionUid " + + " INNER JOIN lams_qb_tool_answer qbToolAnswer " + " ON qbToolAnswer.tool_question_uid = :questionUid " + - " INNER JOIN tl_laasse10_question_result question_result " + " ON result.uid=question_result.result_uid" - + " AND question_result.uid = qbToolAnswer.answer_uid" + + " INNER JOIN tl_laasse10_question_result question_result " + " ON result.uid=question_result.result_uid" + + " AND question_result.uid = qbToolAnswer.answer_uid" + - " WHERE session.session_id = :sessionId " - + " AND (CONCAT(user.last_name, ' ', user.first_name) LIKE CONCAT('%', :searchString, '%')) "; + " WHERE session.session_id = :sessionId " + + " AND (CONCAT(user.last_name, ' ', user.first_name) LIKE CONCAT('%', :searchString, '%')) "; private static String LOAD_USERS_ORDERED_ORDER_BY_RESULT = "ORDER BY question_result.mark "; @SuppressWarnings("unchecked") @Override public List getPagedUsersBySessionAndQuestion(Long sessionId, Long questionUid, int page, - int size, String sortBy, String sortOrder, String searchString, IUserManagementService userManagementService) { + int size, String sortBy, String sortOrder, String searchString, + IUserManagementService userManagementService) { String[] portraitStrings = userManagementService.getPortraitSQL("user.user_id"); - StringBuilder bldr = new StringBuilder(LOAD_USERS_ORDERED_BY_SESSION_QUESTION_SELECT) - .append(portraitStrings[0]) - .append(LOAD_USERS_ORDERED_BY_SESSION_QUESTION_FROM) - .append(portraitStrings[1]) + StringBuilder bldr = new StringBuilder(LOAD_USERS_ORDERED_BY_SESSION_QUESTION_SELECT).append(portraitStrings[0]) + .append(LOAD_USERS_ORDERED_BY_SESSION_QUESTION_FROM).append(portraitStrings[1]) .append(LOAD_USERS_ORDERED_BY_SESSION_QUESTION_JOIN); - if ( "grade".equalsIgnoreCase(sortBy) ) + if ("grade".equalsIgnoreCase(sortBy)) { bldr.append(LOAD_USERS_ORDERED_ORDER_BY_RESULT); - else + } else { bldr.append(LOAD_USERS_ORDERED_ORDER_BY_NAME); + } bldr.append(sortOrder); NativeQuery query = getSession().createNativeQuery(bldr.toString()); @@ -272,7 +269,7 @@ query.setMaxResults(size); List list = query.list(); - ArrayList userDtos = new ArrayList(); + ArrayList userDtos = new ArrayList<>(); if (list != null && list.size() > 0) { for (Object[] element : list) { @@ -281,16 +278,15 @@ String lastName = (String) element[2]; String login = (String) element[3]; float grade = element[4] == null ? 0 : ((Number) element[4]).floatValue(); - Long portraitId = element[5] == null ? null : ((Number) element[5]).longValue(); + byte[] portraitId = (byte[]) element[5]; AssessmentUserDTO userDto = new AssessmentUserDTO(); userDto.setQuestionResultUid(questionResultUid); - ; userDto.setFirstName(firstName); userDto.setLastName(lastName); userDto.setLogin(login); userDto.setGrade(grade); - userDto.setPortraitId(portraitId); + userDto.setPortraitId(portraitId == null ? null : UUID.nameUUIDFromBytes(portraitId).toString()); userDtos.add(userDto); } Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dto/AssessmentUserDTO.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dto/AssessmentUserDTO.java (.../AssessmentUserDTO.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dto/AssessmentUserDTO.java (.../AssessmentUserDTO.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -20,7 +20,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.tool.assessment.dto; public class AssessmentUserDTO { @@ -31,7 +30,7 @@ private float grade; private Long questionResultUid; - private Long portraitId; + private String portraitId; public String getFirstName() { return firstName; @@ -81,11 +80,11 @@ this.questionResultUid = questionResultUid; } - public Long getPortraitId() { + public String getPortraitId() { return portraitId; } - public void setPortraitId(Long portraitId) { + public void setPortraitId(String portraitId) { this.portraitId = portraitId; } Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java =================================================================== diff -u -r3bc5138bc98aae79d0c4c7dbbe2b12d42d029b3f -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 3bc5138bc98aae79d0c4c7dbbe2b12d42d029b3f) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -373,10 +373,10 @@ } @Override - public Long getPortraitId(Long userId) { + public String getPortraitId(Long userId) { if (userId != null) { User user = (User) userManagementService.findById(User.class, userId.intValue()); - return user != null ? user.getPortraitUuid() : null; + return user == null || user.getPortraitUuid() == null ? null : user.getPortraitUuid().toString(); } return null; } @@ -1393,7 +1393,7 @@ return questionSummary; } - + public static boolean isAnswersEqual(AssessmentQuestion question, String answer1, String answer2) { if (answer1 == null || answer2 == null) { return false; @@ -3065,8 +3065,7 @@ for (Object[] assessmentResultsAndPortraitIter : assessmentResultsAndPortraits) { AssessmentResult assessmentResult = (AssessmentResult) assessmentResultsAndPortraitIter[0]; - Long portraitUuid = assessmentResultsAndPortraitIter[1] == null ? null - : ((Number) assessmentResultsAndPortraitIter[1]).longValue(); + String portraitUuid = (String) assessmentResultsAndPortraitIter[1]; AssessmentUser user = assessmentResult.getUser(); //fill in question's and user answer's hashes @@ -3157,8 +3156,7 @@ for (Object[] assessmentResultsAndPortraitIter : assessmentResultsAndPortraits) { AssessmentResult assessmentResult = (AssessmentResult) assessmentResultsAndPortraitIter[0]; - Long portraitUuid = assessmentResultsAndPortraitIter[1] == null ? null - : ((Number) assessmentResultsAndPortraitIter[1]).longValue(); + String portraitUuid = (String) assessmentResultsAndPortraitIter[1]; AssessmentUser user = assessmentResult.getUser(); //fill in question's and user answer's hashes Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java =================================================================== diff -u -r731ac9bda6562e241a71eb71b18caeaa49aeefb5 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision 731ac9bda6562e241a71eb71b18caeaa49aeefb5) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -527,7 +527,7 @@ void releaseFromCache(Object object); - Long getPortraitId(Long userId); + String getPortraitId(Long userId); AssessmentQuestion getAssessmentQuestionByUid(Long questionUid); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java =================================================================== diff -u -r4a2902072e80bc9fcfd6534115751829210e2153 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 4a2902072e80bc9fcfd6534115751829210e2153) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -313,7 +313,7 @@ if (groupLeader != null) { float assessmentResult = service.getLastTotalScoreByUser(assessment.getUid(), groupLeader.getUserId()); - Long portraitId = service.getPortraitId(groupLeader.getUserId()); + String portraitId = service.getPortraitId(groupLeader.getUserId()); AssessmentUserDTO userDto = new AssessmentUserDTO(); userDto.setUserId(groupLeader.getUserId()); Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/LearningWebsocketServer.java =================================================================== diff -u -ra8bbaa43c079c2a25d1a81c234114e6103b046a5 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/LearningWebsocketServer.java (.../LearningWebsocketServer.java) (revision a8bbaa43c079c2a25d1a81c234114e6103b046a5) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/LearningWebsocketServer.java (.../LearningWebsocketServer.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -57,10 +57,10 @@ private String userName; private String nickName; private Long lamsUserId; - private Long portraitId; + private String portraitId; private String hash; - private Websocket(Session session, String nickName, Long lamsUserId, Long portraitId) { + private Websocket(Session session, String nickName, Long lamsUserId, String portraitId) { this.session = session; this.userName = session.getUserPrincipal().getName(); this.nickName = nickName; @@ -186,7 +186,7 @@ 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; @@ -199,11 +199,12 @@ * @throws JsonProcessingException */ private ArrayNode getRosterJSON() throws JsonProcessingException, IOException { - TreeMap localActiveUsers = new TreeMap<>(); + 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 String[] { websocket.lamsUserId.toString(), websocket.portraitId }); } // is it time to sync with the DB yet? @@ -218,7 +219,7 @@ // refresh current collection activeUsers.clear(); for (ChatUser activeUser : storedActiveUsers) { - activeUsers.put(activeUser.getNickname(), new Long[] { activeUser.getUserId(), + activeUsers.put(activeUser.getNickname(), new String[] { activeUser.getUserId().toString(), LearningWebsocketServer.getPortraitId(activeUser.getUserId()) }); } @@ -229,8 +230,8 @@ } ArrayNode rosterJSON = JsonNodeFactory.instance.arrayNode(); - for (Map.Entry entry : activeUsers.entrySet()) { - Long[] ids = entry.getValue(); + for (Map.Entry entry : activeUsers.entrySet()) { + String[] ids = entry.getValue(); ObjectNode userJSON = JsonNodeFactory.instance.objectNode().put("nickName", entry.getKey()) .put("lamsUserId", ids[0]).put("portraitId", ids[1]); rosterJSON.add(userJSON); @@ -412,12 +413,12 @@ return messagesJSON; } - private static Long getPortraitId(Long userId) { + private static String getPortraitId(Long userId) { if (userId != null) { User user = (User) LearningWebsocketServer.getUserManagementService().findById(User.class, userId.intValue()); - if (user != null) { - return user.getPortraitUuid(); + if (user != null && user.getPortraitUuid() != null) { + return user.getPortraitUuid().toString(); } } return null; Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dao/hibernate/McUsrAttemptDAO.java =================================================================== diff -u -r02ce40b60524aa33d326fbda824dcd43f566ab94 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dao/hibernate/McUsrAttemptDAO.java (.../McUsrAttemptDAO.java) (revision 02ce40b60524aa33d326fbda824dcd43f566ab94) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dao/hibernate/McUsrAttemptDAO.java (.../McUsrAttemptDAO.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -85,7 +85,7 @@ @Override public List getFinalizedAttemptsBySessionId(final Long sessionId) { - final String LOAD_QUESTION_ATTEMPTS_BY_SESSION_ID = "SELECT attempt, u.portraitUuid FROM " + final String LOAD_QUESTION_ATTEMPTS_BY_SESSION_ID = "SELECT attempt, BIN_TO_UUID(u.portraitUuid) FROM " + McUsrAttempt.class.getName() + " AS attempt, " + User.class.getName() + " as u WHERE attempt.mcQueUsr.mcSession.mcSessionId=:sessionId" + " AND attempt.mcQueUsr.responseFinalised = true AND u.userId=attempt.mcQueUsr.queUsrId"; @@ -96,7 +96,7 @@ @Override public List getLeadersFinalizedAttemptsByContentId(final Long contentId) { - final String LOAD_QUESTION_ATTEMPTS_BY_SESSION_ID = "SELECT attempt, u.portraitUuid FROM " + final String LOAD_QUESTION_ATTEMPTS_BY_SESSION_ID = "SELECT attempt, BIN_TO_UUID(u.portraitUuid) FROM " + McUsrAttempt.class.getName() + " AS attempt, " + User.class.getName() + " as u WHERE attempt.mcQueUsr=attempt.mcQueUsr.mcSession.groupLeader " + " AND attempt.mcQueContent.mcContent.mcContentId=:contentId " Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/service/IMcService.java =================================================================== diff -u -r5ebec80ccc488d5c09da8e9f648b718b02d0dee2 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/service/IMcService.java (.../IMcService.java) (revision 5ebec80ccc488d5c09da8e9f648b718b02d0dee2) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/service/IMcService.java (.../IMcService.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -83,7 +83,7 @@ McQueUsr getMcUserBySession(final Long queUsrId, final Long mcSessionUid) throws McApplicationException; - Long getPortraitId(Long userId); + String getPortraitId(Long userId); void saveUserAttempt(McQueUsr user, List answerDtos); Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/service/McService.java =================================================================== diff -u -r90aaa6a33006ccf9104ff54239cf13b9ef587728 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/service/McService.java (.../McService.java) (revision 90aaa6a33006ccf9104ff54239cf13b9ef587728) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/service/McService.java (.../McService.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -464,10 +464,10 @@ } @Override - public Long getPortraitId(Long userId) { + public String getPortraitId(Long userId) { if (userId != null) { User user = (User) userManagementService.findById(User.class, userId.intValue()); - return user != null ? user.getPortraitUuid() : null; + return user == null || user.getPortraitUuid() == null ? null : user.getPortraitUuid().toString(); } return null; } @@ -1649,8 +1649,7 @@ for (Object[] userAttemptAndPortraitIter : userAttemptsAndPortraits) { McUsrAttempt userAttempt = (McUsrAttempt) userAttemptAndPortraitIter[0]; - Long portraitUuid = userAttemptAndPortraitIter[1] == null ? null - : ((Number) userAttemptAndPortraitIter[1]).longValue(); + String portraitUuid = (String) userAttemptAndPortraitIter[1]; McQueUsr user = userAttempt.getMcQueUsr(); //fill in question and option uids Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/MonitoringController.java =================================================================== diff -u -rf7937adfea85b6a6976eaa98df8c68db93f9f060 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/MonitoringController.java (.../MonitoringController.java) (revision f7937adfea85b6a6976eaa98df8c68db93f9f060) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -333,7 +333,7 @@ } mcContent.setSubmissionDeadline(tzSubmissionDeadline); mcService.updateMc(mcContent); - + return formattedDate; } @@ -419,14 +419,14 @@ if (groupLeader != null) { Integer totalMark = groupLeader.getLastAttemptTotalMark(); - Long portraitId = mcService.getPortraitId(groupLeader.getQueUsrId()); + String portraitId = mcService.getPortraitId(groupLeader.getQueUsrId()); McUserMarkDTO userDto = new McUserMarkDTO(); userDto.setQueUsrId(groupLeader.getUid().toString()); userDto.setUserId(groupLeader.getQueUsrId().toString()); userDto.setFullName(groupLeader.getFullname()); userDto.setTotalMark(totalMark != null ? totalMark.longValue() : null); - userDto.setPortraitId(portraitId == null ? null : portraitId.toString()); + userDto.setPortraitId(portraitId); userDtos.add(userDto); countVisitLogs = 1; Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/model/ScratchieUser.java =================================================================== diff -u -r1ee503e3d0e0228ea8a45025fddf15d9623c0377 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/model/ScratchieUser.java (.../ScratchieUser.java) (revision 1ee503e3d0e0228ea8a45025fddf15d9623c0377) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/model/ScratchieUser.java (.../ScratchieUser.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -76,7 +76,7 @@ //******************** DTO ********************** @Transient - private Long portraitId; + private String portraitId; public ScratchieUser() { } @@ -191,11 +191,11 @@ this.sessionFinished = sessionFinished; } - public Long getPortraitId() { + public String getPortraitId() { return portraitId; } - public void setPortraitId(Long portraitId) { + public void setPortraitId(String portraitId) { this.portraitId = portraitId; } Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java =================================================================== diff -u -r90aaa6a33006ccf9104ff54239cf13b9ef587728 -r365a2c22199a5fe2b1e55e18cbf4b6d2596f202b --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java (.../ScratchieServiceImpl.java) (revision 90aaa6a33006ccf9104ff54239cf13b9ef587728) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java (.../ScratchieServiceImpl.java) (revision 365a2c22199a5fe2b1e55e18cbf4b6d2596f202b) @@ -718,7 +718,8 @@ // include only leaders in case isUserGroupLeader is ON, include all otherwise if (isIncludeOnlyLeaders && isUserGroupLeader) { User systemUser = (User) userManagementService.findById(User.class, user.getUserId().intValue()); - user.setPortraitId(systemUser.getPortraitUuid()); + user.setPortraitId( + systemUser.getPortraitUuid() == null ? null : systemUser.getPortraitUuid().toString()); usersToShow.add(user); } else if (!isIncludeOnlyLeaders) { usersToShow.add(user);