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