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 Boolean getEnabled() {
78 return enabled;
79 }
80
81 public void setEnabled(Boolean enabled) {
82 this.enabled = enabled;
83 }
84
85 public String getComponents() {
86 return components;
87 }
88
89 public void setComponents(String components) {
90 this.components = components;
91 }
92
93 public void setProperties(String properties) {
94 this.properties = properties;
95 }
96
97 @Override
98 public Boolean isInheritsProperties() {
99 return isEnabled() != null && isEnabled() && StringUtils.equalsIgnoreCase(StringUtils.trim(properties), PROPERTIES_ALL);
100 }
101
102 @Override
103 public Boolean isInheritsComponents() {
104 return isEnabled() != null && isEnabled() && (StringUtils.equalsIgnoreCase(StringUtils.trim(components), COMPONENTS_ALL) || StringUtils.equalsIgnoreCase(StringUtils.trim(components), COMPONENTS_FILTERED));
105 }
106
107 @Override
108 public AbstractPredicate<Node> getComponentPredicate() {
109 if (isEnabled() == null || !isEnabled()) {
110 return new InheritNothingInheritancePredicate();
111 }
112 if (predicateClass != null) {
113 return Components.newInstance(predicateClass);
114 }
115 if (StringUtils.equalsIgnoreCase(StringUtils.trim(components), COMPONENTS_ALL)) {
116 InheritancePredicate inheritancePredicate = new InheritancePredicate();
117 inheritancePredicate.setNodeTypes(getNodeTypes());
118 return inheritancePredicate;
119 }
120 if (StringUtils.equalsIgnoreCase(StringUtils.trim(components), COMPONENTS_FILTERED)) {
121 FilteredInheritancePredicate filteredInheritancePredicate = new FilteredInheritancePredicate();
122 filteredInheritancePredicate.setNodeTypes(getNodeTypes());
123 return filteredInheritancePredicate;
124 }
125 return new InheritNothingInheritancePredicate();
126 }
127
128 public void setPredicateClass(Class<? extends AbstractPredicate<Node>> predicateClass) {
129 this.predicateClass = predicateClass;
130 }
131
132 @Override
133 public Comparator<Node> getComponentComparator() {
134 if (nodeComparatorClass != null) {
135 return Components.newInstance(nodeComparatorClass);
136 }
137 return new NodeDepthComparator();
138 }
139
140 public void setNodeComparatorClass(Class<? extends Comparator<Node>> nodeComparatorClass) {
141 this.nodeComparatorClass = nodeComparatorClass;
142 }
143
144 public List<String> getNodeTypes() {
145 return nodeTypes;
146 }
147
148 public void setNodeTypes(List<String> nodeTypes) {
149 this.nodeTypes = nodeTypes;
150 }
151
152
153
154
155
156
157
158 public static class FilteredComponentInheritancePredicate extends AbstractPredicate<Node> {
159
160 public static final String INHERITED_PROPERTY_NAME = "inheritable";
161
162 @Override
163 public boolean evaluateTyped(Node node) {
164 try {
165 return NodeUtil.isNodeType(node, NodeTypes.Component.NAME) && (node.hasProperty(INHERITED_PROPERTY_NAME) && Boolean.parseBoolean(node.getProperty(INHERITED_PROPERTY_NAME).getString()));
166 } catch (RepositoryException e) {
167 throw new RuntimeRepositoryException(e);
168 }
169 }
170 }
171
172
173
174
175
176
177 public static class AllComponentsAndResourcesInheritancePredicate extends AbstractPredicate<Node> {
178
179 @Override
180 public boolean evaluateTyped(Node node) {
181 try {
182 return NodeUtil.isNodeType(node, NodeTypes.Component.NAME) || NodeUtil.isNodeType(node, NodeTypes.Resource.NAME);
183 } catch (RepositoryException e) {
184 throw new RuntimeRepositoryException(e);
185 }
186 }
187 }
188
189
190
191
192 public static class InheritNothingInheritancePredicate extends AbstractPredicate<Node> {
193
194 @Override
195 public boolean evaluateTyped(Node node) {
196 return false;
197 }
198 }
199
200
201
202
203
204 public static class NodeDepthComparator implements Comparator<Node> {
205
206 @Override
207 public int compare(Node lhs, Node rhs) {
208 try {
209 if (lhs.getDepth() != rhs.getDepth())
210 return lhs.getDepth() - rhs.getDepth();
211 return getSiblingIndex(lhs) - getSiblingIndex(rhs);
212 } catch (RepositoryException e) {
213 throw new RuntimeRepositoryException(e);
214 }
215 }
216
217 private int getSiblingIndex(Node node) throws RepositoryException {
218 if (node.getDepth() == 0) {
219 return 0;
220 }
221 int index = 0;
222 NodeIterator nodes = node.getParent().getNodes();
223 while (nodes.hasNext()) {
224 if (NodeUtil.isSame(node, nodes.nextNode())) {
225 return index;
226 }
227 index++;
228 }
229 return -1;
230 }
231 }
232 }