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