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