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