1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.exoplatform.ecm.webui.component.explorer.rightclick.manager;
19
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.Collections;
23 import java.util.LinkedList;
24 import java.util.List;
25 import java.util.Queue;
26 import java.util.ResourceBundle;
27 import java.util.regex.Matcher;
28
29 import javax.jcr.AccessDeniedException;
30 import javax.jcr.Node;
31 import javax.jcr.NodeIterator;
32 import javax.jcr.PathNotFoundException;
33 import javax.jcr.PropertyIterator;
34 import javax.jcr.ReferentialIntegrityException;
35 import javax.jcr.Session;
36 import javax.jcr.lock.LockException;
37 import javax.jcr.nodetype.ConstraintViolationException;
38 import javax.jcr.version.VersionException;
39 import javax.portlet.PortletPreferences;
40
41 import org.apache.commons.lang.StringEscapeUtils;
42 import org.apache.commons.lang.Validate;
43 import org.exoplatform.ecm.webui.component.explorer.UIConfirmMessage;
44 import org.exoplatform.ecm.webui.component.explorer.UIJCRExplorer;
45 import org.exoplatform.ecm.webui.component.explorer.UIWorkingArea;
46 import org.exoplatform.ecm.webui.component.explorer.control.filter.CanDeleteNodeFilter;
47 import org.exoplatform.ecm.webui.component.explorer.control.filter.IsNotEditingDocumentFilter;
48 import org.exoplatform.ecm.webui.component.explorer.control.filter.IsNotLockedFilter;
49 import org.exoplatform.ecm.webui.component.explorer.control.filter.IsNotMandatoryChildNode;
50 import org.exoplatform.ecm.webui.component.explorer.control.filter.IsNotTrashHomeNodeFilter;
51 import org.exoplatform.ecm.webui.component.explorer.control.listener.UIWorkingAreaActionListener;
52 import org.exoplatform.ecm.webui.utils.JCRExceptionManager;
53 import org.exoplatform.ecm.utils.lock.LockUtil;
54 import org.exoplatform.ecm.webui.utils.PermissionUtil;
55 import org.exoplatform.ecm.webui.utils.Utils;
56 import org.exoplatform.services.cms.actions.ActionServiceContainer;
57 import org.exoplatform.services.cms.documents.TrashService;
58 import org.exoplatform.services.cms.folksonomy.NewFolksonomyService;
59 import org.exoplatform.services.cms.jcrext.activity.ActivityCommonService;
60 import org.exoplatform.services.cms.link.LinkManager;
61 import org.exoplatform.services.cms.link.LinkUtils;
62 import org.exoplatform.services.cms.relations.RelationsService;
63 import org.exoplatform.services.cms.taxonomy.TaxonomyService;
64 import org.exoplatform.services.cms.templates.TemplateService;
65 import org.exoplatform.services.cms.thumbnail.ThumbnailService;
66 import org.exoplatform.services.jcr.core.ManageableRepository;
67 import org.exoplatform.services.jcr.ext.audit.AuditService;
68 import org.exoplatform.services.jcr.ext.common.SessionProvider;
69 import org.exoplatform.services.listener.ListenerService;
70 import org.exoplatform.services.log.ExoLogger;
71 import org.exoplatform.services.log.Log;
72 import org.exoplatform.services.wcm.core.NodetypeConstant;
73 import org.exoplatform.services.wcm.utils.WCMCoreUtils;
74 import org.exoplatform.web.application.ApplicationMessage;
75 import org.exoplatform.web.application.RequestContext;
76 import org.exoplatform.webui.config.annotation.ComponentConfig;
77 import org.exoplatform.webui.config.annotation.EventConfig;
78 import org.exoplatform.webui.core.UIApplication;
79 import org.exoplatform.webui.core.UIComponent;
80 import org.exoplatform.webui.core.UIPopupWindow;
81 import org.exoplatform.webui.event.Event;
82 import org.exoplatform.webui.ext.filter.UIExtensionFilter;
83 import org.exoplatform.webui.ext.filter.UIExtensionFilters;
84 import org.exoplatform.webui.ext.manager.UIAbstractManager;
85 import org.exoplatform.webui.ext.manager.UIAbstractManagerComponent;
86
87
88
89
90
91
92
93
94 @ComponentConfig(
95 events = {
96 @EventConfig(listeners = DeleteManageComponent.DeleteActionListener.class)
97 }
98 )
99
100 public class DeleteManageComponent extends UIAbstractManagerComponent {
101
102 private static final Log LOG = ExoLogger.getLogger(DeleteManageComponent.class.getName());
103
104 private static final String DELETE_FILE_CONFIRM_TITLE = "UIDeleteFileConfirmMessage";
105 private static final String DELETE_FOLDER_CONFIRM_TITLE = "UIDeleteFolderConfirmMessage";
106 private static final String DELETE_ITEMS_CONFIRM_TITLE = "UIDeleteItemsConfirmMessage";
107
108 private static final int GENERIC_TYPE = 1;
109 private static final int FILE_TYPE = 2;
110 private static final int FOLDER_TYPE = 3;
111
112
113 private static final int FOLDERS = 1;
114 private static final int FILES = 2;
115 private static final int FILES_AND_FOLDERS = 3;
116 private static final int GENERIC = 4;
117 private static final int GENERICS_AND_FOLDERS = 5;
118 private static final int GENERICS_AND_FILES = 6;
119 private static final int GENERICS_AND_FILES_AND_FOLDERS = 7;
120
121 private static final List<UIExtensionFilter> FILTERS
122
123 = Arrays.asList(new UIExtensionFilter[]{new IsNotLockedFilter(),
124 new CanDeleteNodeFilter(),
125 new IsNotTrashHomeNodeFilter(),
126 new IsNotEditingDocumentFilter(),
127 new IsNotMandatoryChildNode()});
128
129 @UIExtensionFilters
130 public List<UIExtensionFilter> getFilters() {
131 return FILTERS;
132 }
133
134 private String processRemoveMultiple(String[] nodePaths, Event<?> event) throws Exception {
135 StringBuilder trashId = new StringBuilder();
136 UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
137 UIApplication uiApp = uiExplorer.getAncestorOfType(UIApplication.class);
138 Arrays.sort(nodePaths,Collections.reverseOrder());
139 for (int i = 0; i < nodePaths.length ; i++) {
140 try {
141 Node node = this.getNodeByPath(nodePaths[i]);
142 Validate.isTrue(node != null, "The ObjectId is invalid '" + nodePaths[i] + "'");
143 trashId.append(processRemoveOrMoveToTrash(nodePaths[i], node, event, true, true)).append(";");
144 } catch (PathNotFoundException path) {
145 uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.path-not-found-exception", null, ApplicationMessage.WARNING));
146 event.getRequestContext().addUIComponentToUpdateByAjax(uiApp.getUIPopupMessages());
147 } catch (Exception e) {
148 JCRExceptionManager.process(uiApp, e);
149 }
150 }
151
152 return trashId.substring(0,trashId.length() - 1);
153 }
154
155 private void removeAuditForNode(Node node) throws Exception {
156 UIJCRExplorer uiExplorer = this.getAncestorOfType(UIJCRExplorer.class);
157 ManageableRepository repository = uiExplorer.getRepository();
158 SessionProvider sessionProvider = uiExplorer.getSystemProvider();
159 Session session = null;
160 session = sessionProvider.getSession(node.getSession().getWorkspace().getName(), repository);
161 Node rootNode = session.getRootNode();
162 if (rootNode.hasNode("exo:audit") && rootNode.getNode("exo:audit").hasNode(node.getUUID())) {
163 rootNode.getNode("exo:audit").getNode(node.getUUID()).remove();
164 session.save();
165 }
166 }
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182 private String processRemoveOrMoveToTrash(String nodePath,
183 Node node,
184 Event<?> event,
185 boolean isMultiSelect,
186 boolean checkToMoveToTrash)
187 throws Exception {
188 String trashId="-1";
189 if (!checkToMoveToTrash || Utils.isInTrash(node)) {
190 processRemoveNode(nodePath, node, event, isMultiSelect);
191 return "0";
192 }else {
193 trashId = moveToTrash(nodePath, node, event, isMultiSelect);
194 if (!trashId.equals("-1")) {
195
196 ListenerService listenerService = WCMCoreUtils.getService(ListenerService.class);
197
198 TrashService trashService = WCMCoreUtils.getService(TrashService.class);
199 node = trashService.getNodeByTrashId(trashId);
200 if(!isDocumentNodeType(node)
201 && !node.getPrimaryNodeType().getName().equals(NodetypeConstant.NT_FILE)){
202 Queue<Node> queue = new LinkedList<Node>();
203 queue.add(node);
204
205
206 Node tempNode = null;
207 try {
208 while (!queue.isEmpty()) {
209 tempNode = queue.poll();
210 if (isDocumentNodeType(tempNode) || tempNode.getPrimaryNodeType().getName().equals(NodetypeConstant.NT_FILE)) {
211 listenerService.broadcast(ActivityCommonService.FILE_REMOVE_ACTIVITY, tempNode.getParent(), tempNode);
212 } else {
213 for (NodeIterator iter = tempNode.getNodes(); iter.hasNext(); ) {
214 Node childNode = iter.nextNode();
215 if(isDocumentNodeType(childNode) || childNode.isNodeType(NodetypeConstant.NT_UNSTRUCTURED) ||
216 childNode.isNodeType(NodetypeConstant.NT_FOLDER))
217 queue.add(childNode);
218 }
219 }
220 }
221 } catch (Exception e) {
222 if (LOG.isWarnEnabled()) {
223 LOG.warn(e.getMessage());
224 }
225 }
226 }
227 }
228 }
229 return trashId;
230 }
231
232
233
234
235
236
237
238
239
240
241
242
243 private String moveToTrash(String srcPath, Node node, Event<?> event, boolean isMultiSelect) throws Exception {
244 TrashService trashService = WCMCoreUtils.getService(TrashService.class);
245 AuditService auditService = WCMCoreUtils.getService(AuditService.class);
246 boolean ret = true;
247 String trashId="-1";
248 final String virtualNodePath = srcPath;
249 UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
250 UIApplication uiApp = uiExplorer.getAncestorOfType(UIApplication.class);
251 try {
252 uiExplorer.addLockToken(node);
253 } catch (Exception e) {
254 JCRExceptionManager.process(uiApp, e);
255 return trashId;
256 }
257
258 try {
259 if (node.isLocked()) {
260 LockUtil.removeLock(node);
261 node.unlock();
262 }
263
264 if(auditService.hasHistory(node)) {
265 auditService.removeHistory(node);
266 }
267
268 if( node.isNodeType(Utils.EXO_AUDITABLE)){
269 node.removeMixin(Utils.EXO_AUDITABLE);
270 }
271 node.save();
272
273 RelationsService relationService = uiApp.getApplicationComponent(RelationsService.class) ;
274 PropertyIterator iter = node.getReferences();
275 while (iter.hasNext()) {
276 Node refNode = iter.nextProperty().getParent();
277 relationService.removeRelation(refNode, node.getPath());
278 }
279
280 if (!node.isCheckedOut())
281 throw new VersionException("node is locked, can't move to trash node :" + node.getPath());
282 if (!PermissionUtil.canRemoveNode(node))
283 throw new AccessDeniedException("access denied, can't move to trash node:" + node.getPath());
284 SessionProvider sessionProvider = uiExplorer.getSessionProvider();
285 Node currentNode = uiExplorer.getCurrentNode();
286
287 try {
288 trashId = trashService.moveToTrash(node, sessionProvider);
289 } catch (PathNotFoundException ex) {
290 ret = false;
291 }
292 String currentPath = LinkUtils.getExistPath(currentNode, uiExplorer.getCurrentPath());
293 uiExplorer.setCurrentPath(currentPath);
294 uiExplorer.updateAjax(event);
295
296 } catch (LockException e) {
297 if (LOG.isErrorEnabled()) {
298 LOG.error("node is locked, can't move to trash node :" + node.getPath());
299 }
300 ApplicationMessage appMessage =
301 new ApplicationMessage("UIPopupMenu.msg.can-not-remove-locked-node",
302 new String[] {node.getPath()}, ApplicationMessage.ERROR);
303 appMessage.setArgsLocalized(false);
304 uiApp.addMessage(appMessage);
305 uiExplorer.updateAjax(event);
306 ret = false;
307 } catch (VersionException e) {
308 if (LOG.isErrorEnabled()) {
309 LOG.error("node is checked in, can't move to trash node:" + node.getPath());
310 }
311 removeMixinEXO_RESTORE_LOCATION(node);
312 ApplicationMessage appMessage =
313 new ApplicationMessage("UIPopupMenu.msg.can-not-remove-checked-in-node",
314 new String[] {node.getPath()}, ApplicationMessage.ERROR);
315 appMessage.setArgsLocalized(false);
316 uiApp.addMessage(appMessage);
317 uiExplorer.updateAjax(event);
318 ret = false;
319 } catch (AccessDeniedException e) {
320 if (LOG.isErrorEnabled()) {
321 LOG.error("access denied, can't move to trash node:" + node.getPath());
322 }
323 ApplicationMessage appMessage =
324 new ApplicationMessage("UIPopupMenu.msg.access-denied-to-delete",
325 new String[] {node.getPath()}, ApplicationMessage.ERROR);
326 appMessage.setArgsLocalized(false);
327 uiApp.addMessage(appMessage);
328 uiExplorer.updateAjax(event);
329 ret = false;
330 } catch (Exception e) {
331 if (LOG.isErrorEnabled()) {
332 LOG.error("an unexpected error occurs", e);
333 }
334 uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.unexpected-error",
335 new String[] {node.getPath()}, ApplicationMessage.ERROR));
336 uiExplorer.updateAjax(event);
337 ret = false;
338 }
339
340 if (!isMultiSelect) {
341 if (uiExplorer.getCurrentPath().equals(virtualNodePath))
342 uiExplorer.setSelectNode(LinkUtils.getParentPath(virtualNodePath));
343 else
344 uiExplorer.setSelectNode(uiExplorer.getCurrentPath());
345 }
346 return (ret)?trashId:"-1";
347 }
348
349 private void processRemoveNode(String nodePath, Node node, Event<?> event, boolean isMultiSelect)
350 throws Exception {
351 final String virtualNodePath = nodePath;
352 UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
353 Node currentNode = uiExplorer.getCurrentNode();
354 Session session = node.getSession();
355 UIApplication uiApp = uiExplorer.getAncestorOfType(UIApplication.class);
356 try {
357 uiExplorer.addLockToken(node);
358 } catch (Exception e) {
359 JCRExceptionManager.process(uiApp, e);
360 return;
361 }
362 Node parentNode = node.getParent();
363 uiExplorer.addLockToken(parentNode);
364 try {
365
366
367 TaxonomyService taxonomyService = uiExplorer.getApplicationComponent(TaxonomyService.class);
368 List<Node> listTaxonomyTrees = taxonomyService.getAllTaxonomyTrees();
369 List<Node> listExistedTaxonomy = taxonomyService.getAllCategories(node);
370 for (Node existedTaxonomy : listExistedTaxonomy) {
371 for (Node taxonomyTrees : listTaxonomyTrees) {
372 if(existedTaxonomy.getPath().contains(taxonomyTrees.getPath())) {
373 taxonomyService.removeCategory(node, taxonomyTrees.getName(),
374 existedTaxonomy.getPath().substring(taxonomyTrees.getPath().length()));
375 break;
376 }
377 }
378 }
379
380 ActionServiceContainer actionService = getApplicationComponent(ActionServiceContainer.class);
381 actionService.removeAction(node, uiExplorer.getRepositoryName());
382 ThumbnailService thumbnailService = getApplicationComponent(ThumbnailService.class);
383 thumbnailService.processRemoveThumbnail(node);
384 NewFolksonomyService newFolksonomyService = getApplicationComponent(NewFolksonomyService.class);
385
386 newFolksonomyService.removeTagsOfNodeRecursively(node,
387 uiExplorer.getRepository()
388 .getConfiguration()
389 .getDefaultWorkspaceName(),
390 WCMCoreUtils.getRemoteUser(),
391 getGroups());
392
393 if (PermissionUtil.canRemoveNode(node) && node.isNodeType(Utils.EXO_AUDITABLE)) {
394 removeAuditForNode(node);
395 }
396
397 LinkManager linkManager = WCMCoreUtils.getService(LinkManager.class);
398 if(!node.isNodeType(NodetypeConstant.EXO_SYMLINK)) {
399 for(Node symlink : linkManager.getAllLinks(node, NodetypeConstant.EXO_SYMLINK)) {
400 symlink.remove();
401 symlink.getSession().save();
402 }
403 }
404 node.remove();
405 parentNode.save();
406 } catch (VersionException ve) {
407 uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.remove-verion-exception", null,
408 ApplicationMessage.WARNING));
409
410 uiExplorer.updateAjax(event);
411 return;
412 } catch (ReferentialIntegrityException ref) {
413 session.refresh(false);
414 uiExplorer.refreshExplorer();
415 uiApp
416 .addMessage(new ApplicationMessage(
417 "UIPopupMenu.msg.remove-referentialIntegrityException", null,
418 ApplicationMessage.WARNING));
419
420 uiExplorer.updateAjax(event);
421 return;
422 } catch (ConstraintViolationException cons) {
423 session.refresh(false);
424 uiExplorer.refreshExplorer();
425 uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.constraintviolation-exception",
426 null, ApplicationMessage.WARNING));
427
428 uiExplorer.updateAjax(event);
429 return;
430 } catch (LockException lockException) {
431 uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.node-locked-other-person", null,
432 ApplicationMessage.WARNING));
433
434 uiExplorer.updateAjax(event);
435 return;
436 } catch (Exception e) {
437 if (LOG.isErrorEnabled()) {
438 LOG.error("an unexpected error occurs while removing the node", e);
439 }
440 JCRExceptionManager.process(uiApp, e);
441
442 return;
443 }
444 if (!isMultiSelect) {
445 if (currentNode.getPath().equals(virtualNodePath))
446 uiExplorer.setSelectNode(LinkUtils.getParentPath(virtualNodePath));
447 else
448 uiExplorer.setSelectNode(currentNode.getPath());
449 }
450 }
451
452 private void processRemoveMultiple(String[] nodePaths, String[] wsNames, Event<?> event)
453 throws Exception {
454 for (int i = 0; i < nodePaths.length; i++) {
455 processRemove(nodePaths[i], wsNames[i], event, true);
456 }
457 }
458
459 private void processRemove(String nodePath, String wsName, Event<?> event, boolean isMultiSelect)
460 throws Exception {
461 if (wsName == null) {
462 wsName = getDefaultWorkspace();
463 }
464 doDelete(wsName.concat(":").concat(nodePath), event);
465 }
466
467 private String getDefaultWorkspace() {
468 UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
469 return uiExplorer.getCurrentDriveWorkspace();
470 }
471
472 public void doDelete(String nodePath, String wsName, Event<?> event) throws Exception {
473 UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
474 if (nodePath.indexOf(";") > -1) {
475 processRemoveMultiple(nodePath.split(";"), wsName.split(";"), event);
476 } else {
477 processRemove(nodePath, wsName, event, false);
478 }
479 uiExplorer.updateAjax(event);
480 }
481
482 public void doDeleteWithoutTrash(String nodePath, Event<?> event) throws Exception {
483 doDelete(nodePath, event, false);
484 }
485
486 public void doDelete(String nodePath, Event<?> event) throws Exception {
487 doDelete(nodePath, event, true);
488 }
489
490 public void doDelete(String nodePath, Event<?> event, boolean checkToMoveToTrash) throws Exception {
491 RequestContext context = RequestContext.getCurrentInstance();
492 UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
493 UIWorkingArea uiWorkingArea = getAncestorOfType(UIWorkingArea.class);
494 ResourceBundle res = context.getApplicationResourceBundle();
495 String deleteNotice = "";
496 String deleteNoticeParam = "";
497 String trashId = "";
498 if (nodePath.indexOf(";") > -1) {
499 trashId = processRemoveMultiple(Utils.removeChildNodes(nodePath), event);
500 if(checkToMoveToTrash) deleteNotice = "UIWorkingArea.msg.feedback-delete-multi";
501 else deleteNotice = "UIWorkingArea.msg.feedback-delete-permanently-multi";
502 deleteNoticeParam = String.valueOf(nodePath.split(";").length);
503 } else {
504 UIApplication uiApp = uiExplorer.getAncestorOfType(UIApplication.class);
505
506 try {
507 Node node = this.getNodeByPath(nodePath);
508 if(checkToMoveToTrash) deleteNotice = "UIWorkingArea.msg.feedback-delete";
509 else deleteNotice = "UIWorkingArea.msg.feedback-delete-permanently";
510 deleteNoticeParam = StringEscapeUtils.unescapeHtml(Utils.getTitle(node));
511 if (node != null) {
512 trashId = processRemoveOrMoveToTrash(node.getPath(), node, event, false, checkToMoveToTrash);
513 }
514 } catch (PathNotFoundException path) {
515 uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.path-not-found-exception", null,
516 ApplicationMessage.WARNING));
517 event.getRequestContext().addUIComponentToUpdateByAjax(uiApp.getUIPopupMessages());
518 return;
519 } catch (Exception e) {
520 JCRExceptionManager.process(uiApp, e);
521 return;
522 }
523 }
524 deleteNotice = res.getString(deleteNotice);
525 deleteNotice = deleteNotice.replace("{" + 0 + "}", deleteNoticeParam);
526 deleteNotice = deleteNotice.replace("\"", "'");
527 deleteNotice = StringEscapeUtils.escapeHtml(deleteNotice);
528 if(checkToMoveToTrash) {
529 String undoLink = getUndoLink(trashId);
530 uiWorkingArea.setDeleteNotice(deleteNotice);
531 uiWorkingArea.setNodePathDelete(undoLink);
532 } else {
533 uiWorkingArea.setWCMNotice(deleteNotice);
534 }
535 uiExplorer.updateAjax(event);
536 }
537
538
539
540
541
542
543 private String getUndoLink(String trashId) throws Exception {
544 String undoLink = "";
545 TrashService trashService = WCMCoreUtils.getService(TrashService.class);
546
547 UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
548 PortletPreferences portletPrefs = uiExplorer.getPortletPreferences();
549
550 String trashWorkspace = portletPrefs.getValue(Utils.TRASH_WORKSPACE, "");
551 StringBuffer sb = new StringBuffer();
552 if (trashId.indexOf(";") > -1) {
553 String[] nodePaths = trashId.split(";");
554 for(int i=0; i<nodePaths.length; i++) {
555 trashId = nodePaths[i].substring(nodePaths[i].indexOf(":") + 1, nodePaths[i].length());
556 sb.append(trashWorkspace).append(":").append(trashService.getNodeByTrashId(trashId).getPath()).append(";");
557 }
558 undoLink = sb.toString();
559 if(undoLink.length() > 0) undoLink = undoLink.substring(0,undoLink.length()-1);
560 } else {
561 trashId = trashId.substring(trashId.indexOf(":") + 1, trashId.length());
562 Node tmpNode = trashService.getNodeByTrashId(trashId);
563 sb.append(tmpNode.getPath()).append(";");
564 undoLink = sb.toString();
565 if(undoLink.length() > 0) {
566 undoLink = undoLink.substring(0,undoLink.length()-1);
567 undoLink = trashWorkspace + ":" +undoLink;
568 }
569 }
570 return undoLink;
571 }
572
573 private boolean isInTrashFolder(String nodePath) throws Exception {
574 UIJCRExplorer uiExplorer = getAncestorOfType(UIJCRExplorer.class);
575 String wsName = null;
576 Session session = null;
577 String[] nodePaths = nodePath.split(";");
578 for(int i=0; i<nodePaths.length; i++) {
579 Matcher matcher = UIWorkingArea.FILE_EXPLORER_URL_SYNTAX.matcher(nodePaths[i]);
580 if (matcher.find()) {
581 wsName = matcher.group(1);
582 nodePath = matcher.group(2);
583 session = uiExplorer.getSessionByWorkspace(wsName);
584 Node node = uiExplorer.getNodeByPath(nodePath, session, false);
585 return Utils.isInTrash(node);
586 }
587 }
588 return false;
589 }
590
591 private boolean isDocumentNodeType(Node node) throws Exception {
592 boolean isDocument = true;
593 TemplateService templateService = WCMCoreUtils.getService(TemplateService.class);
594 isDocument = templateService.getAllDocumentNodeTypes().contains(node.getPrimaryNodeType().getName());
595 return isDocument;
596 }
597
598
599
600
601
602
603 private int getContentType(String nodePath) throws Exception {
604 int content_type = 1;
605 Node node = getNodeByPath(nodePath);
606 String primaryType = node.getPrimaryNodeType().getName();
607 if(node.isNodeType(NodetypeConstant.NT_FILE)) content_type = 2;
608 else if (primaryType.equals(NodetypeConstant.NT_FOLDER) || primaryType.equals(NodetypeConstant.NT_UNSTRUCTURED))
609 content_type = 3;
610 else content_type = 1;
611 return content_type;
612 }
613
614
615
616
617
618
619 private int getMultiContentType(String nodePath) throws Exception {
620 StringBuffer sBuffer = new StringBuffer();
621 String[] nodePaths = nodePath.split(";");
622 boolean isGeneric = false;
623 boolean isFile = false;
624 boolean isFolder = false;
625
626 for(int i=0; i<nodePaths.length; i++) {
627 Node node = getNodeByPath(nodePaths[i]);
628 String primaryType = node.getPrimaryNodeType().getName();
629 if(node.isNodeType(NodetypeConstant.NT_FILE)) isFile = true;
630 else if (primaryType.equals(NodetypeConstant.NT_FOLDER) || primaryType.equals(NodetypeConstant.NT_UNSTRUCTURED))
631 isFolder = true;
632 else isGeneric = true;
633 }
634 if(isGeneric) sBuffer.append("1");
635 else sBuffer.append("0");
636
637 if(isFile) sBuffer.append("1");
638 else sBuffer.append("0");
639
640 if(isFolder) sBuffer.append("1");
641 else sBuffer.append("0");
642
643 return Integer.parseInt(sBuffer.toString(),2);
644 }
645
646 public static void deleteManage(Event<? extends UIComponent> event) throws Exception {
647 UIWorkingArea uiWorkingArea = event.getSource().getParent();
648 UIJCRExplorer uiExplorer = event.getSource().getAncestorOfType(UIJCRExplorer.class);
649 String nodePath = event.getRequestContext().getRequestParameter(OBJECTID);
650 UIConfirmMessage uiConfirmMessage = uiWorkingArea.createUIComponent(UIConfirmMessage.class, null, null);
651 UIApplication uiApp = uiExplorer.getAncestorOfType(UIApplication.class);
652 DeleteManageComponent deleteManageComponent = uiWorkingArea.getChild(DeleteManageComponent.class);
653
654
655 List<String> listNodesHaveRelations = null;
656 try {
657 listNodesHaveRelations = checkRelations(nodePath, uiExplorer);
658 } catch (PathNotFoundException pathEx) {
659 uiApp.addMessage(new ApplicationMessage("UIPopupMenu.msg.path-not-found-exception", null, ApplicationMessage.WARNING));
660
661 return;
662 }
663
664 boolean isInTrashFolder = deleteManageComponent.isInTrashFolder(nodePath);
665 uiConfirmMessage.setNodeInTrash(isInTrashFolder);
666 String nodeName = nodePath;
667 int contentType = 1;
668 int multiContentType = 1;
669 String message_key = "";
670
671 if(nodePath.indexOf(";") > 0) {
672 uiConfirmMessage.setId(DELETE_ITEMS_CONFIRM_TITLE);
673 multiContentType = deleteManageComponent.getMultiContentType(nodePath);
674 } else {
675 Node node = deleteManageComponent.getNodeByPath(nodePath);
676 if(node != null)
677 nodeName = StringEscapeUtils.unescapeHtml(Utils.getTitle(node));
678 contentType = deleteManageComponent.getContentType(nodePath);
679 if(contentType == FILE_TYPE)
680 uiConfirmMessage.setId(DELETE_FILE_CONFIRM_TITLE);
681 else if (contentType == FOLDER_TYPE)
682 uiConfirmMessage.setId(DELETE_FOLDER_CONFIRM_TITLE);
683 }
684
685
686 if (listNodesHaveRelations != null && listNodesHaveRelations.size() > 0) {
687
688
689
690 StringBuffer sb = new StringBuffer();
691 for (int i = 0; i < listNodesHaveRelations.size(); i++) {
692 sb.append("'").append(listNodesHaveRelations.get(i)).append("', ");
693 }
694
695
696
697 if (nodePath.indexOf(";") < 0) {
698 if(contentType == GENERIC_TYPE)
699 message_key = "UIWorkingArea.msg.confirm-delete-has-relations";
700 else if(contentType == FILE_TYPE)
701 message_key = "UIWorkingArea.msg.confirm-delete-file-has-relations";
702 else if (contentType == FOLDER_TYPE) {
703 message_key = "UIWorkingArea.msg.confirm-delete-folder-has-relations";
704 }
705 uiConfirmMessage.setMessageKey(message_key);
706 uiConfirmMessage.setArguments(new String[] { nodeName });
707 } else {
708
709 switch(multiContentType) {
710 case FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-folder-have-relations"; break;
711 case FILES: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-file-have-relations"; break;
712 case FILES_AND_FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-file-and-folder-have-relations";
713 break;
714 case GENERIC: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-have-relations"; break;
715 case GENERICS_AND_FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-and" +
716 "-folder-have-relations"; break;
717 case GENERICS_AND_FILES: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-" +
718 "and-file-have-relations"; break;
719 case GENERICS_AND_FILES_AND_FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-" +
720 "and-file-and-folder-have-relations"; break;
721 default: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-have-relations"; break;
722 }
723
724 uiConfirmMessage.setMessageKey(message_key);
725 uiConfirmMessage.setArguments(new String[] { Integer.toString(nodePath.split(";").length) });
726 }
727
728 } else {
729 if (isInTrashFolder) {
730 if (nodePath.indexOf(";") > -1) {
731
732 switch(multiContentType) {
733 case FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-folder-permanently"; break;
734 case FILES: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-file-permanently"; break;
735 case FILES_AND_FOLDERS:
736 message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-file-and-folder-permanently"; break;
737 case GENERIC: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-permanently"; break;
738 case GENERICS_AND_FOLDERS:
739 message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-and-folder-permanently"; break;
740 case GENERICS_AND_FILES:
741 message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-and-file-permanently"; break;
742 case GENERICS_AND_FILES_AND_FOLDERS:
743 message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-and-file-and-folder-permanently"; break;
744 default: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-permanently"; break;
745 }
746
747 uiConfirmMessage.setMessageKey(message_key);
748 uiConfirmMessage.setArguments(new String[] { Integer.toString(nodePath.split(";").length) });
749 } else {
750 if(contentType == GENERIC_TYPE)
751 message_key = "UIWorkingArea.msg.confirm-delete-permanently";
752 else if(contentType == FILE_TYPE)
753 message_key = "UIWorkingArea.msg.confirm-delete-file-permanently";
754 else if(contentType == FOLDER_TYPE)
755 message_key = "UIWorkingArea.msg.confirm-delete-folder-permanently";
756 uiConfirmMessage.setMessageKey(message_key);
757 uiConfirmMessage.setArguments(new String[] { nodeName });
758 }
759 } else {
760 if (nodePath.indexOf(";") > -1) {
761
762 switch(multiContentType) {
763 case FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-folder"; break;
764 case FILES: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-file"; break;
765 case FILES_AND_FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-file-and-folder"; break;
766 case GENERIC: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic"; break;
767 case GENERICS_AND_FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-and-folder"; break;
768 case GENERICS_AND_FILES: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-and-file"; break;
769 case GENERICS_AND_FILES_AND_FOLDERS: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic-and-file-" +
770 "and-folder"; break;
771 default: message_key = "UIWorkingArea.msg.confirm-delete-multi-nodes-generic"; break;
772 }
773 uiConfirmMessage.setMessageKey(message_key);
774 uiConfirmMessage.setArguments(new String[] { Integer.toString(nodePath.split(";").length) });
775 } else {
776 if(contentType == GENERIC_TYPE)
777 message_key = "UIWorkingArea.msg.confirm-delete";
778 else if(contentType == FILE_TYPE)
779 message_key = "UIWorkingArea.msg.confirm-delete-file";
780 else if(contentType == FOLDER_TYPE)
781 message_key = "UIWorkingArea.msg.confirm-delete-folder";
782 uiConfirmMessage.setMessageKey(message_key);
783 uiConfirmMessage.setArguments(new String[] { nodeName });
784 }
785 }
786 }
787
788 uiConfirmMessage.setNodePath(nodePath);
789 UIPopupWindow popUp = uiExplorer.getChild(UIPopupWindow.class);
790 popUp.setUIComponent(uiConfirmMessage);
791 popUp.setShowMask(true);
792 popUp.setShow(true);
793 event.getRequestContext().addUIComponentToUpdateByAjax(popUp);
794
795 }
796
797
798
799
800
801
802
803
804
805 private static List<String> checkRelations(String nodePath, UIJCRExplorer uiExplorer) throws Exception{
806
807 Node node = null;
808 String wsName = null;
809 Session session = null;
810 String[] nodePaths = nodePath.split(";");
811 RelationsService rlService = WCMCoreUtils.getService(RelationsService.class);
812 SessionProvider sessionProvider = WCMCoreUtils.getUserSessionProvider();
813 List<String> listNodesHaveRelations = new ArrayList<String>();
814 for (int i = 0; i < nodePaths.length; i++) {
815 Matcher matcher = UIWorkingArea.FILE_EXPLORER_URL_SYNTAX.matcher(nodePaths[i]);
816 if (matcher.find()) {
817 wsName = matcher.group(1);
818 nodePath = matcher.group(2);
819 session = uiExplorer.getSessionByWorkspace(wsName);
820 node = uiExplorer.getNodeByPath(nodePath, session, false);
821 if (rlService.getRelations(node, sessionProvider).size()>0) {
822
823 listNodesHaveRelations.add(nodePath);
824 }
825 } else {
826 throw new IllegalArgumentException("The ObjectId is invalid '" + nodePath + "'");
827 }
828 }
829 return listNodesHaveRelations;
830 }
831
832
833
834
835
836
837
838
839 private Node getNodeByPath(String nodePath) throws Exception {
840 UIJCRExplorer uiExplorer = this.getAncestorOfType(UIJCRExplorer.class);
841 Matcher matcher = UIWorkingArea.FILE_EXPLORER_URL_SYNTAX.matcher(nodePath);
842 if (!matcher.find()) return null;
843 String wsName = matcher.group(1);
844 nodePath = matcher.group(2);
845 Session session = uiExplorer.getSessionByWorkspace(wsName);
846 return uiExplorer.getNodeByPath(nodePath, session, false);
847 }
848
849 private String getGroups() throws Exception {
850 StringBuilder ret = new StringBuilder();
851 for (String group : Utils.getGroups())
852 ret.append(group).append(';');
853 ret.deleteCharAt(ret.length() - 1);
854 return ret.toString();
855 }
856
857 @Override
858 public Class<? extends UIAbstractManager> getUIAbstractManagerClass() {
859 return null;
860 }
861
862 public static class DeleteActionListener extends UIWorkingAreaActionListener<DeleteManageComponent> {
863 public void processEvent(Event<DeleteManageComponent> event) throws Exception {
864 deleteManage(event);
865 }
866 }
867
868 private void removeMixinEXO_RESTORE_LOCATION(Node node) throws Exception {
869 if (node.isNodeType(Utils.EXO_RESTORELOCATION)) {
870 node.removeMixin(Utils.EXO_RESTORELOCATION);
871 node.save();
872 }
873 }
874 }