1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.contentapp.action;
35
36 import info.magnolia.i18nsystem.SimpleTranslator;
37 import info.magnolia.jcr.predicate.AbstractPredicate;
38 import info.magnolia.jcr.util.NodeTypes;
39 import info.magnolia.jcr.util.NodeUtil;
40 import info.magnolia.ui.ValueContext;
41 import info.magnolia.ui.api.context.UiContext;
42 import info.magnolia.ui.contentapp.browser.ActionExecutionService;
43 import info.magnolia.ui.datasource.jcr.JcrDatasourceDefinition;
44
45 import java.util.Set;
46 import java.util.stream.Collectors;
47 import java.util.stream.StreamSupport;
48
49 import javax.inject.Inject;
50 import javax.jcr.Node;
51
52 import org.apache.commons.lang3.StringUtils;
53
54 import com.machinezoo.noexception.Exceptions;
55
56 import lombok.AllArgsConstructor;
57
58
59
60
61
62
63 public class DeleteNodesConfirmationAction<D extends DeleteNodesConfirmationActionDefinition> extends ConfirmationAction<D, Node> {
64
65 private static final String NL = "<br />";
66
67 private boolean warningAlreadySet = false;
68
69 private final ModifiedSubNodesWithNodeTypePredicate predicate;
70
71 @Inject
72 public DeleteNodesConfirmationAction(D definition, UiContext uiContext, ActionExecutionService actionExecutionService, SimpleTranslator i18n, ValueContext valueContext, JcrDatasourceDefinition datasourceDefinition) {
73 super(definition, uiContext, actionExecutionService, i18n, valueContext);
74 this.predicate = new ModifiedSubNodesWithNodeTypePredicate(datasourceDefinition.getAllowedNodeTypes());
75 }
76
77 @Override
78 protected String getConfirmationMessage() {
79 if (predicate == null) {
80 return super.getConfirmationMessage();
81 }
82 StringBuilder label = new StringBuilder();
83
84
85 label.append(super.getConfirmationMessage());
86
87 getValueContext().get().forEach(node -> {
88 String modifiedSubNodesPaths = getModifiedSubNodesMessage(node);
89 if (StringUtils.isNotEmpty(modifiedSubNodesPaths)) {
90 if (!warningAlreadySet) {
91 label.append(NL).append(NL);
92 label.append(getSimpleTranslator().translate("confirmation.delete.modified.message"));
93 label.append(NL);
94 warningAlreadySet = true;
95 }
96 label.append(modifiedSubNodesPaths);
97 }
98 });
99 return label.toString();
100 }
101
102 private String getModifiedSubNodesMessage(Node parent) {
103 return StreamSupport.stream(Exceptions.wrap().get(() -> NodeUtil.getNodes(parent, predicate).spliterator()), false)
104 .map(Exceptions.wrap().function(Node::getPath))
105 .collect(Collectors.joining(NL));
106 }
107
108 @AllArgsConstructor
109 private static class ModifiedSubNodesWithNodeTypePredicate extends AbstractPredicate<Node> {
110
111 private final Set<String> nodeTypes;
112
113 @Override
114 public boolean evaluateTyped(Node node) {
115 return nodeTypes.stream()
116 .filter(Exceptions.wrap().predicate(nodeType -> NodeUtil.isNodeType(node, nodeType)))
117 .map(Exceptions.wrap().function(any -> NodeTypes.Activatable.ACTIVATION_STATUS_MODIFIED == NodeTypes.Activatable.getActivationStatus(node)))
118 .findFirst()
119 .orElse(false);
120 }
121 }
122 }