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 FilterOrderingTask extends AbstractRepositoryTask {
60
61 private final String filterToBeOrderedName;
62 private final List<String> requiredFilters;
63 private final List<String> optionalFilters;
64
65
66
67
68
69 public FilterOrderingTask(String filterName, String[] requiredFiltersBefore) {
70 this(filterName, requiredFiltersBefore, new String[]{});
71 }
72
73 public FilterOrderingTask(String filterName, String[] requiredFiltersBefore, String[] optionalFiltersBefore) {
74 this(filterName, "Orders the " + filterName + " filter in the filter chain.", requiredFiltersBefore, optionalFiltersBefore);
75 }
76
77 public FilterOrderingTask(String filterName, String description, String[] requiredFiltersBefore) {
78 this(filterName, description, requiredFiltersBefore, new String[]{});
79 }
80
81 public FilterOrderingTask(String filterName, String description, String[] requiredFiltersBefore, String[] optionalFiltersBefore) {
82 super("Setup " + filterName + " filter", description);
83 this.filterToBeOrderedName = filterName;
84 this.requiredFilters = new ArrayList<String>(Arrays.asList(requiredFiltersBefore));
85 this.optionalFilters = new ArrayList<String>(Arrays.asList(optionalFiltersBefore));
86 }
87
88 @Override
89 protected void doExecute(InstallContext ctx) throws RepositoryException, TaskExecutionException {
90 final Node filtersParent = ctx.getConfigJCRSession().getNode(FilterManager.SERVER_FILTERS);
91
92
93 if (!filtersParent.hasNode(filterToBeOrderedName)) {
94 throw new TaskExecutionException("Filter with name " + filterToBeOrderedName + " can't be found.");
95 }
96
97 if (!requiredFilters.isEmpty() && !hasNodes(filtersParent, requiredFilters)) {
98 ctx.warn("Could not sort filter " + filterToBeOrderedName + ". It should be positioned after " + requiredFilters);
99 return;
100 }
101
102 Set<String> combinedFilterNames = new HashSet<String>();
103 combinedFilterNames.addAll(requiredFilters);
104 combinedFilterNames.addAll(optionalFilters);
105
106 orderAfterSiblings(filtersParent.getNode(filterToBeOrderedName), combinedFilterNames);
107 }
108
109 private void orderAfterSiblings(Node node, Set<String> siblingNames) throws RepositoryException {
110 Node lastMatch = getLastChild(node.getParent(), siblingNames);
111 if (lastMatch != null) {
112 NodeUtil.orderAfter(node, lastMatch.getName());
113 }
114 }
115
116 private Node getLastChild(Node parent, Collection<String> childNames) throws RepositoryException {
117 Node lastMatch = null;
118 NodeIterator nodes = parent.getNodes();
119 while (nodes.hasNext()) {
120 Node child = nodes.nextNode();
121 if (childNames.contains(child.getName())) {
122 lastMatch = child;
123 }
124 }
125 return lastMatch;
126 }
127
128 private boolean hasNodes(Node node, Collection<String> childNames) throws RepositoryException {
129 for (String childName : childNames) {
130 if (!node.hasNode(childName)) {
131 return false;
132 }
133 }
134 return true;
135 }
136 }