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.module.delta;
35
36 import info.magnolia.cms.filters.FilterManager;
37 import info.magnolia.jcr.util.NodeUtil;
38 import info.magnolia.module.InstallContext;
39
40 import java.util.ArrayList;
41 import java.util.Arrays;
42 import java.util.Collection;
43 import java.util.HashSet;
44 import java.util.List;
45 import java.util.Set;
46
47 import javax.jcr.Node;
48 import javax.jcr.NodeIterator;
49 import javax.jcr.RepositoryException;
50
51
52
53
54
55
56
57
58
59 public class OrderFilterBeforeTask extends AbstractRepositoryTask {
60
61 private final String filterToBeOrderedName;
62 private final List<String> requiredFilters;
63 private final List<String> optionalFilters;
64
65 public OrderFilterBeforeTask(String filterName, String[] filtersAfter) {
66 this(filterName, filtersAfter, new String[]{});
67 }
68
69 public OrderFilterBeforeTask(String filterName, String[] filtersAfter, String[] optionalFiltersAfter) {
70 this(filterName, "Orders the " + filterName + " filter in the filter chain.", filtersAfter, optionalFiltersAfter);
71 }
72
73 public OrderFilterBeforeTask(String filterName, String description, String[] requiredFiltersAfter) {
74 this(filterName, description, requiredFiltersAfter, new String[]{});
75 }
76
77 public OrderFilterBeforeTask(String filterName, String description, String[] requiredFiltersAfter, String[] optionalFiltersAfter) {
78 super("Setup " + filterName + " filter", description);
79 this.filterToBeOrderedName = filterName;
80 this.requiredFilters = new ArrayList<String>(Arrays.asList(requiredFiltersAfter));
81 this.optionalFilters = new ArrayList<String>(Arrays.asList(optionalFiltersAfter));
82 }
83
84 @Override
85 protected void doExecute(InstallContext ctx) throws RepositoryException, TaskExecutionException {
86 final Node filtersParent = ctx.getConfigJCRSession().getNode(FilterManager.SERVER_FILTERS);
87
88 if (!filtersParent.hasNode(filterToBeOrderedName)) {
89 throw new TaskExecutionException("Filter with name " + filterToBeOrderedName + " can't be found.");
90 }
91
92 if (!requiredFilters.isEmpty() && !hasNodes(filtersParent, requiredFilters)) {
93 ctx.warn("Could not sort filter " + filterToBeOrderedName + ". It should be positioned before " + requiredFilters);
94 return;
95 }
96
97 Set<String> combinedFilterNames = new HashSet<String>();
98 combinedFilterNames.addAll(requiredFilters);
99 combinedFilterNames.addAll(optionalFilters);
100
101 orderBeforeSiblings(filtersParent.getNode(filterToBeOrderedName), combinedFilterNames);
102 }
103
104 private void orderBeforeSiblings(Node node, Set<String> siblingNames) throws RepositoryException {
105 Node firstMatch = getFirstChild(node.getParent(), siblingNames);
106 if (firstMatch != null) {
107 NodeUtil.orderBefore(node, firstMatch.getName());
108 }
109 }
110
111 private Node getFirstChild(Node parentNode, Collection<String> childNames) throws RepositoryException {
112 NodeIterator nodes = parentNode.getNodes();
113 while (nodes.hasNext()) {
114 Node child = nodes.nextNode();
115 if (childNames.contains(child.getName())) {
116 return child;
117 }
118 }
119 return null;
120 }
121
122 private boolean hasNodes(Node node, Collection<String> childNames) throws RepositoryException {
123 for (String childName : childNames) {
124 if (!node.hasNode(childName)) {
125 return false;
126 }
127 }
128 return true;
129 }
130 }