
com.adobe.aem.formsndocuments.rnc.ReviewManagementServiceImpl Maven / Gradle / Ivy
/***************************************************************************
* ADOBE CONFIDENTIAL
* ___________________
*
* Copyright 2013 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and may be covered by U.S. and Foreign Patents,
* patents in process, and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package com.adobe.aem.formsndocuments.rnc;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.ValueFormatException;
import com.adobe.aem.formsndocuments.util.FMUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.jcr.base.util.AccessControlUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.adobe.aem.formsndocuments.exception.FormsNDocumentsException;
import com.adobe.aem.formsndocuments.util.RnCUtil;
import com.adobe.granite.resourceresolverhelper.ResourceResolverHelper;
import com.adobe.granite.taskmanagement.Task;
import com.adobe.granite.taskmanagement.TaskManager;
import com.adobe.granite.taskmanagement.TaskManagerException;
import com.adobe.granite.workflow.exec.Status;
import com.adobe.aemforms.fm.exception.FormsMgrException;
import com.adobe.aem.formsndocuments.util.FMConstants;
import javax.jcr.security.Privilege;
/**
* The ReviewManagementService
is the service which provides
* functionality to support Review Management.
*
* @author sakarora
*/
@Component(immediate = true)
@Service(value = ReviewManagementService.class)
public class ReviewManagementServiceImpl implements ReviewManagementService {
private static final String REVIEW_CONTAINER_PATH = "/jcr:content/reviewcontainer";
private static final String REVIEW_GROUPS_PATH = "forms/rnc";
private static final String METADATA_PATH = "/jcr:content/metadata";
private static final String EVERYONE = "everyone";
private static final String REMOVED_REVIEWERS = "removedReviewers";
private static final String ADDED_REVIEWERS = "addedReviewers";
private static final String MIXIN_MODIFY = "mix:lastModified";
private static final String MIXIN_ACESS = "rep:AccessControllable";
private static final String NT_UNSTRUCTURED = "nt:unstructured";
@Reference(referenceInterface = SlingRepository.class)
SlingRepository slingRepository;
@Reference(referenceInterface = ResourceResolverHelper.class)
ResourceResolverHelper resourceResolverHelper;
@Reference(referenceInterface = ResourceResolverFactory.class)
ResourceResolverFactory resourceResolverFactory;
private static Logger logger = LoggerFactory
.getLogger(ReviewManagementServiceImpl.class);
private void createReviewContainer(String assetPath, String initiatorId, Session session,
ResourceResolver resourceResolver) throws FormsNDocumentsException {
logger.trace("Entering createReviewContainer.");
try {
Node asset = RnCUtil.checkNodeExistance(assetPath, resourceResolver);
UserManager um = resourceResolver.adaptTo(UserManager.class);
// If review container is not present i.e. when review is Created for first time then,
// Add reviewcontainer & reviewtasks node and deny jcr:all permission to forms-users group.
if (!asset.hasNode(REVIEW_CONTAINER_PATH.substring(1))) {
// Create reviewcontainer node
Node reviewContainer = asset.addNode(REVIEW_CONTAINER_PATH.substring(1),
FMConstants.SLING_FOLDER_NODETYPE);
reviewContainer.addMixin(MIXIN_MODIFY);
// Create reviewtasks node
Node reviewTasks = asset.addNode(RnCUtil.REVIEW_TASKS_PATH.substring(1),
FMConstants.SLING_FOLDER_NODETYPE);
reviewTasks.addMixin(MIXIN_MODIFY);
// Deny jcr:all permission to everyone on reviewtasks node.
Authorizable formsUserAuth = um.getAuthorizable(EVERYONE);
AccessControlUtil.replaceAccessControlEntry(session, assetPath + RnCUtil.REVIEW_TASKS_PATH,
formsUserAuth.getPrincipal(), new String[] {}, new String[] { Privilege.JCR_ALL },
new String[] {}, null);
// Provide required permission to service user.
Authorizable serviceUserAuth = um.getAuthorizable(session.getUserID());
AccessControlUtil.replaceAccessControlEntry(session, assetPath + RnCUtil.REVIEW_TASKS_PATH,
serviceUserAuth.getPrincipal(), new String[]{ Privilege.JCR_READ, Privilege.JCR_VERSION_MANAGEMENT,
FMConstants.CRX_REPLICATE_PRIVILEGE, FMConstants.REP_WRITE_PRIVILEGE, Privilege.JCR_MODIFY_ACCESS_CONTROL,
Privilege.JCR_READ_ACCESS_CONTROL }, new String[]{}, new String[]{}, null);
}
// Provide jcr:read & rep:write permission to review initiator on reviewtasks node whenever review is initiated.
Authorizable initiatorAuth = um.getAuthorizable(initiatorId);
AccessControlUtil.replaceAccessControlEntry(session, assetPath + RnCUtil.REVIEW_TASKS_PATH,
initiatorAuth.getPrincipal(), new String[] { Privilege.JCR_READ, FMConstants.REP_WRITE_PRIVILEGE },
new String[] {}, new String[] {}, null);
session.save();
} catch (RepositoryException e) {
logger.error("Exception while creating review container for asset "
+ assetPath , e);
Object[] args = { assetPath };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_022, args);
}
logger.trace("Exiting createReviewContainer.");
}
private String createReviewNode(String assetPath, String reviewId,
String reviewGroupId, Session session,
ResourceResolver resourceResolver) throws FormsNDocumentsException {
logger.trace("Entering createReviewNode.");
try {
Node asset = RnCUtil
.checkNodeExistance(assetPath, resourceResolver);
reviewId = reviewId.replace("\"", "_");
String reviewNodePath = REVIEW_CONTAINER_PATH.substring(1) + "/"
+ reviewId;
Node reviewContainer = asset.addNode(reviewNodePath,
NT_UNSTRUCTURED);
reviewContainer.addMixin(MIXIN_MODIFY);
reviewContainer.addMixin(MIXIN_ACESS);
UserManager um = resourceResolver.adaptTo(UserManager.class);
// Deny write permission to everyone.
Authorizable everyoneAuth = um.getAuthorizable(EVERYONE);
AccessControlUtil.replaceAccessControlEntry(session, assetPath
+ "/" + reviewNodePath, everyoneAuth.getPrincipal(),
new String[] {}, new String[] { FMConstants.REP_WRITE_PRIVILEGE },
new String[] {}, null);
// Provide write permission to review group.
Authorizable reviewGrpAuth = um.getAuthorizable(reviewGroupId);
AccessControlUtil.replaceAccessControlEntry(session, assetPath
+ "/" + reviewNodePath, reviewGrpAuth.getPrincipal(),
new String[] { FMConstants.REP_WRITE_PRIVILEGE }, new String[] {},
new String[] {}, null);
// Provide write permission to service user.
Authorizable serviceUserAuth = um.getAuthorizable(session.getUserID());
AccessControlUtil.replaceAccessControlEntry(session, assetPath
+ "/" + reviewNodePath, serviceUserAuth.getPrincipal(),
new String[]{ FMConstants.REP_WRITE_PRIVILEGE }, new String[]{},
new String[]{}, null);
} catch (RepositoryException e) {
logger.error("Exception while creating review node for asset "
+ assetPath + " exception: " , e);
Object[] args = { assetPath };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_009, args);
}
logger.trace("Exiting createReviewNode.");
return reviewId;
}
private Task addReviewerTask(String reviewProjectId, String reviewName,
String deadline, String reviewer, String assetPath,
String reviewGroupId, String reviewDescription, ResourceResolver bundleResourceResolver,
ResourceResolver resourceResolver) throws FormsNDocumentsException {
logger.trace("Entering addReviewerTask.");
Task task = null;
try {
task = RnCUtil.createTask(reviewProjectId, reviewName, deadline,
reviewer, assetPath, reviewDescription, bundleResourceResolver, resourceResolver);
} catch (TaskManagerException e) {
logger.error("Exception while creating Task " , e);
Object[] args=null;
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_006, args);
}
logger.trace("Exiting addReviewerTask.");
return task;
}
private void removeReviewerTask(String reviewProjectName, String reviewer,
String reviewGroupId, String reviewInitiator,
ResourceResolver resourceResolver) throws FormsNDocumentsException {
logger.trace("Entering removeReviewerTask.");
if (reviewProjectName == null || reviewer == null
|| reviewGroupId == null) {
return;
}
if (reviewProjectName.isEmpty() || reviewer.isEmpty()
|| reviewGroupId.isEmpty()) {
return;
}
try {
TaskManager taskManager = resourceResolver
.adaptTo(TaskManager.class);
Task task = taskManager.getTask(reviewProjectName, true);
if (task != null) {
List subTaskList = task.getSubTasks();
if (subTaskList != null) {
for (Task subTask : subTaskList) {
String assignee = subTask.getCurrentAssignee();
if (assignee.equals(reviewer)
&& !Status.COMPLETE.equals(subTask.getStatus())) {
taskManager.terminateTask(subTask.getId());
}
}
}
}
} catch (TaskManagerException e) {
logger.error("Exception while terminating Task " , e);
Object[] args=null;
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_007, args);
}
logger.trace("Exiting removeReviewerTask.");
}
private void addAssetReviewInfo(String assetPath, String reviewName,
String reviewDescription, String reviewProjectId,
String deadline, String reviewGroup, String reviewId,
ResourceResolver resourceResolver) throws FormsNDocumentsException {
logger.trace("Entering addAssetReviewInfo.");
try {
Node asset = RnCUtil.getNode(assetPath + METADATA_PATH,
resourceResolver);
if (asset == null) {
return;
}
String initiatorId = resourceResolverHelper.getResourceResolverAs(
Session.class).getUserID();
Node review = RnCUtil.getNode(assetPath + REVIEW_CONTAINER_PATH
+ "/" + reviewId, resourceResolver);
asset.setProperty(RnCUtil.UNDER_REVIEW, true);
asset.setProperty(RnCUtil.REVIEW_ID, reviewId);
asset.setProperty(RnCUtil.REVIEW_INITIATOR, initiatorId);
review.setProperty(RnCUtil.REVIEW_PROJECT_NAME, reviewProjectId);
review.setProperty(RnCUtil.REVIEW_NAME, reviewName);
review.setProperty(RnCUtil.REVIEW_ID, reviewId);
review.setProperty(RnCUtil.REVIEW_INITIATOR, initiatorId);
review.setProperty(RnCUtil.REVIEW_DESCRIPTION, reviewDescription);
review.setProperty(RnCUtil.REVIEW_GROUP, reviewGroup);
review.setProperty(RnCUtil.REVIEW_DEADLINE, deadline);
} catch (RepositoryException e) {
logger.error("Exception while setting Review state " , e);
Object[] args = { assetPath };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_010, args);
}
logger.trace("Exiting addAssetReviewInfo.");
}
private void removeAssetReviewInfo(String assetPath,
ResourceResolver resourceResolver) throws FormsNDocumentsException {
logger.trace("Entering addAssetReviewInfo.");
try {
Node asset = RnCUtil.getNode(assetPath + METADATA_PATH,
resourceResolver);
if (asset == null) {
return;
}
asset.setProperty(RnCUtil.UNDER_REVIEW, false);
String reviewId = "";
if (asset.hasProperty(RnCUtil.REVIEW_ID)) {
reviewId = asset.getProperty(RnCUtil.REVIEW_ID).getString();
asset.getProperty(RnCUtil.REVIEW_ID).remove();
}
if (asset.hasProperty(RnCUtil.REVIEW_INITIATOR)) {
asset.getProperty(RnCUtil.REVIEW_INITIATOR).remove();
}
Node review = RnCUtil.getNode(assetPath + REVIEW_CONTAINER_PATH
+ "/" + reviewId, resourceResolver);
if (review != null && review.hasProperty(RnCUtil.REVIEW_GROUP)) {
review.getProperty(RnCUtil.REVIEW_GROUP).remove();
}
} catch (RepositoryException e) {
logger.error("Exception while clearing review state " , e);
Object[] args = { assetPath };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_011, args);
}
logger.trace("Exiting addAssetReviewInfo.");
}
private void cleanUpPermissions(String assetPath,
String reviewGroup, String reviewID, ResourceResolver bundleResourceResolver,
ResourceResolver currentResourceResolver) throws FormsNDocumentsException {
logger.trace("Entering cleanUpPermissions.");
try {
String reviewContainerPath = assetPath + REVIEW_CONTAINER_PATH + "/"
+ reviewID;
Node reviewContainerNode = RnCUtil.getNode(reviewContainerPath, currentResourceResolver);
if (reviewContainerNode == null) {
// First Review no comments node, implies no permissions
// applied, so return.
return;
}
UserManager um = bundleResourceResolver.adaptTo(UserManager.class);
Authorizable authorizable = um.getAuthorizable(EVERYONE);
Session bundleSession = bundleResourceResolver.adaptTo(Session.class);
AccessControlUtil.replaceAccessControlEntry(bundleSession, reviewContainerPath,
authorizable.getPrincipal(), new String[] {},
new String[] {}, new String[] { FMConstants.REP_WRITE_PRIVILEGE },
null);
authorizable = um.getAuthorizable(reviewGroup);
AccessControlUtil.replaceAccessControlEntry(bundleSession, reviewContainerPath,
authorizable.getPrincipal(), new String[] {},
new String[] {}, new String[] { FMConstants.REP_WRITE_PRIVILEGE },
null);
if(reviewContainerNode.hasProperty(RnCUtil.REVIEW_INITIATOR)) {
String initiatorId = reviewContainerNode.getProperty(RnCUtil.REVIEW_INITIATOR).getString();
// Remove read & write permission of review initiator from reviewtasks node.
Authorizable initiatorAuth = um.getAuthorizable(initiatorId);
AccessControlUtil.replaceAccessControlEntry(bundleSession,
assetPath + RnCUtil.REVIEW_TASKS_PATH, initiatorAuth.getPrincipal(),
new String[] {}, new String[] {}, new String[] {Privilege.JCR_READ, FMConstants.REP_WRITE_PRIVILEGE}, null);
}
} catch (RepositoryException e) {
logger.error("Exception while removing permissions on comments node for asset "
+ assetPath , e);
Object[] args = { assetPath };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_016, args);
}
logger.trace("Exiting cleanUpPermissions.");
}
private Map> getReviewersDiff(String[] newList,
String reviewerGroupId, ResourceResolver bundleResourceResolver)
throws FormsNDocumentsException {
logger.trace("Entering getReviewersDiff.");
Map> reviewerDiff = new HashMap>();
List reviewersList = new ArrayList();
List removedReviewers = new ArrayList();
List addedReviewers = new ArrayList();
try {
UserManager um = bundleResourceResolver.adaptTo(UserManager.class);
Group reviewGroup = (Group) um.getAuthorizable(reviewerGroupId);
Iterator iterator = reviewGroup.getDeclaredMembers();
while (iterator.hasNext()) {
String id = iterator.next().getID();
reviewersList.add(id);
}
for (String id : reviewersList) {
if (!RnCUtil.isInArray(id, newList)) {
removedReviewers.add(id);
}
}
for (String id : newList) {
if (!reviewersList.contains(id)) {
addedReviewers.add(id);
}
}
reviewerDiff.put(REMOVED_REVIEWERS, removedReviewers);
reviewerDiff.put(ADDED_REVIEWERS, addedReviewers);
} catch (RepositoryException e) {
logger.error("Exception while retrieving group members for group "
+ reviewerGroupId , e);
Object[] args = { reviewerGroupId };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_017, args);
}
logger.trace("Exiting getReviewersDiff.");
return reviewerDiff;
}
public boolean isUnderReview(ResourceResolver resourceResolver, String assetPath)
throws FormsNDocumentsException {
if (resourceResolver != null) {
try {
Node asset = RnCUtil.getNode(assetPath + METADATA_PATH,
resourceResolver);
if (asset.hasProperty(RnCUtil.UNDER_REVIEW) &&
asset.getProperty(RnCUtil.UNDER_REVIEW).getBoolean())
return true;
} catch (ValueFormatException e){
logger.error("Illegal Review State. " , e);
Object[] args=null;
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_008, args);
} catch (RepositoryException e) {
logger.error("Exception while retrieving bundle context " , e);
Object[] args = { e.getMessage() };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_005, args);
}
}
return false;
}
/**
* {@inheritDoc}
*/
public Map fetchReviewInfo(ResourceResolver resourceResolver, String assetPath)
throws FormsNDocumentsException {
logger.trace("Entering fetchReviewInfo.");
RnCUtil.checkAssetPathArgument(assetPath);
Map reviewInfo = new HashMap();
try {
if (resourceResolver != null) {
// This check ensures, the person fetching the review information has
// access to the asset.
Node asset = RnCUtil.checkNodeExistance(assetPath + METADATA_PATH,
resourceResolver);
if (!isUnderReview(resourceResolver, assetPath)) {
logger.error(" Asset " + assetPath
+ " is currently not under review.");
Object[] args = { assetPath };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_019, args);
}
String reviewId = "";
if (asset.hasProperty(RnCUtil.REVIEW_ID)) {
reviewId = asset.getProperty(RnCUtil.REVIEW_ID).getString();
reviewInfo.put(RnCUtil.REVIEW_ID, reviewId);
}
Node review = RnCUtil.checkNodeExistance(assetPath
+ REVIEW_CONTAINER_PATH + "/" + reviewId, resourceResolver);
if (review.hasProperty(RnCUtil.REVIEW_PROJECT_NAME)) {
reviewInfo.put(RnCUtil.REVIEW_PROJECT_NAME,
review.getProperty(RnCUtil.REVIEW_PROJECT_NAME)
.getString());
}
if (review.hasProperty(RnCUtil.REVIEW_NAME)) {
reviewInfo.put(RnCUtil.REVIEW_NAME,
review.getProperty(RnCUtil.REVIEW_NAME).getString());
}
if (review.hasProperty(RnCUtil.REVIEW_INITIATOR)) {
reviewInfo.put(RnCUtil.REVIEW_INITIATOR,
review.getProperty(RnCUtil.REVIEW_INITIATOR)
.getString());
}
if (review.hasProperty(RnCUtil.REVIEW_DESCRIPTION)) {
reviewInfo.put(RnCUtil.REVIEW_DESCRIPTION,
review.getProperty(RnCUtil.REVIEW_DESCRIPTION)
.getString());
}
if (review.hasProperty(RnCUtil.REVIEW_GROUP)) {
reviewInfo.put(RnCUtil.REVIEW_GROUP,
review.getProperty(RnCUtil.REVIEW_GROUP).getString());
}
if (review.hasProperty(RnCUtil.REVIEW_DEADLINE)) {
reviewInfo
.put(RnCUtil.REVIEW_DEADLINE,
review.getProperty(RnCUtil.REVIEW_DEADLINE)
.getString());
}
}
} catch (FormsNDocumentsException e) {
throw e;
} catch (ValueFormatException e) {
logger.error("Illegal Review State. " , e);
Object[] args=null;
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_008, args);
} catch (RepositoryException e) {
logger.error("Exception while retrieving bundle context " , e);
Object[] args = { e.getMessage() };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_005, args);
}
logger.trace("Exiting fetchReviewInfo.");
return reviewInfo;
}
/**
* {@inheritDoc}
*/
public void beginReview(String reviewName, String reviewDescription,
String deadline, String[] reviewers, String assetPath)
throws FormsNDocumentsException {
logger.trace("Entering beginReview.");
Session bundleSession = null;
ResourceResolver bundleResourceResolver = null;
try {
// bundleSession is first used to check the validity of the
// reviewers passed and then used for creating review (creates
// review node, creates review project and review tasks, creates a
// new review group and add reviewers to it, applies ACL to review
// node, add review information).
bundleSession = FMUtils.getFnDServiceUserSession(slingRepository);
bundleResourceResolver = RnCUtil.getResourceResolver(bundleSession,
resourceResolverFactory);
RnCUtil.checkAssetPathArgument(assetPath);
RnCUtil.checkCreateReviewArguments(reviewName, reviewers, deadline,
bundleResourceResolver);
ResourceResolver resourceResolver = resourceResolverHelper
.getResourceResolver();
String initiatorId = resourceResolverHelper.getResourceResolverAs(
Session.class).getUserID();
createReviewContainer(assetPath, initiatorId, bundleSession,
bundleResourceResolver);
String underReviewProp = METADATA_PATH.substring(1) + "/"
+ RnCUtil.UNDER_REVIEW;
Node asset = RnCUtil
.checkNodeExistance(assetPath, resourceResolver);
if (asset.hasProperty(underReviewProp)
&& asset.getProperty(underReviewProp).getBoolean()) {
logger.error(" Asset "
+ assetPath
+ " is already under review, can not start a new review.");
Object[] args = { assetPath };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_003, args);
}
Task task = RnCUtil.createProject(reviewName, assetPath, deadline,
initiatorId, bundleResourceResolver, resourceResolver);
String reviewProjectID = task.getId();
String reviewProjectName = task.getName();
Group reviewGroup = RnCUtil.createGroup(reviewProjectName + "_" + System.currentTimeMillis(), REVIEW_GROUPS_PATH,
bundleResourceResolver);
String reviewGroupId = reviewGroup.getID();
RnCUtil.addUserToGroup(initiatorId, reviewGroupId,
bundleResourceResolver);
String reviewId = createReviewNode(assetPath, reviewProjectName,
reviewGroupId, bundleSession, bundleResourceResolver);
addAssetReviewInfo(assetPath, reviewName, reviewDescription,
reviewProjectID, deadline, reviewGroupId, reviewId,
bundleResourceResolver);
for (String reviewer : reviewers) {
addReviewerTask(reviewProjectID, reviewName, deadline, reviewer,
assetPath, reviewGroupId, reviewDescription, bundleResourceResolver,
resourceResolver);
RnCUtil.addUserToGroup(reviewer, reviewGroupId, bundleResourceResolver);
}
bundleSession.save();
} catch (RepositoryException e) {
logger.error("Exception while creation of review " , e);
Object[] args=null;
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_004, args);
} catch (LoginException e) {
logger.error("Exception while retrieving bundle context " , e);
Object[] args = { e.getMessage() };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_005, args);
} catch (TaskManagerException e) {
logger.error("Exception while creation of Task " , e);
Object[] args=null;
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_006, args);
} finally {
if (bundleResourceResolver != null) {
bundleResourceResolver.close();
}
if (bundleSession != null) {
bundleSession.logout();
}
}
logger.trace("Exiting beginReview.");
}
/**
* {@inheritDoc}
*/
public void endReview(String assetPath) throws FormsNDocumentsException {
logger.trace("Entering endReview.");
RnCUtil.checkAssetPathArgument(assetPath);
String reviewProjectName;
String reviewID;
ResourceResolver currentResourceResolver = resourceResolverHelper.getResourceResolver();
String currentUserID = currentResourceResolver.getUserID();
RnCUtil.checkNodeExistance(assetPath, currentResourceResolver);
Map reviewInfo = fetchReviewInfo(currentResourceResolver, assetPath);
// check for initiator ensures that only the initiator is able to take further actions to end review.
if (!currentUserID.equals(reviewInfo.get(RnCUtil.REVIEW_INITIATOR))) {
logger.error(" Current User " + currentUserID + " is not the initiator of review for asset " + assetPath + " , and only initiator can end the review.");
Object[] args = { currentUserID, assetPath };
throw new FormsNDocumentsException(FormsNDocumentsException.ERROR_AEM_FMG_700_020, args);
}
reviewProjectName = reviewInfo.get(RnCUtil.REVIEW_PROJECT_NAME);
reviewID = reviewInfo.get(RnCUtil.REVIEW_ID);
ResourceResolver bundleResourceResolver = null;
try {
RnCUtil.terminateProjectActiveTasks(reviewProjectName, currentResourceResolver);
removeAssetReviewInfo(assetPath, currentResourceResolver);
currentResourceResolver.commit();
// bundle session is used for ending review (terminates review
// tasks, completes review project, removes review group ACL,
// deletes review group, update review information)
bundleResourceResolver = FMUtils.getFnDServiceUserResourceResolver(resourceResolverFactory);
cleanUpPermissions(assetPath, reviewInfo.get(RnCUtil.REVIEW_GROUP), reviewID, bundleResourceResolver, currentResourceResolver);
RnCUtil.removeGroup(reviewInfo.get(RnCUtil.REVIEW_GROUP), bundleResourceResolver);
bundleResourceResolver.commit();
} catch (RepositoryException e) {
logger.error("Exception while ending review " , e);
Object[] args = { assetPath };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_012, args);
} catch (LoginException e) {
logger.error("Exception while retrieving bundle context " , e);
Object[] args = { e.getMessage() };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_005, args);
} catch (TaskManagerException e) {
logger.error("Exception while terminating task " , e);
Object[] args=null;
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_007, args);
} catch (PersistenceException e) {
logger.error("Exception while saving the updated review state " , e);
Object[] args = { assetPath };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_012, args);
} finally {
if (bundleResourceResolver != null) {
bundleResourceResolver.close();
}
}
logger.trace("Exiting endReview.");
}
/**
* {@inheritDoc}
*/
public void updateReview(String assetPath, String reviewDescription,
String deadline, String[] reviewers)
throws FormsNDocumentsException {
logger.trace("Entering updateReview.");
ResourceResolver bundleResourceResolver = null;
try {
// bundleSession is first used to check the validity of the reviewers passed and then used for updating review
// (terminates/completes review tasks as per addition and removal of reviewers, updates review group, update review information).
bundleResourceResolver = FMUtils.getFnDServiceUserResourceResolver(resourceResolverFactory);
ResourceResolver currentResourceResolver = resourceResolverHelper.getResourceResolver();
RnCUtil.checkUpdateReviewArguments(reviewers, deadline, bundleResourceResolver);
RnCUtil.checkNodeExistance(assetPath, currentResourceResolver);
// check for initiator ensures that only the initiator is able to
// take further actions to update the review.
String currentUserID = currentResourceResolver.getUserID();
Map reviewInfo = fetchReviewInfo(currentResourceResolver, assetPath);
if (!currentUserID.equals(reviewInfo.get(RnCUtil.REVIEW_INITIATOR))) {
logger.error(" Current User " + currentUserID + " is not the initiator of review for asset " + assetPath + " , and only initiator can end the review.");
Object[] args = { currentUserID, assetPath };
throw new FormsNDocumentsException(FormsNDocumentsException.ERROR_AEM_FMG_700_020, args);
}
Node reviewNode = RnCUtil.getNode(assetPath + REVIEW_CONTAINER_PATH + "/" + reviewInfo.get(RnCUtil.REVIEW_ID), currentResourceResolver);
if (reviewNode == null) {
Object[] args = { reviewInfo.get(RnCUtil.REVIEW_ID), assetPath };
throw new FormsNDocumentsException(FormsNDocumentsException.ERROR_AEM_FMG_700_023, args);
}
if (reviewDescription != null && !reviewDescription.equals(reviewInfo.get(RnCUtil.REVIEW_DESCRIPTION))) {
RnCUtil.updateProjectDescription(reviewInfo.get(RnCUtil.REVIEW_PROJECT_NAME), reviewDescription, currentResourceResolver);
reviewNode.setProperty(RnCUtil.REVIEW_DESCRIPTION, reviewDescription);
} else {
reviewDescription = reviewInfo.get(RnCUtil.REVIEW_DESCRIPTION);
}
if (deadline != null && !deadline.equals(reviewInfo.get(RnCUtil.REVIEW_DEADLINE))) {
RnCUtil.updateProjectDeadline(reviewInfo.get(RnCUtil.REVIEW_PROJECT_NAME), deadline, currentResourceResolver);
reviewNode.setProperty(RnCUtil.REVIEW_DEADLINE, deadline);
} else {
deadline = reviewInfo.get(RnCUtil.REVIEW_DEADLINE);
}
Map> reviewersDiff = getReviewersDiff(reviewers, reviewInfo.get(RnCUtil.REVIEW_GROUP), bundleResourceResolver);
List removedReviewers = reviewersDiff.get(REMOVED_REVIEWERS);
List addedReviewers = reviewersDiff.get(ADDED_REVIEWERS);
for (String reviewer : removedReviewers) {
removeReviewerTask(reviewInfo.get(RnCUtil.REVIEW_PROJECT_NAME), reviewer, reviewInfo.get(RnCUtil.REVIEW_GROUP), reviewInfo.get(RnCUtil.REVIEW_INITIATOR), currentResourceResolver);
// Ignore removing of initiator from group.
if (!reviewer.equals(reviewInfo.get(RnCUtil.REVIEW_INITIATOR))) {
RnCUtil.removeUserFromGroup(reviewer, reviewInfo.get(RnCUtil.REVIEW_GROUP), bundleResourceResolver);
}
}
for (String reviewer : addedReviewers) {
addReviewerTask(reviewInfo.get(RnCUtil.REVIEW_PROJECT_NAME), reviewInfo.get(RnCUtil.REVIEW_NAME), deadline, reviewer, assetPath, reviewInfo.get(RnCUtil.REVIEW_GROUP), reviewDescription, bundleResourceResolver, currentResourceResolver);
RnCUtil.addUserToGroup(reviewer, reviewInfo.get(RnCUtil.REVIEW_GROUP), bundleResourceResolver);
}
bundleResourceResolver.commit();
currentResourceResolver.commit();
} catch (RepositoryException e) {
logger.error("Exception while updating review " , e);
Object[] args = { assetPath };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_013, args);
} catch (LoginException e) {
logger.error("Exception while retrieving bundle context " , e);
Object[] args = { e.getMessage() };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_005, args);
} catch (TaskManagerException e) {
logger.error("Exception while updating review state " , e);
Object[] args = { assetPath };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_014, args);
} catch (PersistenceException e) {
logger.error("Exception while saving the updated review state ", e);
Object[] args = { assetPath };
throw new FormsNDocumentsException(
FormsNDocumentsException.ERROR_AEM_FMG_700_014, args);
} finally {
if (bundleResourceResolver != null) {
bundleResourceResolver.close();
}
}
logger.trace("Exiting updateReview.");
}
@Override
public void cleanReview(String assetPath, Session currentSession,
boolean updateReviewProperties) throws FormsMgrException {
logger.trace("Entering cleanReview.");
RnCUtil.checkAssetPathArgument(assetPath);
String reviewProjectName;
String reviewID;
ResourceResolver currentResourceResolver = FMUtils.getResourceResolver(resourceResolverFactory, currentSession);
RnCUtil.checkNodeExistance(assetPath, currentResourceResolver);
Map reviewInfo = fetchReviewInfo(currentResourceResolver, assetPath);
reviewProjectName = reviewInfo.get(RnCUtil.REVIEW_PROJECT_NAME);
reviewID = reviewInfo.get(RnCUtil.REVIEW_ID);
ResourceResolver bundleResourceResolver = null;
try {
bundleResourceResolver = FMUtils.getFnDServiceUserResourceResolver(resourceResolverFactory);
/* The following condition helps define what tasks need to be executed
before an asset is being published and should not be executed before it is being deleted.*/
if (updateReviewProperties) {
try {
RnCUtil.terminateProjectActiveTasks(reviewProjectName,
bundleResourceResolver);
} catch (Exception e) {
logger.error("Exception while terminating task " , e);
}
try {
removeAssetReviewInfo(assetPath, bundleResourceResolver);
} catch (Exception e) {
logger.error("Exception while setting asset review state " , e);
}
try {
cleanUpPermissions(assetPath,
reviewInfo.get(RnCUtil.REVIEW_GROUP), reviewID,
bundleResourceResolver, currentResourceResolver);
} catch (Exception e) {
logger.error("Exception while removing review ACL " , e);
}
}
try {
RnCUtil.removeGroup(reviewInfo.get(RnCUtil.REVIEW_GROUP),
bundleResourceResolver);
} catch (Exception e) {
logger.error("Exception while removing temporary review group " , e);
}
bundleResourceResolver.commit();
} catch (Exception e) {
logger.error("Exception while retrieving bundle context " , e);
} finally {
if (bundleResourceResolver !=null ){
bundleResourceResolver.close();
}
}
logger.trace("Exiting cleanReview.");
}
public ResourceResolver getFnDServiceUserResourceResolver() {
ResourceResolver serviceResourceResolver = null;
try {
serviceResourceResolver = FMUtils.getFnDServiceUserResourceResolver(resourceResolverFactory);
} catch (LoginException e) {
logger.error("Error while retrieving service session for system user 'fd-service'", e);
}
return serviceResourceResolver;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy