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.rendering.template.configured;
35
36 import info.magnolia.jcr.RuntimeRepositoryException;
37 import info.magnolia.jcr.predicate.AbstractPredicate;
38 import info.magnolia.jcr.util.NodeTypes;
39 import info.magnolia.jcr.util.NodeUtil;
40 import info.magnolia.objectfactory.Components;
41 import info.magnolia.rendering.template.InheritanceConfiguration;
42
43 import java.util.Arrays;
44 import java.util.Comparator;
45 import java.util.List;
46
47 import javax.jcr.Node;
48 import javax.jcr.NodeIterator;
49 import javax.jcr.RepositoryException;
50
51 import org.apache.commons.lang3.StringUtils;
52
53
54
55
56 public class ConfiguredInheritance implements InheritanceConfiguration {
57
58 public static final String COMPONENTS_ALL = "all";
59 public static final String COMPONENTS_NONE = "none";
60 public static final String COMPONENTS_FILTERED = "filtered";
61
62 public static final String PROPERTIES_ALL = "all";
63 public static final String PROPERTIES_NONE = "none";
64
65 private Boolean enabled = false;
66 private String components = COMPONENTS_FILTERED;
67 private String properties = PROPERTIES_ALL;
68 private List<String> nodeTypes = Arrays.asList(NodeTypes.Component.NAME, NodeTypes.Resource.NAME);
69 private Class<? extends AbstractPredicate<Node>> predicateClass;
70 private Class<? extends Comparator<Node>> nodeComparatorClass;
71
72 @Override
73 public Boolean isEnabled() {
74 return enabled;
75 }
76
77 public void setEnabled(Boolean enabled) {
78 this.enabled = enabled;
79 }
80
81 public void setComponents(String components) {
82 this.components = components;
83 }
84
85 public void setProperties(String properties) {
86 this.properties = properties;
87 }
88
89 @Override
90 public Boolean isInheritsProperties() {
91 return isEnabled() != null && isEnabled() && StringUtils.equalsIgnoreCase(StringUtils.trim(properties), PROPERTIES_ALL);
92 }
93
94 @Override
95 public Boolean isInheritsComponents() {
96 return isEnabled() != null && isEnabled() && (StringUtils.equalsIgnoreCase(StringUtils.trim(components), COMPONENTS_ALL) || StringUtils.equalsIgnoreCase(StringUtils.trim(components), COMPONENTS_FILTERED));
97 }
98
99 @Override
100 public AbstractPredicate<Node> getComponentPredicate() {
101 if (isEnabled() == null || !isEnabled()) {
102 return new InheritNothingInheritancePredicate();
103 }
104 if (predicateClass != null) {
105 return Components.newInstance(predicateClass);
106 }
107 if (StringUtils.equalsIgnoreCase(StringUtils.trim(components), COMPONENTS_ALL)) {
108 InheritancePredicate inheritancePredicate = new InheritancePredicate();
109 inheritancePredicate.setNodeTypes(getNodeTypes());
110 return inheritancePredicate;
111 }
112 if (StringUtils.equalsIgnoreCase(StringUtils.trim(components), COMPONENTS_FILTERED)) {
113 FilteredInheritancePredicate filteredInheritancePredicate = new FilteredInheritancePredicate();
114 filteredInheritancePredicate.setNodeTypes(getNodeTypes());
115 return filteredInheritancePredicate;
116 }
117 return new InheritNothingInheritancePredicate();
118 }
119
120 public void setPredicateClass(Class<? extends AbstractPredicate<Node>> predicateClass) {
121 this.predicateClass = predicateClass;
122 }
123
124 @Override
125 public Comparator<Node> getComponentComparator() {
126 if (nodeComparatorClass != null) {
127 return Components.newInstance(nodeComparatorClass);
128 }
129 return new NodeDepthComparator();
130 }
131
132 public void setNodeComparatorClass(Class<? extends Comparator<Node>> nodeComparatorClass) {
133 this.nodeComparatorClass = nodeComparatorClass;
134 }
135
136 public List<String> getNodeTypes() {
137 return nodeTypes;
138 }
139
140 public void setNodeTypes(List<String> nodeTypes) {
141 this.nodeTypes = nodeTypes;
142 }
143
144
145
146
147
148
149
150 public static class FilteredComponentInheritancePredicate extends AbstractPredicate<Node> {
151
152 public static final String INHERITED_PROPERTY_NAME = "inheritable";
153
154 @Override
155 public boolean evaluateTyped(Node node) {
156 try {
157 return NodeUtil.isNodeType(node, NodeTypes.Component.NAME) && (node.hasProperty(INHERITED_PROPERTY_NAME) && Boolean.parseBoolean(node.getProperty(INHERITED_PROPERTY_NAME).getString()));
158 } catch (RepositoryException e) {
159 throw new RuntimeRepositoryException(e);
160 }
161 }
162 }
163
164
165
166
167
168
169 public static class AllComponentsAndResourcesInheritancePredicate extends AbstractPredicate<Node> {
170
171 @Override
172 public boolean evaluateTyped(Node node) {
173 try {
174 return NodeUtil.isNodeType(node, NodeTypes.Component.NAME) || NodeUtil.isNodeType(node, NodeTypes.Resource.NAME);
175 } catch (RepositoryException e) {
176 throw new RuntimeRepositoryException(e);
177 }
178 }
179 }
180
181
182
183
184 public static class InheritNothingInheritancePredicate extends AbstractPredicate<Node> {
185
186 @Override
187 public boolean evaluateTyped(Node node) {
188 return false;
189 }
190 }
191
192
193
194
195
196 public static class NodeDepthComparator implements Comparator<Node> {
197
198 @Override
199 public int compare(Node lhs, Node rhs) {
200 try {
201 if (lhs.getDepth() != rhs.getDepth())
202 return lhs.getDepth() - rhs.getDepth();
203 return getSiblingIndex(lhs) - getSiblingIndex(rhs);
204 } catch (RepositoryException e) {
205 throw new RuntimeRepositoryException(e);
206 }
207 }
208
209 private int getSiblingIndex(Node node) throws RepositoryException {
210 if (node.getDepth() == 0) {
211 return 0;
212 }
213 int index = 0;
214 NodeIterator nodes = node.getParent().getNodes();
215 while (nodes.hasNext()) {
216 if (NodeUtil.isSame(node, nodes.nextNode())) {
217 return index;
218 }
219 index++;
220 }
221 return -1;
222 }
223 }
224 }