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