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.jcr.util.NodeNameHelper;
37 import info.magnolia.jcr.util.NodeUtil;
38 import info.magnolia.objectfactory.Components;
39 import info.magnolia.ui.ValueContext;
40 import info.magnolia.ui.datasource.DatasourceDefinition;
41 import info.magnolia.ui.datasource.jcr.JcrDatasourceDefinition;
42
43 import java.util.Optional;
44 import java.util.regex.Matcher;
45 import java.util.regex.Pattern;
46
47 import javax.inject.Inject;
48 import javax.jcr.Node;
49 import javax.jcr.RepositoryException;
50 import javax.jcr.Session;
51
52 import org.apache.commons.lang3.StringUtils;
53
54
55
56
57
58
59 public class DuplicateNodeAction extends AbstractJcrAction<Node, DuplicateNodeActionDefinition> {
60
61 private final JcrDatasourceDefinition jcrDatasourceDefinition;
62
63 @Inject
64 public DuplicateNodeAction(DuplicateNodeActionDefinition definition, ValueContext<Node> valueContext, NodeNameHelper nodeNameHelper, JcrDatasourceDefinition jcrDatasourceDefinition) {
65 super(definition, valueContext, nodeNameHelper);
66 this.jcrDatasourceDefinition = jcrDatasourceDefinition;
67 }
68
69
70
71
72 @Deprecated
73 public DuplicateNodeAction(DuplicateNodeActionDefinition definition, ValueContext<Node> valueContext, NodeNameHelper nodeNameHelper) {
74 this(definition, valueContext, nodeNameHelper, (JcrDatasourceDefinition) Components.getComponent(DatasourceDefinition.class));
75 }
76
77 @Override
78 public Node process(Node node) throws RepositoryException {
79 Node parentNode = node.getParent();
80
81
82 String newPath = NodeUtil.getAbsolutePath(parentNode.getPath(), getUniqueName(node));
83
84
85 Session session = node.getSession();
86 session.getWorkspace().copy(node.getPath(), newPath);
87 Node duplicatedNode = session.getNode(newPath);
88
89 updateAllNameProperties(duplicatedNode);
90
91 NodeUtil.orderAfter(duplicatedNode, node.getName());
92 session.save();
93
94 return duplicatedNode;
95 }
96
97 protected String getUniqueName(Node node) throws RepositoryException {
98 return getNodeNameHelper().getUniqueName(node.getSession(), node.getParent().getPath(), node.getName());
99 }
100
101 protected void updateAllNameProperties(Node node) throws RepositoryException {
102 updateProperty(node, Optional.ofNullable(jcrDatasourceDefinition.getNodeNameProperty()).orElse("jcrName"), node.getName());
103 }
104
105 protected Matcher getRegexMatcher(String property) throws RepositoryException {
106 Pattern digitSuffixPattern = Pattern.compile("(?<name>.*[^0-9])?(?<suffix>[0-9]+)$");
107 return digitSuffixPattern.matcher(property);
108 }
109
110 protected void updateProperty(Node node, String property, String nodeName) throws RepositoryException {
111 if (node.hasProperty(property)) {
112 String propertyValue = node.getProperty(property).getString();
113
114 Matcher nodeNameSuffixMatch = getRegexMatcher(nodeName);
115 Matcher jcrNameSuffixMatch = getRegexMatcher(propertyValue);
116
117 if (nodeNameSuffixMatch.find()) {
118 if (jcrNameSuffixMatch.find()) {
119 propertyValue = StringUtils.defaultString(jcrNameSuffixMatch.group("name"));
120 }
121 propertyValue += StringUtils.defaultString(nodeNameSuffixMatch.group("suffix"));
122 }
123
124 node.setProperty(property, propertyValue);
125 }
126 }
127 }