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