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.editor;
35
36 import info.magnolia.jcr.RuntimeRepositoryException;
37 import info.magnolia.jcr.util.NodeNameHelper;
38 import info.magnolia.jcr.util.NodeUtil;
39 import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
40
41 import java.util.List;
42 import java.util.Locale;
43 import java.util.regex.Matcher;
44 import java.util.regex.Pattern;
45
46 import javax.inject.Inject;
47 import javax.jcr.Item;
48 import javax.jcr.Node;
49 import javax.jcr.RepositoryException;
50
51 import org.apache.commons.lang3.StringUtils;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 import com.google.common.collect.Lists;
56
57
58
59
60
61 public class DefaultJcrNodeOrderHandler implements MultiFormDefinition.OrderHandler<Node> {
62
63 private static final Logger log = LoggerFactory.getLogger(DefaultJcrNodeOrderHandler.class);
64
65 private static final Pattern INDEX_PATTERN = Pattern.compile("(?<name>.*?)(?<index>\\d*)(?<i18n>_[a-z]{2})?");
66 private static final String TMP_NAME_PREFIX = "__TMP_NAME_PREFIX";
67
68 private final I18NAuthoringSupport<Item> i18NAuthoringSupport;
69 private final NodeNameHelper nodeNameHelper;
70 private final Locale locale;
71
72 @Inject
73 public DefaultJcrNodeOrderHandler(I18NAuthoringSupport<Item> i18NAuthoringSupport,
74 Locale locale,
75 NodeNameHelper nodeNameHelper) {
76 this.i18NAuthoringSupport = i18NAuthoringSupport;
77 this.locale = locale;
78 this.nodeNameHelper = nodeNameHelper;
79 }
80
81 @Override
82 public void applyOrder(List<Node> nodeOrder) {
83 if (nodeOrder.isEmpty()) {
84 return;
85 }
86
87 try {
88 Node parent = nodeOrder.get(0).getParent();
89 for (int idx = 0; idx < nodeOrder.size(); ++idx) {
90 Node node = nodeOrder.get(idx);
91 Matcher indexedNameMatcher = INDEX_PATTERN.matcher(node.getName());
92 if (indexedNameMatcher.matches()) {
93 String name = refreshIndexInNodeName(idx, node, indexedNameMatcher);
94 node.getSession().move(node.getPath(), getParentPathWithSlash(node) + TMP_NAME_PREFIX + name);
95 } else {
96 log.warn("Node name [{}] mentions no index, node is ignored by [{}]", node.getName(), DefaultJcrNodeOrderHandler.class.getName());
97 }
98 }
99
100 for (Node node : Lists.newArrayList(NodeUtil.getNodes(parent))) {
101 String nodeName = node.getName();
102 if (nodeName.startsWith(TMP_NAME_PREFIX)) {
103 String parentPath = getParentPathWithSlash(node);
104 node.getSession().move(
105 parentPath + nodeName,
106 parentPath + nodeName.substring(TMP_NAME_PREFIX.length()));
107 }
108 }
109
110 } catch (RepositoryException e) {
111 throw new RuntimeRepositoryException(e);
112 }
113 }
114
115 private String refreshIndexInNodeName(int idx, Node node, Matcher indexedNameMatcher) {
116 String name = createIndexedName(indexedNameMatcher.group("name"), idx);
117 name = localize(node, name);
118 return name;
119 }
120
121 private String localize(Node node, String name) {
122 if (i18NAuthoringSupport.getDefaultLocale(node) != null && !i18NAuthoringSupport.isDefaultLocale(locale, node)) {
123 name = i18NAuthoringSupport.deriveLocalisedPropertyName(name, locale);
124 }
125 return name;
126 }
127
128 protected String createIndexedName(String name, int idx) {
129 return name + idx;
130 }
131
132 private String getParentPathWithSlash(Node node) throws RepositoryException {
133 return StringUtils.appendIfMissing(node.getParent().getPath(), "/");
134 }
135
136
137
138
139 public static class Definition extends MultiFormDefinition.OrderHandlerDefinition<Node> {
140
141 public Definition() {
142 setImplementationClass(DefaultJcrNodeOrderHandler.class);
143 }
144 }
145 }