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.cms.util;
35
36 import info.magnolia.cms.core.AbstractContent;
37 import info.magnolia.cms.core.Content;
38 import info.magnolia.cms.core.ItemType;
39 import info.magnolia.cms.core.NodeData;
40
41 import java.util.ArrayList;
42 import java.util.Collection;
43 import java.util.Collections;
44 import java.util.Comparator;
45 import java.util.List;
46
47 import javax.jcr.PathNotFoundException;
48 import javax.jcr.RepositoryException;
49
50 import org.apache.commons.lang3.StringUtils;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public class InheritanceContentWrapper extends ContentWrapper {
72
73 private static Logger log = LoggerFactory.getLogger(InheritanceContentWrapper.class);
74
75
76
77
78 private final Content start;
79
80
81
82
83 public InheritanceContentWrapper(Content wrappedContent, Content start) {
84 super(wrappedContent);
85 this.start = start;
86 }
87
88
89
90
91 public InheritanceContentWrapper(Content node) {
92 this(node, node);
93 }
94
95 @Override
96 public boolean hasContent(String name) throws RepositoryException {
97 return getContentSafely(name) != null;
98 }
99
100 @Override
101 public Content getContent(String name) throws RepositoryException {
102 Content inherited = getContentSafely(name);
103 if (inherited == null) {
104 throw new PathNotFoundException("Can't inherit a node [" + name + "] on node [" + getWrappedContent().getHandle() + "]");
105 }
106 return inherited;
107 }
108
109 @Override
110 public Collection<Content> getChildren(ContentFilter filter, String namePattern, Comparator<Content> orderCriteria) {
111 List<Content> children = new ArrayList<Content>();
112
113
114 try {
115 Content inherited = getContentSafely(findNextAnchor(), resolveInnerPath());
116 if (inherited != null) {
117 children.addAll(((AbstractContent) inherited).getChildren(filter, namePattern, orderCriteria));
118 }
119 } catch (RepositoryException e) {
120 throw new RuntimeException("Can't inherit children from " + getWrappedContent(), e);
121 }
122
123
124 children.addAll(((AbstractContent) getWrappedContent()).getChildren(filter, namePattern, orderCriteria));
125 if (orderCriteria != null) {
126 Collections.sort(children, orderCriteria);
127 }
128
129 return wrapContentNodes(children);
130 }
131
132
133
134
135 protected String resolveInnerPath() throws RepositoryException {
136 final String path;
137 InheritanceContentWrapper anchor = findAnchor();
138
139 if (anchor == null) {
140 path = this.getHandle();
141 } else {
142 path = StringUtils.substringAfter(this.getHandle(), anchor.getHandle());
143 }
144 return StringUtils.removeStart(path, "/");
145 }
146
147
148
149
150 protected Content getContentSafely(String name) throws RepositoryException {
151 if (getWrappedContent().hasContent(name)) {
152 return super.getContent(name);
153 }
154
155 String innerPath = resolveInnerPath() + "/" + name;
156 innerPath = StringUtils.removeStart(innerPath, "/");
157
158 Content inherited = getContentSafely(findNextAnchor(), innerPath);
159 return inherited;
160 }
161
162
163
164
165 protected Content getContentSafely(InheritanceContentWrapper anchor, String path) throws RepositoryException {
166 if (anchor == null) {
167 return null;
168 }
169 if (StringUtils.isEmpty(path)) {
170 return anchor;
171 }
172 return anchor.getContentSafely(path);
173 }
174
175
176
177
178 protected InheritanceContentWrapper findAnchor() throws RepositoryException {
179 if (getLevel() == 0) {
180 return null;
181 }
182 if (isAnchor()) {
183 return this;
184 }
185
186 return ((InheritanceContentWrapper) getParent()).findAnchor();
187 }
188
189
190
191
192 protected InheritanceContentWrapper findNextAnchor() throws RepositoryException {
193 final InheritanceContentWrapper currentAnchor = findAnchor();
194 if (currentAnchor != null && getLevel() > 0) {
195 return ((InheritanceContentWrapper) currentAnchor.getParent()).findAnchor();
196 }
197 return null;
198 }
199
200
201
202
203 protected boolean isAnchor() {
204 return isNodeType(ItemType.CONTENT.getSystemName());
205 }
206
207 @Override
208 public NodeData getNodeData(String name) {
209 try {
210 if (getWrappedContent().hasNodeData(name)) {
211 return getWrappedContent().getNodeData(name);
212 }
213 Content inherited = getContentSafely(findNextAnchor(), resolveInnerPath());
214 if (inherited != null) {
215 return inherited.getNodeData(name);
216 }
217 } catch (RepositoryException e) {
218 throw new RuntimeException("Can't inherit nodedata " + name + " for " + getWrappedContent(), e);
219
220 }
221
222 return super.getNodeData(name);
223 }
224
225 @Override
226 public boolean hasNodeData(String name) throws RepositoryException {
227 try {
228 if (getWrappedContent().hasNodeData(name)) {
229 return getWrappedContent().hasNodeData(name);
230 }
231 Content inherited = getContentSafely(findNextAnchor(), resolveInnerPath());
232 if (inherited != null) {
233 return inherited.hasNodeData(name);
234 }
235 } catch (RepositoryException e) {
236 throw new RuntimeException("Can't inherit nodedata " + name + " for " + getWrappedContent(), e);
237
238 }
239
240 return super.hasNodeData(name);
241 }
242
243
244
245
246 @Override
247 protected Content wrap(Content node) {
248
249 if (node instanceof InheritanceContentWrapper) {
250 return node;
251 }
252 return new InheritanceContentWrapper(node, start);
253 }
254
255
256
257
258 public boolean isInherited() {
259 return !getWrappedContent().getHandle().startsWith(start.getHandle());
260 }
261
262 }