DeleteManageComponent.java
/***************************************************************************
* Copyright (C) 2003-2009 eXo Platform SAS.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see<http://www.gnu.org/licenses/>.
*
**************************************************************************/
package org.exoplatform.ecm.webui.component.explorer.rightclick.manager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import javax.jcr.AccessDeniedException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.PropertyIterator;
import javax.jcr.ReferentialIntegrityException;
import javax.jcr.Session;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.version.VersionException;
import javax.portlet.PortletPreferences;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.Validate;
import org.exoplatform.ecm.webui.component.explorer.UIConfirmMessage;
import org.exoplatform.ecm.webui.component.explorer.UIJCRExplorer;
import org.exoplatform.ecm.webui.component.explorer.UIWorkingArea;
import org.exoplatform.ecm.webui.component.explorer.control.filter.CanDeleteNodeFilter;
import org.exoplatform.ecm.webui.component.explorer.control.filter.IsNotEditingDocumentFilter;
import org.exoplatform.ecm.webui.component.explorer.control.filter.IsNotLockedFilter;
import org.exoplatform.ecm.webui.component.explorer.control.filter.IsNotMandatoryChildNode;
import org.exoplatform.ecm.webui.component.explorer.control.filter.IsNotTrashHomeNodeFilter;
import org.exoplatform.ecm.webui.component.explorer.control.listener.UIWorkingAreaActionListener;
import org.exoplatform.ecm.webui.utils.JCRExceptionManager;
import org.exoplatform.ecm.utils.lock.LockUtil;
import org.exoplatform.ecm.webui.utils.PermissionUtil;
import org.exoplatform.ecm.webui.utils.Utils;
import org.exoplatform.services.cms.actions.ActionServiceContainer;
import org.exoplatform.services.cms.documents.TrashService;
import org.exoplatform.services.cms.folksonomy.NewFolksonomyService;
import org.exoplatform.services.cms.jcrext.activity.ActivityCommonService;
import org.exoplatform.services.cms.link.LinkManager;
import org.exoplatform.services.cms.link.LinkUtils;
import org.exoplatform.services.cms.relations.RelationsService;
import org.exoplatform.services.cms.taxonomy.TaxonomyService;
import org.exoplatform.services.cms.templates.TemplateService;
import org.exoplatform.services.cms.thumbnail.ThumbnailService;
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.jcr.ext.audit.AuditService;
import org.exoplatform.services.jcr.ext.common.SessionProvider;
import org.exoplatform.services.listener.ListenerService;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.wcm.core.NodetypeConstant;
import org.exoplatform.services.wcm.utils.WCMCoreUtils;
import org.exoplatform.web.application.ApplicationMessage;
import org.exoplatform.web.application.RequestContext;
import org.exoplatform.webui.config.annotation.ComponentConfig;
import org.exoplatform.webui.config.annotation.EventConfig;
import org.exoplatform.webui.core.UIApplication;
import org.exoplatform.webui.core.UIComponent;
import org.exoplatform.webui.core.UIPopupWindow;
import org.exoplatform.webui.event.Event;
import org.exoplatform.webui.ext.filter.UIExtensionFilter;
import org.exoplatform.webui.ext.filter.UIExtensionFilters;
import org.exoplatform.webui.ext.manager.UIAbstractManager;
import org.exoplatform.webui.ext.manager.UIAbstractManagerComponent;
/**
* Created by The eXo Platform SARL
* Author : Hoang Van Hung
* hunghvit@gmail.com
* Aug 6, 2009
*/
@ComponentConfig(
events = {
@EventConfig(listeners = DeleteManageComponent.DeleteActionListener.class)
}
)
public class DeleteManageComponent extends UIAbstractManagerComponent {
private static final Log LOG = ExoLogger.getLogger(DeleteManageComponent.class.getName());
private static final String DELETE_FILE_CONFIRM_TITLE = "UIDeleteFileConfirmMessage";
private static final String DELETE_FOLDER_CONFIRM_TITLE = "UIDeleteFolderConfirmMessage";
private static final String DELETE_ITEMS_CONFIRM_TITLE = "UIDeleteItemsConfirmMessage";
private static final int GENERIC_TYPE = 1;
private static final int FILE_TYPE = 2;
private static final int FOLDER_TYPE = 3;
private static final int FOLDERS = 1; //"001";
private static final int FILES = 2; //"010";
private static final int FILES_AND_FOLDERS = 3; //"011";
private static final int GENERIC = 4; //"100";
private static final int GENERICS_AND_FOLDERS = 5; //"101";
private static final int GENERICS_AND_FILES = 6; //"110";
private static final int GENERICS_AND_FILES_AND_FOLDERS = 7; //"111";
private static final List<UIExtensionFilter> FILTERS
= Arrays.asList(new UIExtensionFilter[]{new IsNotLockedFilter(),
new CanDeleteNodeFilter(),
new IsNotTrashHomeNodeFilter(),
new IsNotEditingDocumentFilter(),
new IsNotMandatoryChildNode()});
@UIExtensionFilters
public List<UIExtensionFilter> getFilters() {
return FILTERS;
}
private String processRemoveMultiple(String[] nodePaths, Event<?> event) throws Exception {
StringBuilder trashId = new StringBuilder();
UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
UIApplication uiApp = uiExplorer.getAncestorOfType(UIApplication.class);
Arrays.sort(nodePaths,Collections.reverseOrder());
for (int i = 0; i < nodePaths.length ; i++) {
try {
Node node = this.getNodeByPath(nodePaths[i]);
Validate.isTrue(node != null, "The ObjectId is invalid '" + nodePaths[i] + "'");
trashId.append(processRemoveOrMoveToTrash(nodePaths[i], node, event, true, true)).append(";");
} catch (PathNotFoundException path) {
uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.path-not-found-exception", null, ApplicationMessage.WARNING));
event.getRequestContext().addUIComponentToUpdateByAjax(uiApp.getUIPopupMessages());
} catch (Exception e) {
JCRExceptionManager.process(uiApp, e);
}
}
return trashId.substring(0,trashId.length() - 1);
}
private void removeAuditForNode(Node node) throws Exception {
UIJCRExplorer uiExplorer = this.getAncestorOfType(UIJCRExplorer.class);
ManageableRepository repository = uiExplorer.getRepository();
SessionProvider sessionProvider = uiExplorer.getSystemProvider();
Session session = null;
session = sessionProvider.getSession(node.getSession().getWorkspace().getName(), repository);
Node rootNode = session.getRootNode();
if (rootNode.hasNode("exo:audit") && rootNode.getNode("exo:audit").hasNode(node.getUUID())) {
rootNode.getNode("exo:audit").getNode(node.getUUID()).remove();
session.save();
}
}
/**
* Remove or MoveToTrash
*
* @param nodePath
* @param node
* @param event
* @param isMultiSelect
* @param checkToMoveToTrash
* @return
* 0: node removed
* -1: move to trash failed
* trashId: moved to trash successfully
* @throws Exception
*/
private String processRemoveOrMoveToTrash(String nodePath,
Node node,
Event<?> event,
boolean isMultiSelect,
boolean checkToMoveToTrash)
throws Exception {
String trashId="-1";
if (!checkToMoveToTrash || Utils.isInTrash(node)) {
processRemoveNode(nodePath, node, event, isMultiSelect);
return "0";
}else {
trashId = moveToTrash(nodePath, node, event, isMultiSelect);
if (!trashId.equals("-1")) {
//Broadcast the event when delete folder, in case deleting file, Thrash service will broadcast event
ListenerService listenerService = WCMCoreUtils.getService(ListenerService.class);
TrashService trashService = WCMCoreUtils.getService(TrashService.class);
node = trashService.getNodeByTrashId(trashId);
if(!isDocumentNodeType(node)
&& !node.getPrimaryNodeType().getName().equals(NodetypeConstant.NT_FILE)){
Queue<Node> queue = new LinkedList<Node>();
queue.add(node);
//Broadcast event to remove file activities
Node tempNode = null;
try {
while (!queue.isEmpty()) {
tempNode = queue.poll();
if (isDocumentNodeType(tempNode) || tempNode.getPrimaryNodeType().getName().equals(NodetypeConstant.NT_FILE)) {
listenerService.broadcast(ActivityCommonService.FILE_REMOVE_ACTIVITY, tempNode.getParent(), tempNode);
} else {
for (NodeIterator iter = tempNode.getNodes(); iter.hasNext(); ) {
Node childNode = iter.nextNode();
if(isDocumentNodeType(childNode) || childNode.isNodeType(NodetypeConstant.NT_UNSTRUCTURED) ||
childNode.isNodeType(NodetypeConstant.NT_FOLDER))
queue.add(childNode);
}
}
}
} catch (Exception e) {
if (LOG.isWarnEnabled()) {
LOG.warn(e.getMessage());
}
}
}
}
}
return trashId;
}
/**
* Move Node to Trash
* Return -1: move failed
* Return trashId: move successfully with trashId
* @param srcPath
* @param node
* @param event
* @param isMultiSelect
* @return
* @throws Exception
*/
private String moveToTrash(String srcPath, Node node, Event<?> event, boolean isMultiSelect) throws Exception {
TrashService trashService = WCMCoreUtils.getService(TrashService.class);
AuditService auditService = WCMCoreUtils.getService(AuditService.class);
boolean ret = true;
String trashId="-1";
final String virtualNodePath = srcPath;
UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
UIApplication uiApp = uiExplorer.getAncestorOfType(UIApplication.class);
try {
uiExplorer.addLockToken(node);
} catch (Exception e) {
JCRExceptionManager.process(uiApp, e);
return trashId;
}
try {
if (node.isLocked()) {
LockUtil.removeLock(node);
node.unlock();
}
//remove audit relations
if(auditService.hasHistory(node)) {
auditService.removeHistory(node);
}
//remove mixin auditable
if( node.isNodeType(Utils.EXO_AUDITABLE)){
node.removeMixin(Utils.EXO_AUDITABLE);
}
node.save();
//remove all relations that refer to this node
RelationsService relationService = uiApp.getApplicationComponent(RelationsService.class) ;
PropertyIterator iter = node.getReferences();
while (iter.hasNext()) {
Node refNode = iter.nextProperty().getParent();
relationService.removeRelation(refNode, node.getPath());
}
if (!node.isCheckedOut())
throw new VersionException("node is locked, can't move to trash node :" + node.getPath());
if (!PermissionUtil.canRemoveNode(node))
throw new AccessDeniedException("access denied, can't move to trash node:" + node.getPath());
SessionProvider sessionProvider = uiExplorer.getSessionProvider();
Node currentNode = uiExplorer.getCurrentNode();
try {
trashId = trashService.moveToTrash(node, sessionProvider);
} catch (PathNotFoundException ex) {
ret = false;
}
String currentPath = LinkUtils.getExistPath(currentNode, uiExplorer.getCurrentPath());
uiExplorer.setCurrentPath(currentPath);
uiExplorer.updateAjax(event);
} catch (LockException e) {
if (LOG.isErrorEnabled()) {
LOG.error("node is locked, can't move to trash node :" + node.getPath());
}
ApplicationMessage appMessage =
new ApplicationMessage("UIPopupMenu.msg.can-not-remove-locked-node",
new String[] {node.getPath()}, ApplicationMessage.ERROR);
appMessage.setArgsLocalized(false);
uiApp.addMessage(appMessage);
uiExplorer.updateAjax(event);
ret = false;
} catch (VersionException e) {
if (LOG.isErrorEnabled()) {
LOG.error("node is checked in, can't move to trash node:" + node.getPath());
}
removeMixinEXO_RESTORE_LOCATION(node);
ApplicationMessage appMessage =
new ApplicationMessage("UIPopupMenu.msg.can-not-remove-checked-in-node",
new String[] {node.getPath()}, ApplicationMessage.ERROR);
appMessage.setArgsLocalized(false);
uiApp.addMessage(appMessage);
uiExplorer.updateAjax(event);
ret = false;
} catch (AccessDeniedException e) {
if (LOG.isErrorEnabled()) {
LOG.error("access denied, can't move to trash node:" + node.getPath());
}
ApplicationMessage appMessage =
new ApplicationMessage("UIPopupMenu.msg.access-denied-to-delete",
new String[] {node.getPath()}, ApplicationMessage.ERROR);
appMessage.setArgsLocalized(false);
uiApp.addMessage(appMessage);
uiExplorer.updateAjax(event);
ret = false;
} catch (Exception e) {
if (LOG.isErrorEnabled()) {
LOG.error("an unexpected error occurs", e);
}
uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.unexpected-error",
new String[] {node.getPath()}, ApplicationMessage.ERROR));
uiExplorer.updateAjax(event);
ret = false;
}
if (!isMultiSelect) {
if (uiExplorer.getCurrentPath().equals(virtualNodePath))
uiExplorer.setSelectNode(LinkUtils.getParentPath(virtualNodePath));
else
uiExplorer.setSelectNode(uiExplorer.getCurrentPath());
}
return (ret)?trashId:"-1";
}
private void processRemoveNode(String nodePath, Node node, Event<?> event, boolean isMultiSelect)
throws Exception {
final String virtualNodePath = nodePath;
UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
Node currentNode = uiExplorer.getCurrentNode();
Session session = node.getSession();
UIApplication uiApp = uiExplorer.getAncestorOfType(UIApplication.class);
try {
uiExplorer.addLockToken(node);
} catch (Exception e) {
JCRExceptionManager.process(uiApp, e);
return;
}
Node parentNode = node.getParent();
uiExplorer.addLockToken(parentNode);
try {
// If node has taxonomy
TaxonomyService taxonomyService = uiExplorer.getApplicationComponent(TaxonomyService.class);
List<Node> listTaxonomyTrees = taxonomyService.getAllTaxonomyTrees();
List<Node> listExistedTaxonomy = taxonomyService.getAllCategories(node);
for (Node existedTaxonomy : listExistedTaxonomy) {
for (Node taxonomyTrees : listTaxonomyTrees) {
if(existedTaxonomy.getPath().contains(taxonomyTrees.getPath())) {
taxonomyService.removeCategory(node, taxonomyTrees.getName(),
existedTaxonomy.getPath().substring(taxonomyTrees.getPath().length()));
break;
}
}
}
ActionServiceContainer actionService = getApplicationComponent(ActionServiceContainer.class);
actionService.removeAction(node, uiExplorer.getRepositoryName());
ThumbnailService thumbnailService = getApplicationComponent(ThumbnailService.class);
thumbnailService.processRemoveThumbnail(node);
NewFolksonomyService newFolksonomyService = getApplicationComponent(NewFolksonomyService.class);
newFolksonomyService.removeTagsOfNodeRecursively(node,
uiExplorer.getRepository()
.getConfiguration()
.getDefaultWorkspaceName(),
WCMCoreUtils.getRemoteUser(),
getGroups());
//trashService.removeRelations(node, uiExplorer.getSystemProvider(), uiExplorer.getRepositoryName());
if (PermissionUtil.canRemoveNode(node) && node.isNodeType(Utils.EXO_AUDITABLE)) {
removeAuditForNode(node);
}
//Remove symlinks
LinkManager linkManager = WCMCoreUtils.getService(LinkManager.class);
if(!node.isNodeType(NodetypeConstant.EXO_SYMLINK)) {
for(Node symlink : linkManager.getAllLinks(node, NodetypeConstant.EXO_SYMLINK)) {
symlink.remove();
symlink.getSession().save();
}
}
node.remove();
parentNode.save();
} catch (VersionException ve) {
uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.remove-verion-exception", null,
ApplicationMessage.WARNING));
uiExplorer.updateAjax(event);
return;
} catch (ReferentialIntegrityException ref) {
session.refresh(false);
uiExplorer.refreshExplorer();
uiApp
.addMessage(new ApplicationMessage(
"UIPopupMenu.msg.remove-referentialIntegrityException", null,
ApplicationMessage.WARNING));
uiExplorer.updateAjax(event);
return;
} catch (ConstraintViolationException cons) {
session.refresh(false);
uiExplorer.refreshExplorer();
uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.constraintviolation-exception",
null, ApplicationMessage.WARNING));
uiExplorer.updateAjax(event);
return;
} catch (LockException lockException) {
uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.node-locked-other-person", null,
ApplicationMessage.WARNING));
uiExplorer.updateAjax(event);
return;
} catch (Exception e) {
if (LOG.isErrorEnabled()) {
LOG.error("an unexpected error occurs while removing the node", e);
}
JCRExceptionManager.process(uiApp, e);
return;
}
if (!isMultiSelect) {
if (currentNode.getPath().equals(virtualNodePath))
uiExplorer.setSelectNode(LinkUtils.getParentPath(virtualNodePath));
else
uiExplorer.setSelectNode(currentNode.getPath());
}
}
private void processRemoveMultiple(String[] nodePaths, String[] wsNames, Event<?> event)
throws Exception {
for (int i = 0; i < nodePaths.length; i++) {
processRemove(nodePaths[i], wsNames[i], event, true);
}
}
private void processRemove(String nodePath, String wsName, Event<?> event, boolean isMultiSelect)
throws Exception {
if (wsName == null) {
wsName = getDefaultWorkspace();
}
doDelete(wsName.concat(":").concat(nodePath), event);
}
private String getDefaultWorkspace() {
UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
return uiExplorer.getCurrentDriveWorkspace();
}
public void doDelete(String nodePath, String wsName, Event<?> event) throws Exception {
UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
if (nodePath.indexOf(";") > -1) {
processRemoveMultiple(nodePath.split(";"), wsName.split(";"), event);
} else {
processRemove(nodePath, wsName, event, false);
}
uiExplorer.updateAjax(event);
}
public void doDeleteWithoutTrash(String nodePath, Event<?> event) throws Exception {
doDelete(nodePath, event, false);
}
public void doDelete(String nodePath, Event<?> event) throws Exception {
doDelete(nodePath, event, true);
}
public void doDelete(String nodePath, Event<?> event, boolean checkToMoveToTrash) throws Exception {
RequestContext context = RequestContext.getCurrentInstance();
UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
UIWorkingArea uiWorkingArea = getAncestorOfType(UIWorkingArea.class);
ResourceBundle res = context.getApplicationResourceBundle();
String deleteNotice = "";
String deleteNoticeParam = "";
String trashId = "";
if (nodePath.indexOf(";") > -1) {
trashId = processRemoveMultiple(Utils.removeChildNodes(nodePath), event);
if(checkToMoveToTrash) deleteNotice = "UIWorkingArea.msg.feedback-delete-multi";
else deleteNotice = "UIWorkingArea.msg.feedback-delete-permanently-multi";
deleteNoticeParam = String.valueOf(nodePath.split(";").length);
} else {
UIApplication uiApp = uiExplorer.getAncestorOfType(UIApplication.class);
// Prepare to remove
try {
Node node = this.getNodeByPath(nodePath);
if(checkToMoveToTrash) deleteNotice = "UIWorkingArea.msg.feedback-delete";
else deleteNotice = "UIWorkingArea.msg.feedback-delete-permanently";
deleteNoticeParam = StringEscapeUtils.unescapeHtml(Utils.getTitle(node));
if (node != null) {
trashId = processRemoveOrMoveToTrash(node.getPath(), node, event, false, checkToMoveToTrash);
}
} catch (PathNotFoundException path) {
uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.path-not-found-exception", null,
ApplicationMessage.WARNING));
event.getRequestContext().addUIComponentToUpdateByAjax(uiApp.getUIPopupMessages());
return;
} catch (Exception e) {
JCRExceptionManager.process(uiApp, e);
return;
}
}
deleteNotice = res.getString(deleteNotice);
deleteNotice = deleteNotice.replace("{" + 0 + "}", deleteNoticeParam);
deleteNotice = deleteNotice.replace("\"", "'");
deleteNotice = StringEscapeUtils.escapeHtml(deleteNotice);
if(checkToMoveToTrash) {
String undoLink = getUndoLink(trashId);
uiWorkingArea.setDeleteNotice(deleteNotice);
uiWorkingArea.setNodePathDelete(undoLink);
} else {
uiWorkingArea.setWCMNotice(deleteNotice);
}
uiExplorer.updateAjax(event);
}
/**
* Get undo link to restore nodes that deleted
*
* @param trashId node path of nodes want to restore
* @throws Exception
*/
private String getUndoLink(String trashId) throws Exception {
String undoLink = "";
TrashService trashService = WCMCoreUtils.getService(TrashService.class);
UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
PortletPreferences portletPrefs = uiExplorer.getPortletPreferences();
String trashWorkspace = portletPrefs.getValue(Utils.TRASH_WORKSPACE, "");
StringBuffer sb = new StringBuffer();
if (trashId.indexOf(";") > -1) {
String[] nodePaths = trashId.split(";");
for(int i=0; i<nodePaths.length; i++) {
trashId = nodePaths[i].substring(nodePaths[i].indexOf(":") + 1, nodePaths[i].length());
sb.append(trashWorkspace).append(":").append(trashService.getNodeByTrashId(trashId).getPath()).append(";");
}
undoLink = sb.toString();
if(undoLink.length() > 0) undoLink = undoLink.substring(0,undoLink.length()-1);
} else {
trashId = trashId.substring(trashId.indexOf(":") + 1, trashId.length());
Node tmpNode = trashService.getNodeByTrashId(trashId);
sb.append(tmpNode.getPath()).append(";");
undoLink = sb.toString();
if(undoLink.length() > 0) {
undoLink = undoLink.substring(0,undoLink.length()-1);
undoLink = trashWorkspace + ":" +undoLink;
}
}
return undoLink;
}
private boolean isInTrashFolder(String nodePath) throws Exception {
UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
String wsName = null;
Session session = null;
String[] nodePaths = nodePath.split(";");
for(int i=0; i<nodePaths.length; i++) {
Matcher matcher = UIWorkingArea.FILE_EXPLORER_URL_SYNTAX.matcher(nodePaths[i]);
if (matcher.find()) {
wsName = matcher.group(1);
nodePath = matcher.group(2);
session = uiExplorer.getSessionByWorkspace(wsName);
Node node = uiExplorer.getNodeByPath(nodePath, session, false);
return Utils.isInTrash(node);
}
}
return false;
}
private boolean isDocumentNodeType(Node node) throws Exception {
boolean isDocument = true;
TemplateService templateService = WCMCoreUtils.getService(TemplateService.class);
isDocument = templateService.getAllDocumentNodeTypes().contains(node.getPrimaryNodeType().getName());
return isDocument;
}
/**
* Get the content type of one node
*
* @param nodePath node path of one node
* @throws Exception
*/
private int getContentType(String nodePath) throws Exception {
int content_type = 1;
Node node = getNodeByPath(nodePath);
String primaryType = node.getPrimaryNodeType().getName();
if(node.isNodeType(NodetypeConstant.NT_FILE)) content_type = 2;
else if (primaryType.equals(NodetypeConstant.NT_FOLDER) || primaryType.equals(NodetypeConstant.NT_UNSTRUCTURED))
content_type = 3;
else content_type = 1;
return content_type;
}
/**
* Get the content type of multiple nodes
*
* @param nodePath node path of multiple nodes
* @throws Exception
*/
private int getMultiContentType(String nodePath) throws Exception {
StringBuffer sBuffer = new StringBuffer();
String[] nodePaths = nodePath.split(";");
boolean isGeneric = false;
boolean isFile = false;
boolean isFolder = false;
for(int i=0; i<nodePaths.length; i++) {
Node node = getNodeByPath(nodePaths[i]);
String primaryType = node.getPrimaryNodeType().getName();
if(node.isNodeType(NodetypeConstant.NT_FILE)) isFile = true;
else if (primaryType.equals(NodetypeConstant.NT_FOLDER) || primaryType.equals(NodetypeConstant.NT_UNSTRUCTURED))
isFolder = true;
else isGeneric = true;
}
if(isGeneric) sBuffer.append("1");
else sBuffer.append("0");
if(isFile) sBuffer.append("1");
else sBuffer.append("0");
if(isFolder) sBuffer.append("1");
else sBuffer.append("0");
return Integer.parseInt(sBuffer.toString(),2);
}
public static void deleteManage(Event<? extends UIComponent> event) throws Exception {
UIWorkingArea uiWorkingArea = event.getSource().getParent();
UIJCRExplorer uiExplorer = event.getSource().getAncestorOfType(UIJCRExplorer.class);
String nodePath = event.getRequestContext().getRequestParameter(OBJECTID);
UIConfirmMessage uiConfirmMessage = uiWorkingArea.createUIComponent(UIConfirmMessage.class, null, null);
UIApplication uiApp = uiExplorer.getAncestorOfType(UIApplication.class);
DeleteManageComponent deleteManageComponent = uiWorkingArea.getChild(DeleteManageComponent.class);
//get nodes that have relations referring to them
List<String> listNodesHaveRelations = null;
try {
listNodesHaveRelations = checkRelations(nodePath, uiExplorer);
} catch (PathNotFoundException pathEx) {
uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.path-not-found-exception", null, ApplicationMessage.WARNING));
return;
}
boolean isInTrashFolder = deleteManageComponent.isInTrashFolder(nodePath);
uiConfirmMessage.setNodeInTrash(isInTrashFolder);
String nodeName = nodePath;
int contentType = 1;
int multiContentType = 1;
String message_key = "";
// Check and set the title for Delete Confirmation Dialog
if(nodePath.indexOf(";") > 0) {
uiConfirmMessage.setId(DELETE_ITEMS_CONFIRM_TITLE);
multiContentType = deleteManageComponent.getMultiContentType(nodePath);
} else {
Node node = deleteManageComponent.getNodeByPath(nodePath);
if(node != null)
nodeName = StringEscapeUtils.unescapeHtml(Utils.getTitle(node));
contentType = deleteManageComponent.getContentType(nodePath);
if(contentType == FILE_TYPE)
uiConfirmMessage.setId(DELETE_FILE_CONFIRM_TITLE);
else if (contentType == FOLDER_TYPE)
uiConfirmMessage.setId(DELETE_FOLDER_CONFIRM_TITLE);
}
//show confirm message
if (listNodesHaveRelations != null && listNodesHaveRelations.size() > 0) {
// there are some nodes which have relations referring to them
// in the deleting node list
// build node list to string to add into the confirm message
StringBuffer sb = new StringBuffer();
for (int i = 0; i < listNodesHaveRelations.size(); i++) {
sb.append("'").append(listNodesHaveRelations.get(i)).append("', ");
}
//remove "," character at the end of string
// Node has relations means it is not in Trash folder and is not Folder
if (nodePath.indexOf(";") < 0) { // in case: delete one node that has relations
if(contentType == GENERIC_TYPE)
message_key = "UIWorkingArea.msg.confirm-delete-has-relations";
else if(contentType == FILE_TYPE)
message_key = "UIWorkingArea.msg.confirm-delete-file-has-relations";
else if (contentType == FOLDER_TYPE) {
message_key = "UIWorkingArea.msg.confirm-delete-folder-has-relations";
}
uiConfirmMessage.setMessageKey(message_key);
uiConfirmMessage.setArguments(new String[] { nodeName });
} else { // in case: delete multiple node have relations
switch(multiContentType) {
case FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-folder-have-relations"; break;
case FILES: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-file-have-relations"; break;
case FILES_AND_FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-file-and-folder-have-relations";
break;
case GENERIC: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-have-relations"; break;
case GENERICS_AND_FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-and" +
"-folder-have-relations"; break;
case GENERICS_AND_FILES: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-" +
"and-file-have-relations"; break;
case GENERICS_AND_FILES_AND_FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-" +
"and-file-and-folder-have-relations"; break;
default: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-have-relations"; break;
}
uiConfirmMessage.setMessageKey(message_key);
uiConfirmMessage.setArguments(new String[] { Integer.toString(nodePath.split(";").length) });
}
} else { //there isn't any node which has relations referring to it in the deleting node list
if (isInTrashFolder) {
if (nodePath.indexOf(";") > -1) { // delete multi
switch(multiContentType) {
case FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-folder-permanently"; break;
case FILES: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-file-permanently"; break;
case FILES_AND_FOLDERS:
message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-file-and-folder-permanently"; break;
case GENERIC: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-permanently"; break;
case GENERICS_AND_FOLDERS:
message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-and-folder-permanently"; break;
case GENERICS_AND_FILES:
message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-and-file-permanently"; break;
case GENERICS_AND_FILES_AND_FOLDERS:
message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-and-file-and-folder-permanently"; break;
default: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-permanently"; break;
}
uiConfirmMessage.setMessageKey(message_key);
uiConfirmMessage.setArguments(new String[] { Integer.toString(nodePath.split(";").length) });
} else { // delete one
if(contentType == GENERIC_TYPE)
message_key = "UIWorkingArea.msg.confirm-delete-permanently";
else if(contentType == FILE_TYPE)
message_key = "UIWorkingArea.msg.confirm-delete-file-permanently";
else if(contentType == FOLDER_TYPE)
message_key = "UIWorkingArea.msg.confirm-delete-folder-permanently";
uiConfirmMessage.setMessageKey(message_key);
uiConfirmMessage.setArguments(new String[] { nodeName });
}
} else {
if (nodePath.indexOf(";") > -1) { // delete multi
switch(multiContentType) {
case FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-folder"; break;
case FILES: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-file"; break;
case FILES_AND_FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-file-and-folder"; break;
case GENERIC: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic"; break;
case GENERICS_AND_FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-and-folder"; break;
case GENERICS_AND_FILES: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-and-file"; break;
case GENERICS_AND_FILES_AND_FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-and-file-" +
"and-folder"; break;
default: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic"; break;
}
uiConfirmMessage.setMessageKey(message_key);
uiConfirmMessage.setArguments(new String[] { Integer.toString(nodePath.split(";").length) });
} else { // delete one
if(contentType == GENERIC_TYPE)
message_key = "UIWorkingArea.msg.confirm-delete";
else if(contentType == FILE_TYPE)
message_key = "UIWorkingArea.msg.confirm-delete-file";
else if(contentType == FOLDER_TYPE)
message_key = "UIWorkingArea.msg.confirm-delete-folder";
uiConfirmMessage.setMessageKey(message_key);
uiConfirmMessage.setArguments(new String[] { nodeName });
}
}
}
uiConfirmMessage.setNodePath(nodePath);
UIPopupWindow popUp = uiExplorer.getChild(UIPopupWindow.class);
popUp.setUIComponent(uiConfirmMessage);
popUp.setShowMask(true);
popUp.setShow(true);
event.getRequestContext().addUIComponentToUpdateByAjax(popUp);
}
/**
* This function uses to get a node list that have relations referring to them in the deleting node list
*
* @param nodePath The list of nodes that user wants to delete
* @param uiExplorer uiExplorer
* @return The list of nodes that have relations referring to them
* @throws Exception
*/
private static List<String> checkRelations(String nodePath, UIJCRExplorer uiExplorer) throws Exception{
Node node = null;
String wsName = null;
Session session = null;
String[] nodePaths = nodePath.split(";");
RelationsService rlService = WCMCoreUtils.getService(RelationsService.class);
SessionProvider sessionProvider = WCMCoreUtils.getUserSessionProvider();
List<String> listNodesHaveRelations = new ArrayList<String>();
for (int i = 0; i < nodePaths.length; i++) {
Matcher matcher = UIWorkingArea.FILE_EXPLORER_URL_SYNTAX.matcher(nodePaths[i]);
if (matcher.find()) {
wsName = matcher.group(1);
nodePath = matcher.group(2);
session = uiExplorer.getSessionByWorkspace(wsName);
node = uiExplorer.getNodeByPath(nodePath, session, false);
if (rlService.getRelations(node, sessionProvider).size()>0) {
//check references
listNodesHaveRelations.add(nodePath);
}
} else {
throw new IllegalArgumentException("The ObjectId is invalid '" + nodePath + "'");
}
}
return listNodesHaveRelations;
}
/**
* Get node by node path.
*
* @param nodePath node path of specific node with syntax [workspace:node path]
* @return Node of specific node nath
* @throws Exception
*/
private Node getNodeByPath(String nodePath) throws Exception {
UIJCRExplorer uiExplorer = this.getAncestorOfType(UIJCRExplorer.class);
Matcher matcher = UIWorkingArea.FILE_EXPLORER_URL_SYNTAX.matcher(nodePath);
if (!matcher.find()) return null;
String wsName = matcher.group(1);
nodePath = matcher.group(2);
Session session = uiExplorer.getSessionByWorkspace(wsName);
return uiExplorer.getNodeByPath(nodePath, session, false);
}
private String getGroups() throws Exception {
StringBuilder ret = new StringBuilder();
for (String group : Utils.getGroups())
ret.append(group).append(';');
ret.deleteCharAt(ret.length() - 1);
return ret.toString();
}
@Override
public Class<? extends UIAbstractManager> getUIAbstractManagerClass() {
return null;
}
public static class DeleteActionListener extends UIWorkingAreaActionListener<DeleteManageComponent> {
public void processEvent(Event<DeleteManageComponent> event) throws Exception {
deleteManage(event);
}
}
private void removeMixinEXO_RESTORE_LOCATION(Node node) throws Exception {
if (node.isNodeType(Utils.EXO_RESTORELOCATION)) {
node.removeMixin(Utils.EXO_RESTORELOCATION);
node.save();
}
}
}