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