diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ReviewNode.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ReviewNode.java index 5a7f9930b7f..c3c5c75026c 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ReviewNode.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ReviewNode.java @@ -1,4 +1,3 @@ -package org.wso2.carbon.device.application.mgt.common; /* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. * * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, @@ -16,7 +15,7 @@ package org.wso2.carbon.device.application.mgt.common; * under the License. */ - +package org.wso2.carbon.device.application.mgt.common; import java.util.ArrayList; import java.util.List; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ReviewTmp.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ReviewTmp.java deleted file mode 100644 index 98998dbfebd..00000000000 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ReviewTmp.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.wso2.carbon.device.application.mgt.common; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; - -import java.sql.Timestamp; - -@ApiModel(value = "ReviewTmp", description = "ReviewTmp represents the user's review for an application release") -public class ReviewTmp { - - @ApiModelProperty(name = "id", - value = "The Id given to the comment when it store to the App manager") - private int id; - - @ApiModelProperty(name = "comment", - value = "Comment of the review") - private String comment; - - @ApiModelProperty(name = "parentId", - value = "Parent id of the review") - private int parentId; - - @ApiModelProperty(name = "username", - value = "Username odf the Review creator", - required = true) - private String username; - - @ApiModelProperty(name = "createdAt", - value = "Timestamp fo the review is created") - private Timestamp createdAt; - - @ApiModelProperty(name = "modifiedAt", - value = "Timestamp of the review is modified") - private Timestamp modifiedAt; - - @ApiModelProperty(name = "rating", - value = "Rating value of the application release") - private int rating; - - @ApiModelProperty(name = "replyReviewTmp", - value = "Replying review") - private ReviewTmp replyReviewTmp; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getComment() { - return comment; - } - - public void setComment(String comment) { - this.comment = comment; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public Timestamp getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(Timestamp createdAt) { - this.createdAt = createdAt; - } - - public Timestamp getModifiedAt() { - return modifiedAt; - } - - public void setModifiedAt(Timestamp modifiedAt) { - this.modifiedAt = modifiedAt; - } - - public int getRating() { - return rating; - } - - public void setRating(int rating) { - this.rating = rating; - } - - public int getParentId() { - return parentId; - } - - public void setParentId(int parentId) { - this.parentId = parentId; - } - - public ReviewTmp getReplyReviewTmp() { - return replyReviewTmp; - } - - public void setReplyReviewTmp(ReviewTmp replyReviewTmp) { - this.replyReviewTmp = replyReviewTmp; - } -} - diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApplicationDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApplicationDTO.java index c91f53972f2..108e1e87637 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApplicationDTO.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApplicationDTO.java @@ -81,7 +81,7 @@ public class ApplicationDTO { @ApiModelProperty(name = "appRating", value = "Rating of the aplication") - private int appRating; + private double appRating; @ApiModelProperty(name = "status", value = "Application status", @@ -176,7 +176,7 @@ public class ApplicationDTO { public void setDescription(String description) { this.description = description; } - public int getAppRating() { return appRating; } + public double getAppRating() { return appRating; } - public void setAppRating(int appRating) { this.appRating = appRating; } + public void setAppRating(double appRating) { this.appRating = appRating; } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApplicationReleaseDTO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApplicationReleaseDTO.java index f57035cc7a1..86fbe7cb46e 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApplicationReleaseDTO.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/dto/ApplicationReleaseDTO.java @@ -75,7 +75,7 @@ public class ApplicationReleaseDTO { @ApiModelProperty(name = "price", value = "Price of the application release", required = true) - private Double price; + private double price; @ApiModelProperty(name = "appHashValue", value = "Hash value of the application release") @@ -97,7 +97,7 @@ public class ApplicationReleaseDTO { @ApiModelProperty(name = "rating", value = "Rating value of the application release") - private Double rating; + private double rating; @ApiModelProperty(name = "url", value = "URL which is used for WEB-CLIP") @@ -126,11 +126,11 @@ public class ApplicationReleaseDTO { this.ratedUsers = ratedUsers; } - public Double getRating() { + public double getRating() { return rating; } - public void setRating(Double rating) { + public void setRating(double rating) { this.rating = rating; } @@ -178,11 +178,11 @@ public class ApplicationReleaseDTO { return version; } - public Double getPrice() { + public double getPrice() { return price; } - public void setPrice(Double price) { + public void setPrice(double price) { this.price = price; } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Application.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Application.java index 2afa90f8d93..91dced53faa 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Application.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Application.java @@ -73,6 +73,10 @@ public class Application { example = "IoS, Android, Arduino, RaspberryPi etc") private String deviceType; + @ApiModelProperty(name = "rating", + value = "Application Rating") + private double rating; + @ApiModelProperty(name = "applicationReleases", value = "List of application releases", required = true) @@ -128,4 +132,8 @@ public class Application { public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } + + public double getRating() { return rating; } + + public void setRating(double rating) { this.rating = rating; } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/ApplicationRelease.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/ApplicationRelease.java index 15903198a25..b4d8f5a426e 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/ApplicationRelease.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/ApplicationRelease.java @@ -75,7 +75,7 @@ public class ApplicationRelease { @ApiModelProperty(name = "price", value = "Price of the application release", required = true) - private Double price; + private double price; @ApiModelProperty(name = "isSharedWithAllTenants", value = "If application release is shared with all tenants it is eqal to 1 otherwise 0", @@ -95,6 +95,10 @@ public class ApplicationRelease { value = "ApplicationDTO release supported OS versions") private String supportedOsVersions; + @ApiModelProperty(name = "rating", + value = "Application Rating") + private double rating; + public String getReleaseType() { return releaseType; } @@ -111,11 +115,11 @@ public class ApplicationRelease { this.metaData = metaData; } - public Double getPrice() { + public double getPrice() { return price; } - public void setPrice(Double price) { + public void setPrice(double price) { this.price = price; } @@ -182,4 +186,8 @@ public class ApplicationRelease { public String getCurrentStatus() { return currentStatus; } public void setCurrentStatus(String currentStatus) { this.currentStatus = currentStatus; } + + public double getRating() { return rating; } + + public void setRating(double rating) { this.rating = rating; } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Review.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Review.java index 4acfa1e6a6e..e77bbacc061 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Review.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Review.java @@ -17,19 +17,40 @@ package org.wso2.carbon.device.application.mgt.common.response; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + import java.sql.Timestamp; import java.util.List; +@ApiModel(value = "Review", description = "Review represents the user's review for an application release") public class Review { + @ApiModelProperty(name = "id", value = "Review ID.") private int id; + + @ApiModelProperty(name = "content", value = "Review message.") private String content; + + @ApiModelProperty(name = "rootParentId", value = "Root Parent id of the review") private int rootParentId; + + @ApiModelProperty(name = "immediateParentId", value = "Immediate Parent id of the review") private int immediateParentId; + + @ApiModelProperty(name = "username", value = "Username odf the Review creator") private String username; + + @ApiModelProperty(name = "createdAt", value = "Review created timestamp.") private Timestamp createdAt; + + @ApiModelProperty(name = "createdAt", value = "Review modified timestamp.") private Timestamp modifiedAt; + + @ApiModelProperty(name = "rating", value = "Rating value of the application release") private int rating; + + @ApiModelProperty(name = "replies", value = "Replying reviews") private List replies; public int getId() { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ReviewManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ReviewManager.java index d677fa0e562..409bfe289aa 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ReviewManager.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ReviewManager.java @@ -19,11 +19,10 @@ package org.wso2.carbon.device.application.mgt.common.services; import org.wso2.carbon.device.application.mgt.common.Rating; -import org.wso2.carbon.device.application.mgt.common.ReviewTmp; +import org.wso2.carbon.device.application.mgt.common.response.Review; import org.wso2.carbon.device.application.mgt.common.PaginationRequest; import org.wso2.carbon.device.application.mgt.common.PaginationResult; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; -import org.wso2.carbon.device.application.mgt.common.exception.ReviewDoesNotExistException; import org.wso2.carbon.device.application.mgt.common.exception.ReviewManagementException; import org.wso2.carbon.device.application.mgt.common.wrapper.ReviewWrapper; @@ -37,7 +36,7 @@ public interface ReviewManager { * * @param reviewWrapper reviewTmp of the application. * @param uuid uuid of the application release. - * @return {@link ReviewTmp} ReviewTmp added + * @return {@link Review} Added review * @throws ReviewManagementException Exceptions of the reviewTmp management. */ boolean addReview(ReviewWrapper reviewWrapper, String uuid) @@ -61,29 +60,28 @@ public interface ReviewManager { * To delete review using review id. * * @param uuid UUID of the application release - * @param commentId id of the comment * @return If review is successfully deleted return true, otherwise returns false * @throws ReviewManagementException Exceptions of the comment management */ - boolean deleteReview(String uuid, int commentId) - throws ReviewManagementException, ReviewDoesNotExistException; + void deleteReview(String uuid, int reviewId, boolean isPriviledgedUser) + throws ReviewManagementException, ApplicationManagementException; /** * To update a reviewTmp. * * @param reviewId id of the reviewTmp * @param uuid UUID of the application release - * @return {@link ReviewTmp}updated reviewTmp + * @return {@link Review}updated review * @throws ReviewManagementException Exceptions of the reviewTmp management */ - boolean updateReview(ReviewWrapper updatingReview, int reviewId, String uuid) + boolean updateReview(ReviewWrapper updatingReview, int reviewId, String uuid, boolean isPriviledgedUser) throws ReviewManagementException, ApplicationManagementException; /** * To get the overall rating for a application release * * @param appReleaseUuuid UUID of the application release. - * @return {@link ReviewTmp}updated review + * @return {@link Review}updated review * @throws ReviewManagementException Exceptions of the review management */ Rating getRating(String appReleaseUuuid) throws ReviewManagementException; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationDAO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationDAO.java index 596d7ec9f09..7e24b9ac367 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationDAO.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationDAO.java @@ -202,6 +202,9 @@ public interface ApplicationDAO { */ boolean updateApplication(ApplicationDTO application, int tenantId) throws ApplicationManagementDAOException; + void updateApplicationRating(String uuid, double rating, int tenantId) throws ApplicationManagementDAOException; + + /** * To delete the application * diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java index a97fe2d08bc..e289e58597c 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java @@ -106,6 +106,9 @@ public interface ApplicationReleaseDAO { */ Rating getRating(String uuid, int tenantId) throws ApplicationManagementDAOException; + List getReleaseRatings(String uuid, int tenantId) throws ApplicationManagementDAOException; + + /** * To delete a particular release. diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ReviewDAO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ReviewDAO.java index e7f74cdeb0f..855f3bc5162 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ReviewDAO.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ReviewDAO.java @@ -18,7 +18,7 @@ */ package org.wso2.carbon.device.application.mgt.core.dao; -import org.wso2.carbon.device.application.mgt.common.ReviewTmp; +import org.wso2.carbon.device.application.mgt.common.response.Review; import org.wso2.carbon.device.application.mgt.common.PaginationRequest; import org.wso2.carbon.device.application.mgt.common.dto.ReviewDTO; import org.wso2.carbon.device.application.mgt.common.exception.ReviewManagementException; @@ -65,15 +65,14 @@ import java.util.List; * @return row count if updating is succeed otherwise 0 * @throws ReviewManagementDAOException Exceptions of the reviewTmp management. */ - int updateReview(ReviewDTO reviewDTO, int reviewId, int tenantId) - throws ReviewManagementDAOException; + int updateReview(ReviewDTO reviewDTO, int reviewId, int tenantId) throws ReviewManagementDAOException; /** * To get the comment with id. * * @param reviewId id of the review - * @return {@link ReviewTmp}ReviewTmp + * @return {@link Review} * @throws ReviewManagementDAOException Exceptions of the review management DAO. */ ReviewDTO getReview(int reviewId) throws ReviewManagementDAOException; @@ -88,7 +87,7 @@ import java.util.List; * @param request {@link PaginationRequest}pagination request with offSet and limit * @param tenantId Tenant id * @return {@link List}List of all reviews for the application release - * @throws ReviewManagementDAOException ReviewTmp management DAO exception + * @throws ReviewManagementDAOException Review management DAO exception **/ List getAllReviews(int releaseId, PaginationRequest request, int tenantId) throws ReviewManagementDAOException; @@ -125,9 +124,14 @@ import java.util.List; * @param username username of the review owner * @param reviewId id of the review * @return If review is successfully deleted return 1, otherwise returns 0. - * @throws ReviewManagementDAOException ReviewTmp management DAO exception. + * @throws ReviewManagementDAOException Review management DAO exception. */ - int deleteReview(String username, int reviewId) throws ReviewManagementDAOException; + void deleteReview(int reviewId, int tenantId) throws ReviewManagementDAOException; + + void deleteReviews(List reviewIds, int tenantId) throws ReviewManagementDAOException; + + + void deleteAllChildCommentsOfReview(int rootParentId, int tenantId) throws ReviewManagementDAOException; /** * To delete comments using application details. @@ -143,8 +147,8 @@ import java.util.List; * To get review count for a specific application release * * @param uuid uuid of the application release - * @return ReviewTmp count - * @throws ReviewManagementDAOException ReviewTmp management DAO exception + * @return Review count + * @throws ReviewManagementDAOException Review management DAO exception */ int getReviewCount(String uuid) throws ReviewManagementDAOException; } \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java index 59ef55e1b47..587a5cafb74 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java @@ -648,6 +648,37 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic } } + @Override + public void updateApplicationRating(String uuid, double rating, int tenantId) + throws ApplicationManagementDAOException { + Connection conn; + try { + conn = this.getDBConnection(); + String sql = "UPDATE AP_APP AP " + + "SET " + + "AP.RATING = ? " + + "WHERE " + + "AP.ID = (SELECT AP_APP_ID FROM AP_APP_RELEASE WHERE UUID = ?) AND " + + "AP.TENANT_ID = ?"; + + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setDouble(1, rating); + stmt.setString(2, uuid); + stmt.setInt(3, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to update the application rating."; + log.error(msg); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when obtaining database connection for updating the application rating."; + log.error(msg); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override public void retireApplication(int appId) throws ApplicationManagementDAOException { Connection conn; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java index 93663008c81..a7b96f5b893 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/release/GenericApplicationReleaseDAOImpl.java @@ -393,7 +393,8 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements * @param uuid UUID of the application Release. * @throws ApplicationManagementDAOException ApplicationDTO Management DAO Exception. */ - @Override public Rating getRating(String uuid, int tenantId) throws ApplicationManagementDAOException { + @Override + public Rating getRating(String uuid, int tenantId) throws ApplicationManagementDAOException { Connection connection; PreparedStatement statement = null; ResultSet resultSet = null; @@ -423,6 +424,37 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements } } + @Override + public List getReleaseRatings(String uuid, int tenantId) throws ApplicationManagementDAOException { + Connection connection; + List ratingValues = new ArrayList<>(); + String sql = "SELECT " + + "RATING " + + "FROM AP_APP_RELEASE " + + "WHERE " + + "AP_APP_ID = (SELECT AP_APP_ID FROM AP_APP_RELEASE WHERE UUID = ?) AND " + + "TENANT_ID = ?"; + try { + connection = this.getDBConnection(); + try (PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, uuid); + statement.setInt(2, tenantId); + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + ratingValues.add(resultSet.getDouble("RATING")); + } return ratingValues; + } + } + } catch (DBConnectionException e) { + throw new ApplicationManagementDAOException( + "Database connection exception while trying to update the application release", e); + } catch (SQLException e) { + throw new ApplicationManagementDAOException( + "SQL exception while updating the release ,while executing the query " + sql, e); + } + } + + /** * To insert the application release properties. * diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/review/ReviewDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/review/ReviewDAOImpl.java index 9cf963beed6..d8b457ada4b 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/review/ReviewDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/review/ReviewDAOImpl.java @@ -433,26 +433,77 @@ public class ReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO { } @Override - public int deleteReview(String username, int reviewId) throws ReviewManagementDAOException { + public void deleteReview(int reviewId, int tenantId) throws ReviewManagementDAOException { Connection conn; - PreparedStatement statement = null; try { conn = this.getDBConnection(); - sql = "DELETE FROM AP_APP_REVIEW WHERE ID=? AND USERNAME = ?;"; - statement = conn.prepareStatement(sql); - statement.setInt(1, reviewId); - statement.setString(2, username); - return statement.executeUpdate(); + sql = "DELETE " + + "FROM AP_APP_REVIEW " + + "WHERE " + + "ID = ? AND " + + "TENANT_ID = ?"; + try (PreparedStatement statement = conn.prepareStatement(sql)) { + statement.setInt(1, reviewId); + statement.setInt(2, tenantId); + statement.executeUpdate(); + } } catch (SQLException e) { throw new ReviewManagementDAOException("Error occured while accessing the Database", e); } catch (DBConnectionException e) { throw new ReviewManagementDAOException("Error occured while getting the database connection", e); - } finally { - DAOUtil.cleanupResources(statement, null); } } + @Override + public void deleteReviews(List reviewIds, int tenantId) throws ReviewManagementDAOException{ + Connection conn; + try { + conn = this.getDBConnection(); + sql = "DELETE " + + "FROM AP_APP_REVIEW " + + "WHERE " + + "ID = ? AND " + + "TENANT_ID = ?"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (Integer reviewId : reviewIds) { + stmt.setInt(1, reviewId); + stmt.setInt(2, tenantId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (SQLException e) { + throw new ReviewManagementDAOException("Error occured while accessing the Database", e); + } catch (DBConnectionException e) { + throw new ReviewManagementDAOException("Error occured while getting the database connection", e); + + } + } + + @Override + public void deleteAllChildCommentsOfReview(int rootParentId, int tenantId) throws ReviewManagementDAOException { + Connection conn; + try { + conn = this.getDBConnection(); + sql = "DELETE " + + "FROM AP_APP_REVIEW " + + "WHERE " + + "ROOT_PARENT_ID = ? AND " + + "TENANT_ID = ?"; + try (PreparedStatement statement = conn.prepareStatement(sql)){ + statement.setInt(1, rootParentId); + statement.setInt(2, tenantId); + statement.executeUpdate(); + } + } catch (SQLException e) { + throw new ReviewManagementDAOException("Error occured while accessing the Database", e); + } catch (DBConnectionException e) { + throw new ReviewManagementDAOException("Error occured while getting the database connection", e); + } + } + + @Override public void deleteReviews(String appType, String appName, String version) throws ReviewManagementException { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ReviewManagementDAOException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ReviewManagementDAOException.java index 56cb3ff3bac..f32f08b3244 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ReviewManagementDAOException.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/exception/ReviewManagementDAOException.java @@ -21,7 +21,7 @@ package org.wso2.carbon.device.application.mgt.core.exception; import org.wso2.carbon.device.application.mgt.common.exception.ReviewManagementException; /** - * Exception thrown during the ReviewTmp Management DAO operations. + * Exception thrown during the Review Management DAO operations. */ public class ReviewManagementDAOException extends ReviewManagementException { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java index 010d9a565e8..c7161a2393c 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java @@ -2555,6 +2555,7 @@ public class ApplicationManagerImpl implements ApplicationManager { application.setTags(applicationDTO.getTags()); application.setUnrestrictedRoles(applicationDTO.getUnrestrictedRoles()); application.setDeviceType(deviceType.getName()); + application.setRating(applicationDTO.getAppRating()); List applicationReleases = applicationDTO.getApplicationReleaseDTOs() .stream().map(this::releaseDtoToRelease).collect(Collectors.toList()); application.setApplicationReleases(applicationReleases); @@ -2577,6 +2578,7 @@ public class ApplicationManagerImpl implements ApplicationManager { applicationRelease.setCurrentStatus(applicationReleaseDTO.getCurrentState()); applicationRelease.setIsSharedWithAllTenants(applicationReleaseDTO.getIsSharedWithAllTenants()); applicationRelease.setSupportedOsVersions(applicationReleaseDTO.getSupportedOsVersions()); + applicationRelease.setRating(applicationReleaseDTO.getRating()); applicationRelease .setInstallerPath(basePath + Constants.FORWARD_SLASH + applicationReleaseDTO.getInstallerName()); applicationRelease.setIconPath(basePath + Constants.FORWARD_SLASH + applicationReleaseDTO.getIconName()); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ReviewManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ReviewManagerImpl.java index 5397ccee698..6751eef6689 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ReviewManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ReviewManagerImpl.java @@ -19,7 +19,6 @@ package org.wso2.carbon.device.application.mgt.core.impl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.application.mgt.common.Rating; import org.wso2.carbon.device.application.mgt.common.ReviewNode; @@ -28,13 +27,13 @@ import org.wso2.carbon.device.application.mgt.common.PaginationResult; import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO; import org.wso2.carbon.device.application.mgt.common.dto.ReviewDTO; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; -import org.wso2.carbon.device.application.mgt.common.exception.ReviewDoesNotExistException; import org.wso2.carbon.device.application.mgt.common.exception.ReviewManagementException; import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; import org.wso2.carbon.device.application.mgt.common.exception.TransactionManagementException; import org.wso2.carbon.device.application.mgt.common.response.Review; import org.wso2.carbon.device.application.mgt.common.services.*; import org.wso2.carbon.device.application.mgt.common.wrapper.ReviewWrapper; +import org.wso2.carbon.device.application.mgt.core.dao.ApplicationDAO; import org.wso2.carbon.device.application.mgt.core.dao.ApplicationReleaseDAO; import org.wso2.carbon.device.application.mgt.core.dao.ReviewDAO; import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory; @@ -43,13 +42,11 @@ import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException import org.wso2.carbon.device.application.mgt.core.exception.ForbiddenException; import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException; import org.wso2.carbon.device.application.mgt.core.exception.ReviewManagementDAOException; -import org.wso2.carbon.device.application.mgt.core.internal.DataHolder; import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; -import org.wso2.carbon.user.api.UserRealm; -import org.wso2.carbon.user.api.UserStoreException; -import org.wso2.carbon.utils.multitenancy.MultitenantUtils; +import org.wso2.carbon.device.application.mgt.core.util.Constants; import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.TreeMap; @@ -62,6 +59,7 @@ public class ReviewManagerImpl implements ReviewManager { private static final Log log = LogFactory.getLog(ReviewManagerImpl.class); private ReviewDAO reviewDAO; private ApplicationReleaseDAO applicationReleaseDAO; + private ApplicationDAO applicationDAO; public ReviewManagerImpl() { initDataAccessObjects(); @@ -70,6 +68,7 @@ public class ReviewManagerImpl implements ReviewManager { private void initDataAccessObjects() { this.reviewDAO = ApplicationManagementDAOFactory.getCommentDAO(); this.applicationReleaseDAO = ApplicationManagementDAOFactory.getApplicationReleaseDAO(); + this.applicationDAO = ApplicationManagementDAOFactory.getApplicationDAO(); } @Override @@ -167,10 +166,11 @@ public class ReviewManagerImpl implements ReviewManager { String msg = "Couldn't find an review which has review ID: " + parentReviewId + " for application release which has UUID: " + uuid; log.error(msg); - throw new BadRequestException(msg); + throw new NotFoundException(msg); } ReviewDTO replyComment = reviewWrapperToDO(reviewWrapper); replyComment.setUsername(username); + replyComment.setRating(0); replyComment.setImmediateParentId(parentReview.getId()); if (parentReview.getRootParentId() == -1) { replyComment.setRootParentId(parentReview.getId()); @@ -184,7 +184,7 @@ public class ReviewManagerImpl implements ReviewManager { return false; } catch (DBConnectionException e) { throw new ReviewManagementException( - "DB Connection error occurs ,ReviewTmp for application release with UUID: " + uuid + " is failed", + "DB Connection error occurs ,Review for application release with UUID: " + uuid + " is failed", e); } catch (TransactionManagementException e) { String msg = "DB transaction error occurred when adding reply comment for comment which has comment id: " @@ -210,15 +210,7 @@ public class ReviewManagerImpl implements ReviewManager { List reviews = new ArrayList<>(); for (ReviewDTO reviewDTO : reviewDTOs){ - Review review = new Review(); - review.setId(reviewDTO.getId()); - review.setContent(reviewDTO.getContent()); - review.setRootParentId(reviewDTO.getRootParentId()); - review.setImmediateParentId(reviewDTO.getImmediateParentId()); - review.setCreatedAt(reviewDTO.getCreatedAt()); - review.setModifiedAt(reviewDTO.getModifiedAt()); - review.setReplies(new ArrayList<>()); - reviews.add(review); + reviews.add(reviewDTOToReview(reviewDTO)); } return reviews; } @@ -231,20 +223,21 @@ public class ReviewManagerImpl implements ReviewManager { review.setImmediateParentId(reviewDTO.getImmediateParentId()); review.setCreatedAt(reviewDTO.getCreatedAt()); review.setModifiedAt(reviewDTO.getModifiedAt()); + review.setRating(reviewDTO.getRating()); review.setReplies(new ArrayList<>()); return review; } @Override - public boolean updateReview(ReviewWrapper updatingReview, int reviewId, String uuid) + public boolean updateReview(ReviewWrapper updatingReview, int reviewId, String uuid, boolean isPriviledgedUser) throws ReviewManagementException, ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); if (log.isDebugEnabled()) { - log.debug("ReviewTmp updating request is received for the reviewTmp id " + reviewId); + log.debug("Review updating request is received for the reviewTmp id " + reviewId); } try { - ConnectionManagerUtil.openDBConnection(); + ConnectionManagerUtil.beginDBTransaction(); ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId); if (applicationReleaseDTO == null) { String msg = "Couldn't found an application release for UUID: " + uuid; @@ -260,8 +253,8 @@ public class ReviewManagerImpl implements ReviewManager { throw new NotFoundException(msg); } - if (!username.equals(reviewDTO.getUsername())) { - String msg = "You are trying to update a review which is triggered by " + reviewDTO.getUsername() + if (!isPriviledgedUser && !username.equals(reviewDTO.getUsername())) { + String msg = "You are trying to update a review which is created by " + reviewDTO.getUsername() + ". Hence you are not permitted to update the review."; log.error(msg); throw new ForbiddenException(msg); @@ -275,8 +268,13 @@ public class ReviewManagerImpl implements ReviewManager { reviewDTO.setRating(updatingReview.getRating()); } reviewDTO.setContent(updatingReview.getContent()); - return this.reviewDAO.updateReview(reviewDTO, reviewId, tenantId) == 1; + if (this.reviewDAO.updateReview(reviewDTO, reviewId, tenantId) == 1){ + ConnectionManagerUtil.commitDBTransaction(); + return true; + } + return false; } catch (ReviewManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); String msg = "Error occured while getting reviewTmp with reviewTmp id " + reviewId + "."; log.error(msg); throw new ReviewManagementException(msg, e); @@ -288,6 +286,10 @@ public class ReviewManagerImpl implements ReviewManager { String msg = "Error occured when getting application release data for application release UUID: " + uuid; log.error(msg); throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "DB transaction error occurred when updating comment which has comment id: " + reviewId; + log.error(msg); + throw new ReviewManagementException(msg, e); } finally { ConnectionManagerUtil.closeDBConnection(); } @@ -371,33 +373,96 @@ public class ReviewManagerImpl implements ReviewManager { return review; } + private ReviewNode getReviewNode(ReviewNode node, int reviewId) { + if (node.getData().getId() == reviewId) { + return node; + } else { + for (ReviewNode each : node.getChildren()) { + ReviewNode result = getReviewNode(each, reviewId); + if (result != null) { + return result; + } + } + } + return null; + } + + private List getDeletingReviewIds(ReviewNode node, List reviewIds) { + reviewIds.add(node.getData().getId()); + if (node.getChildren().isEmpty()){ + return reviewIds; + } + for (ReviewNode each : node.getChildren()) { + getDeletingReviewIds(each, reviewIds); + } + return reviewIds; + } + @Override - public boolean deleteReview(String uuid, int reviewId) - throws ReviewManagementException, ReviewDoesNotExistException { - ReviewDTO existingReview; + public void deleteReview(String uuid, int reviewId, boolean isPriviledgedUser) + throws ReviewManagementException, ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); try { - ConnectionManagerUtil.openDBConnection(); - existingReview = this.reviewDAO.getReview(reviewId); + ConnectionManagerUtil.beginDBTransaction(); + ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId); + if (applicationReleaseDTO == null) { + String msg = "Couldn't found an application release for UUID: " + uuid + + " to delete review which has review ID: " + reviewId; + log.error(msg); + throw new NotFoundException(msg); + } + ReviewDTO existingReview = this.reviewDAO.getReview(applicationReleaseDTO.getId(), reviewId); if (existingReview == null) { - throw new ReviewDoesNotExistException( - "Cannot delete a non-existing review for the application with review id" + reviewId); + String msg = "Cannot delete a non-existing review for the application with review id" + reviewId; + log.error(msg); + throw new NotFoundException(msg); + } + if (!isPriviledgedUser && !username.equals(existingReview.getUsername())) { + String msg = "You are trying to delete a comment that is owned by you. Hence you are not permitted to " + + "delete the review"; + log.error(msg); + throw new ForbiddenException(msg); + } + if (existingReview.getRootParentId() == Constants.REVIEW_PARENT_ID + && existingReview.getImmediateParentId() == Constants.REVIEW_PARENT_ID) { + this.reviewDAO.deleteAllChildCommentsOfReview(existingReview.getId(), tenantId); + this.reviewDAO.deleteReview(existingReview.getId(), tenantId); + ConnectionManagerUtil.commitDBTransaction(); + Runnable task = () -> calculateRating(0, existingReview.getRating(), uuid, tenantId); + new Thread(task).start(); + } else { + ReviewDTO rootReview = this.reviewDAO.getReview(existingReview.getRootParentId()); + List replyComments = this.reviewDAO.getReplyComments(rootReview.getId(), tenantId); + + ReviewNode reviewNode = new ReviewNode<>(rootReview); + replyComments.sort(Comparator.comparing(ReviewDTO::getId)); + for (ReviewDTO reply : replyComments) { + reviewNode = findAndSetChild(reviewNode, reply); + } + + ReviewNode deletingRevieNode = getReviewNode(reviewNode, existingReview.getId()); + List deletingReviewIds = getDeletingReviewIds(deletingRevieNode, new ArrayList<>()); + this.reviewDAO.deleteReviews(deletingReviewIds, tenantId); + ConnectionManagerUtil.commitDBTransaction(); } - Runnable task = () -> calculateRating(0, existingReview.getRating(), uuid, tenantId); - new Thread(task).start(); - return isAuthorizedUser(username, existingReview.getUsername(), tenantId) - && this.reviewDAO.deleteReview(username, reviewId) == 1; } catch (DBConnectionException e) { - throw new ReviewManagementException( - "DB Connection error occurs deleting review with review id " + reviewId + ".", e); + String msg = "DB Connection error occurs deleting review with review id " + reviewId + "."; + log.error(msg); + throw new ReviewManagementException(msg, e); } catch (ReviewManagementDAOException e) { - throw new ReviewManagementException("Error occured while deleting review with review id " + reviewId + ".", - e); - } catch (UserStoreException e) { - throw new ReviewManagementException( - "User-store exception while checking whether the user " + username + " of tenant " + tenantId - + " has the publisher permission"); + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occured while deleting review with review id " + reviewId + "."; + log.error(msg); + throw new ReviewManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred when handleing transaction to delete application reviews."; + log.error(msg); + throw new ReviewManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error Occurred when getting application release data for application release UUID: " + uuid; + log.error(msg); + throw new ReviewManagementException(msg, e); } finally { ConnectionManagerUtil.closeDBConnection(); } @@ -446,7 +511,7 @@ public class ReviewManagerImpl implements ReviewManager { private void calculateRating(int newRatingVal, int oldRatingVal, String uuid, int tenantId) { try { - ConnectionManagerUtil.openDBConnection(); + ConnectionManagerUtil.beginDBTransaction(); Rating rating = this.applicationReleaseDAO.getRating(uuid, tenantId); if (rating == null) { log.error("Couldn't find rating for application release uuid: " + uuid); @@ -460,7 +525,7 @@ public class ReviewManagerImpl implements ReviewManager { newTotalRating = currentRating + newRatingVal; numOfUsers++; } else if (newRatingVal == 0) { - newTotalRating = currentRating - newRatingVal; + newTotalRating = currentRating - oldRatingVal; numOfUsers--; } else { double tmpVal; @@ -473,47 +538,30 @@ public class ReviewManagerImpl implements ReviewManager { } else { updatedRating = newTotalRating / numOfUsers; } + this.applicationReleaseDAO.updateRatingValue(uuid, updatedRating, numOfUsers); + + List releaseRatings = this.applicationReleaseDAO.getReleaseRatings(uuid, tenantId); + double appAverageRatingValue = 0.0; + double sumOfRatings = releaseRatings.stream().mapToDouble(rt -> rt).sum(); + if (sumOfRatings != 0.0) { + appAverageRatingValue = sumOfRatings / releaseRatings.size(); + } + this.applicationDAO.updateApplicationRating(uuid, appAverageRatingValue, tenantId); + ConnectionManagerUtil.commitDBTransaction(); } } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); log.error("Error occured while getting the rating value of the application release UUID: " + uuid, e); } catch (DBConnectionException e) { log.error("DB Connection error occured while updated the rating value of the application release UUID: " + uuid + " can not get.", e); + } catch (TransactionManagementException e) { + log.error( + "Transaction error occured while updated the rating value of the application release UUID: " + uuid + + " can not get.", e); } finally { ConnectionManagerUtil.closeDBConnection(); } } - - /** - * To check whether current user has the permission to do some secured operation. - * - * @param username Name of the User. - * @param tenantId ID of the tenant. - * @param permission Permission that need to be checked. - * @return true if the current user has the permission, otherwise false. - * @throws UserStoreException UserStoreException - */ - private boolean isAdminUser(String username, int tenantId, String permission) throws UserStoreException { - UserRealm userRealm = DataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId); - return userRealm != null && userRealm.getAuthorizationManager() != null && userRealm.getAuthorizationManager() - .isUserAuthorized(MultitenantUtils.getTenantAwareUsername(username), permission, - CarbonConstants.UI_PERMISSION_ACTION); - } - - - /** - * To check whether logged in user is authorized user to do an specific action. - * - * @param loggedInUser username of the loggedin user. - * @param reviewOwner username of the review owner. - * @param tenantId ID of the tenant. - * @return true if the current user has the permission, otherwise false. - * @throws UserStoreException UserStoreException - */ - private boolean isAuthorizedUser(String loggedInUser, String reviewOwner, int tenantId) throws UserStoreException { - return loggedInUser.equals(reviewOwner) || isAdminUser(loggedInUser, tenantId, - CarbonConstants.UI_ADMIN_PERMISSION_COLLECTION); - } - -} \ No newline at end of file +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/APIUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/APIUtil.java index d3ae664f320..d4cc2f72c74 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/APIUtil.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/APIUtil.java @@ -120,7 +120,7 @@ public class APIUtil { } /** - * To get the ReviewTmp Manager from the osgi context. + * To get the Review Manager from the osgi context. * @return ReviewManager instance in the current osgi context. */ public static ReviewManager getReviewManager() { @@ -131,7 +131,7 @@ public class APIUtil { reviewManager = (ReviewManager) ctx.getOSGiService(ReviewManager.class, null); if (reviewManager == null) { - String msg = "ReviewTmp Manager service has not initialized."; + String msg = "Review Manager service has not initialized."; log.error(msg); throw new IllegalStateException(msg); } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/DAOUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/DAOUtil.java index 57db28ef403..4068284e678 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/DAOUtil.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/DAOUtil.java @@ -81,7 +81,7 @@ public class DAOUtil { application.setSubType(rs.getString("APP_SUB_TYPE")); application.setPaymentCurrency(rs.getString("APP_CURRENCY")); application.setStatus(rs.getString("APP_STATUS")); - application.setAppRating(rs.getInt("APP_RATING")); + application.setAppRating(rs.getDouble("APP_RATING")); application.setDeviceTypeId(rs.getInt("APP_DEVICE_TYPE_ID")); application.getApplicationReleaseDTOs().add(loadAppRelease(rs)); } else { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/ReviewManagementAPI.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/ReviewManagementAPI.java index f9a4c8f39dc..2428af42838 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/ReviewManagementAPI.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/ReviewManagementAPI.java @@ -32,7 +32,7 @@ import org.wso2.carbon.apimgt.annotations.api.Scope; import org.wso2.carbon.apimgt.annotations.api.Scopes; import org.wso2.carbon.device.application.mgt.common.PaginationResult; import org.wso2.carbon.device.application.mgt.common.ErrorResponse; -import org.wso2.carbon.device.application.mgt.common.ReviewTmp; +import org.wso2.carbon.device.application.mgt.common.response.Review; import org.wso2.carbon.device.application.mgt.common.wrapper.ReviewWrapper; import javax.validation.Valid; @@ -65,7 +65,7 @@ import java.util.List; } ), tags = { - @Tag(name = "review_management", description = "ReviewTmp Management related APIs") + @Tag(name = "review_management", description = "Review Management related APIs") } ) @Scopes( @@ -86,7 +86,7 @@ import java.util.List; ) @Path("/reviews") -@Api(value = "ReviewTmp Management") +@Api(value = "Review Management") @Produces(MediaType.APPLICATION_JSON) public interface ReviewManagementAPI { String SCOPE = "scope"; @@ -163,7 +163,7 @@ public interface ReviewManagementAPI { @ApiResponse( code = 201, message = "OK. \n Successfully add a reviewTmp.", - response = ReviewTmp.class), + response = Review.class), @ApiResponse( code = 400, message = @@ -183,7 +183,7 @@ public interface ReviewManagementAPI { Response addReview( @ApiParam( name = "reviewTmp", - value = "ReviewTmp details", + value = "Review details", required = true) ReviewWrapper reviewWrapper, @ApiParam( name="uuid", @@ -204,7 +204,7 @@ public interface ReviewManagementAPI { tags = "Store Management", extensions = { @Extension(properties = { - @ExtensionProperty(name = SCOPE, value = "perm:app:reviewTmp:update") + @ExtensionProperty(name = SCOPE, value = "perm:app:review:update") }) } ) @@ -214,7 +214,7 @@ public interface ReviewManagementAPI { @ApiResponse( code = 201, message = "OK. \n Successfully add a reviewTmp.", - response = ReviewTmp.class), + response = Review.class), @ApiResponse( code = 400, message = @@ -267,7 +267,7 @@ public interface ReviewManagementAPI { @ApiResponse( code = 200, message = "OK. \n Successfully updated reviewTmp.", - response = ReviewTmp.class), + response = Review.class), @ApiResponse( code = 400, message = "Bad Request. \n Invalid request or validation error."), @@ -316,6 +316,9 @@ public interface ReviewManagementAPI { @ApiResponse( code = 200, message = "OK. \n Successfully deleted the review"), + @ApiResponse( + code = 403, + message = "Don't have permission to delete the review."), @ApiResponse( code = 404, message = "Not Found. \n No activity found with the given ID.", diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/admin/ReviewManagementAdminAPI.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/admin/ReviewManagementAdminAPI.java new file mode 100644 index 00000000000..df2780fcd1f --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/admin/ReviewManagementAdminAPI.java @@ -0,0 +1,174 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.store.api.services.admin; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Info; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.application.mgt.common.ErrorResponse; +import org.wso2.carbon.device.application.mgt.common.response.Review; +import org.wso2.carbon.device.application.mgt.common.wrapper.ReviewWrapper; + +import javax.validation.Valid; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +/** +* APIs to handle review management related tasks. +*/ + +@SwaggerDefinition( +info = @Info( + version = "1.0.0", + title = "Store Management Admin Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "ReviewManagementAdminService"), + @ExtensionProperty(name = "context", value = "/api/application-mgt/v1.0/admin/review"), + }) + } +), +tags = { + @Tag(name = "review_management", description = "Review Management related Admin APIs") +} +) +@Scopes( +scopes = { + @Scope( + name = "Update a Review", + description = "Update a Review from the application store.", + key = "perm:admin:app:review:update", + permissions = {"/app-mgt/store/admin/review/update"} + ) +} +) + +@Path("/admin/reviews") +@Api(value = "Review Management") +@Produces(MediaType.APPLICATION_JSON) +public interface ReviewManagementAdminAPI { +String SCOPE = "scope"; + +@PUT +@Path("/{uuid}/{reviewId}") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Edit a reviewTmp", + notes = "This will edit the reviewTmp", + tags = "Store Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:admin:app:review:update") + }) + } +) +@ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully updated reviewTmp.", + response = Review.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while updating the new reviewTmp.", + response = ErrorResponse.class) + }) +Response updateReview( + @ApiParam( + name = "reviewTmp", + value = "The reviewTmp that need to be updated.", + required = true) + @Valid ReviewWrapper updatingReview, + @ApiParam( + name = "uuid", + value = "uuid of the application release", + required = true) + @PathParam("uuid") String uuid, + @ApiParam( + name = "reviewId", + value = "reviewTmp id of the updating reviewTmp.", + required = true) + @PathParam("reviewId") int reviewId); + +@DELETE +@Path("/{uuid}/{reviewId}") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "DELETE", + value = "Remove comment", + notes = "Remove comment", + tags = "Store Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:admin:app:review:update") + }) + } +) + +@ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully deleted the review"), + @ApiResponse( + code = 404, + message = "Not Found. \n No activity found with the given ID.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while deleting the review.", + response = ErrorResponse.class) + }) + +Response deleteReview( + @ApiParam( + name = "uuid", + value = "UUID of the application release.", + required = true) + @PathParam("uuid") String uuid, + @ApiParam(name = "reviewId", + value = "Id of the review.", + required = true) + @PathParam("reviewId") int reviewId); + + +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/ReviewManagementAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/ReviewManagementAPIImpl.java index 860efe8e38d..c8b8a667a81 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/ReviewManagementAPIImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/ReviewManagementAPIImpl.java @@ -47,7 +47,7 @@ import javax.ws.rs.DELETE; import javax.ws.rs.core.Response; /** - * ReviewTmp Management related jax-rs APIs. + * Review Management related jax-rs APIs. */ @Path("/reviews") public class ReviewManagementAPIImpl implements ReviewManagementAPI { @@ -170,7 +170,7 @@ public class ReviewManagementAPIImpl implements ReviewManagementAPI { @PathParam("reviewId") int reviewId) { ReviewManager reviewManager = APIUtil.getReviewManager(); try { - if (reviewManager.updateReview(updatingReview, reviewId, uuid)) { + if (reviewManager.updateReview(updatingReview, reviewId, uuid, false)) { return Response.status(Response.Status.OK).entity(updatingReview).build(); } else { String msg = "Review updating failed. Please contact the administrator"; @@ -204,20 +204,25 @@ public class ReviewManagementAPIImpl implements ReviewManagementAPI { ReviewManager reviewManager = APIUtil.getReviewManager(); try { - if (reviewManager.deleteReview(uuid, reviewId)) { - return Response.status(Response.Status.OK).entity("ReviewTmp is deleted successfully.").build(); - } else { - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("ReviewTmp deleting is failed.") - .build(); - } + reviewManager.deleteReview(uuid, reviewId, false); + return Response.status(Response.Status.OK).entity("Review is deleted successfully.").build(); + + } catch (NotFoundException e) { + String msg = "Couldn't found an application review to delete which match with the request."; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ForbiddenException e) { + String msg = "You are not permitted to delete the review."; + log.error(msg, e); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); } catch (ReviewManagementException e) { String msg = "Error occurred while deleting the comment."; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); - } catch (ReviewDoesNotExistException e) { - String msg = "Couldn't find a review for review-id: " + reviewId + " to delete."; + } catch (ApplicationManagementException e) { + String msg = "Error occurred while getting application release data."; log.error(msg, e); - return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } } @@ -231,7 +236,7 @@ public class ReviewManagementAPIImpl implements ReviewManagementAPI { try { rating = reviewManager.getRating(uuid); } catch (ReviewManagementException e) { - log.error("ReviewTmp Management Exception occurs", e); + log.error("Review Management Exception occurs", e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } return Response.status(Response.Status.OK).entity(rating).build(); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/admin/ReviewManagementAdminAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/admin/ReviewManagementAdminAPIImpl.java new file mode 100644 index 00000000000..97bc433e172 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/admin/ReviewManagementAdminAPIImpl.java @@ -0,0 +1,102 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.device.application.mgt.store.api.services.impl.admin; + +import io.swagger.annotations.ApiParam; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.ReviewManagementException; +import org.wso2.carbon.device.application.mgt.common.services.ReviewManager; +import org.wso2.carbon.device.application.mgt.common.wrapper.ReviewWrapper; +import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException; +import org.wso2.carbon.device.application.mgt.core.util.APIUtil; +import org.wso2.carbon.device.application.mgt.store.api.services.admin.ReviewManagementAdminAPI; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.Response; + +/** + * Review Management related jax-rs APIs. + */ +@Path("/admin/reviews") +public class ReviewManagementAdminAPIImpl implements ReviewManagementAdminAPI { + + private static Log log = LogFactory.getLog(ReviewManagementAdminAPIImpl.class); + + @Override + @PUT + @Consumes("application/json") + @Path("/{uuid}/{reviewId}") + public Response updateReview( + @ApiParam ReviewWrapper updatingReview, + @PathParam("uuid") String uuid, + @PathParam("reviewId") int reviewId) { + ReviewManager reviewManager = APIUtil.getReviewManager(); + try { + if (reviewManager.updateReview(updatingReview, reviewId, uuid, true)) { + return Response.status(Response.Status.OK).entity(updatingReview).build(); + } else { + String msg = "Review updating failed. Please contact the administrator"; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } catch (ReviewManagementException e) { + String msg = "Error occurred while retrieving comments."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (NotFoundException e) { + String msg = "Couldn't found application release data for UUID " + uuid + " or Review for review ID: " + reviewId; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred when getting application release data for application release UUID:." + uuid; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } + } + + @Override + @DELETE + @Path("/{uuid}/{reviewId}") + public Response deleteReview( + @PathParam("uuid") String uuid, + @PathParam("reviewId") int reviewId) { + + ReviewManager reviewManager = APIUtil.getReviewManager(); + try { + reviewManager.deleteReview(uuid, reviewId, true); + return Response.status(Response.Status.OK).entity("Review is deleted successfully.").build(); + + } catch (NotFoundException e) { + String msg = "Couldn't found an application review to delete which match with the request."; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ReviewManagementException e) { + String msg = "Error occurred while deleting the comment."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while getting application release data."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } +} \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/test/java/org/wso2/carbon/device/application/mgt/store/api/services/util/CommentMgtTestHelper.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/test/java/org/wso2/carbon/device/application/mgt/store/api/services/util/CommentMgtTestHelper.java index c6b6b5f2a6b..4ad4594f4fd 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/test/java/org/wso2/carbon/device/application/mgt/store/api/services/util/CommentMgtTestHelper.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/test/java/org/wso2/carbon/device/application/mgt/store/api/services/util/CommentMgtTestHelper.java @@ -17,32 +17,32 @@ */ package org.wso2.carbon.device.application.mgt.store.api.services.util; -import org.wso2.carbon.device.application.mgt.common.ReviewTmp; +import org.wso2.carbon.device.application.mgt.common.response.Review; /** - * Helper class for ReviewTmp Management API test cases. + * Helper class for Review Management API test cases. */ public class CommentMgtTestHelper { - private static final String COMMENT_TEXT = "Dummy ReviewTmp"; + private static final String COMMENT_TEXT = "Dummy Review"; private static final String CREATED_BY = "TEST_CREATED_BY"; private static final String MODIFIED_BY = "TEST_MODIFIED_BY"; private static final int PARENT_ID = 123; private static final int COMMENT_ID = 1; /** - * Creates a ReviewTmp with given text and given uuid. - * If the text is null, the COMMENT_TEXT will be used as the Dummy ReviewTmp. + * Creates a Review with given text and given uuid. + * If the text is null, the COMMENT_TEXT will be used as the Dummy Review. * - * @param commentText : Text of the ReviewTmp - * @return ReviewTmp + * @param commentText : Text of the Review + * @return Review */ - public static ReviewTmp getDummyComment(String commentText, String uuid) { - ReviewTmp reviewTmp = new ReviewTmp(); + public static Review getDummyComment(String commentText, String uuid) { + Review reviewTmp = new Review(); reviewTmp.setId(COMMENT_ID); reviewTmp.setUsername(CREATED_BY); - reviewTmp.setComment(commentText != null ? commentText : COMMENT_TEXT); + reviewTmp.setContent(commentText != null ? commentText : COMMENT_TEXT); return reviewTmp; } diff --git a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql index b060ec76526..d1696c6f37c 100644 --- a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql +++ b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/h2.sql @@ -10,7 +10,7 @@ CREATE TABLE IF NOT EXISTS AP_APP( STATUS VARCHAR(45) NOT NULL DEFAULT 'ACTIVE', SUB_TYPE VARCHAR(45) NOT NULL, CURRENCY VARCHAR(45) NULL DEFAULT '$', - RATING INTEGER NULL, + RATING DOUBLE NULL DEFAULT NULL, DEVICE_TYPE_ID INTEGER NOT NULL, PRIMARY KEY (ID) );