Add review deleting functionality

feature/appm-store/pbac
lasanthaDLPDS 6 years ago
parent e8743f001b
commit 15dac5bc69

@ -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;
}
}

@ -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; }
}

@ -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;
}

@ -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; }
}

@ -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; }
}

@ -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<Review> replies;
public int getId() {

@ -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,19 +60,18 @@ 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 isPriviledgedUser)
@ -83,7 +81,7 @@ public interface ReviewManager {
* 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;

@ -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
*

@ -106,6 +106,9 @@ public interface ApplicationReleaseDAO {
*/
Rating getRating(String uuid, int tenantId) throws ApplicationManagementDAOException;
List<Double> getReleaseRatings(String uuid, int tenantId) throws ApplicationManagementDAOException;
/**
* To delete a particular release.

@ -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;
@ -72,7 +72,7 @@ import java.util.List;
* 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;
@ -87,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<ReviewDTO> getAllReviews(int releaseId, PaginationRequest request, int tenantId)
throws ReviewManagementDAOException;
@ -124,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<Integer> reviewIds, int tenantId) throws ReviewManagementDAOException;
void deleteAllChildCommentsOfReview(int rootParentId, int tenantId) throws ReviewManagementDAOException;
/**
* To delete comments using application details.
@ -142,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;
}

@ -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;

@ -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<Double> getReleaseRatings(String uuid, int tenantId) throws ApplicationManagementDAOException {
Connection connection;
List<Double> 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.
*

@ -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<Integer> 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 {

@ -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 {

@ -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<ApplicationRelease> 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());

@ -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: "
@ -223,6 +223,7 @@ 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;
}
@ -233,7 +234,7 @@ public class ReviewManagerImpl implements ReviewManager {
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.beginDBTransaction();
@ -372,33 +373,96 @@ public class ReviewManagerImpl implements ReviewManager {
return review;
}
private ReviewNode<ReviewDTO> getReviewNode(ReviewNode<ReviewDTO> node, int reviewId) {
if (node.getData().getId() == reviewId) {
return node;
} else {
for (ReviewNode<ReviewDTO> each : node.getChildren()) {
ReviewNode<ReviewDTO> result = getReviewNode(each, reviewId);
if (result != null) {
return result;
}
}
}
return null;
}
private List<Integer> getDeletingReviewIds(ReviewNode<ReviewDTO> node, List<Integer> reviewIds) {
reviewIds.add(node.getData().getId());
if (node.getChildren().isEmpty()){
return reviewIds;
}
for (ReviewNode<ReviewDTO> 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<ReviewDTO> replyComments = this.reviewDAO.getReplyComments(rootReview.getId(), tenantId);
ReviewNode<ReviewDTO> reviewNode = new ReviewNode<>(rootReview);
replyComments.sort(Comparator.comparing(ReviewDTO::getId));
for (ReviewDTO reply : replyComments) {
reviewNode = findAndSetChild(reviewNode, reply);
}
ReviewNode<ReviewDTO> deletingRevieNode = getReviewNode(reviewNode, existingReview.getId());
List<Integer> 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();
}
@ -447,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);
@ -461,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;
@ -474,47 +538,30 @@ public class ReviewManagerImpl implements ReviewManager {
} else {
updatedRating = newTotalRating / numOfUsers;
}
this.applicationReleaseDAO.updateRatingValue(uuid, updatedRating, numOfUsers);
List<Double> 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);
}
}

@ -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);
}

@ -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 {

@ -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.",

@ -29,7 +29,7 @@ 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.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;
@ -53,12 +53,12 @@ info = @Info(
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "name", value = "ReviewManagementAdminService"),
@ExtensionProperty(name = "context", value = "/api/application-mgt/v1.0/review"),
@ExtensionProperty(name = "context", value = "/api/application-mgt/v1.0/admin/review"),
})
}
),
tags = {
@Tag(name = "review_management", description = "ReviewTmp Management related Admin APIs")
@Tag(name = "review_management", description = "Review Management related Admin APIs")
}
)
@Scopes(
@ -73,7 +73,7 @@ scopes = {
)
@Path("/admin/reviews")
@Api(value = "ReviewTmp Management")
@Api(value = "Review Management")
@Produces(MediaType.APPLICATION_JSON)
public interface ReviewManagementAdminAPI {
String SCOPE = "scope";
@ -100,7 +100,7 @@ String SCOPE = "scope";
@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."),

@ -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 {
@ -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();

@ -20,11 +20,9 @@ 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.ReviewDoesNotExistException;
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.ForbiddenException;
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;
@ -37,7 +35,7 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
/**
* ReviewTmp Management related jax-rs APIs.
* Review Management related jax-rs APIs.
*/
@Path("/admin/reviews")
public class ReviewManagementAdminAPIImpl implements ReviewManagementAdminAPI {
@ -84,20 +82,21 @@ public class ReviewManagementAdminAPIImpl implements ReviewManagementAdminAPI {
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, 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 (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();
}
}
}

@ -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;
}

@ -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)
);

Loading…
Cancel
Save