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 public InheritanceContentWrapper(Content wrappedContent, boolean inherited) {
83 super(wrappedContent);
84 this.inherited = inherited;
85 }
86
87
88
89
90
91 public InheritanceContentWrapper(Content node) {
92 this(node, false);
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 children = new ArrayList();
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 }
120 catch (RepositoryException e) {
121 throw new RuntimeException("Can't inherit children from " + getWrappedContent(), e);
122 }
123
124
125 children.addAll(((AbstractContent)getWrappedContent()).getChildren(filter, namePattern, orderCriteria));
126 if(orderCriteria != null){
127 Collections.sort(children, orderCriteria);
128 }
129
130 return wrapContentNodes(children);
131 }
132
133
134
135
136 protected String resolveInnerPath() throws RepositoryException {
137 final String path;
138 InheritanceContentWrapper anchor = findAnchor();
139
140 if(anchor == null){
141 path = this.getHandle();
142 }
143 else{
144 path = StringUtils.substringAfter(this.getHandle(), anchor.getHandle());
145 }
146 return StringUtils.removeStart(path,"/");
147 }
148
149
150
151
152 protected Content getContentSafely(String name) throws RepositoryException {
153 if(getWrappedContent().hasContent(name)){
154 return super.getContent(name);
155 }
156
157 String innerPath = resolveInnerPath() + "/" + name;
158 innerPath = StringUtils.removeStart(innerPath,"/");
159
160 Content inherited = getContentSafely(findNextAnchor(), innerPath);
161 return inherited;
162 }
163
164
165
166
167 protected Content getContentSafely(InheritanceContentWrapper anchor, String path) throws RepositoryException{
168 if(anchor == null){
169 return null;
170 }
171 if(StringUtils.isEmpty(path)){
172 return anchor;
173 }
174 return anchor.getContentSafely(path);
175 }
176
177
178
179
180 protected InheritanceContentWrapper findAnchor() throws RepositoryException{
181 if(getLevel() ==0){
182 return null;
183 }
184 if(isAnchor()){
185 return this;
186 }
187
188 return ((InheritanceContentWrapper)getParent()).findAnchor();
189 }
190
191
192
193
194 protected InheritanceContentWrapper findNextAnchor() throws RepositoryException{
195 final InheritanceContentWrapper currentAnchor = findAnchor();
196 if(currentAnchor != null && getLevel() >0){
197 return ((InheritanceContentWrapper)currentAnchor.getParent()).findAnchor();
198 }
199 return null;
200 }
201
202
203
204
205 protected boolean isAnchor() {
206 return isNodeType(ItemType.CONTENT.getSystemName());
207 }
208
209 public NodeData getNodeData(String name) {
210 try {
211 if (getWrappedContent().hasNodeData(name)) {
212 return getWrappedContent().getNodeData(name);
213 }
214 Content inherited = getContentSafely(findNextAnchor(), resolveInnerPath());
215 if(inherited != null){
216 return inherited.getNodeData(name);
217 }
218 }
219 catch (RepositoryException e) {
220 throw new RuntimeException("Can't inherit nodedata " + name + " for " + getWrappedContent(), e);
221
222 }
223
224 return super.getNodeData(name);
225 }
226
227
228
229
230 protected Content wrap(Content node) {
231
232 if(node instanceof InheritanceContentWrapper){
233 return node;
234 }
235
236 boolean inherited = !isSubNode(node);
237 return new InheritanceContentWrapper(node, inherited);
238 }
239
240
241
242
243 protected boolean isSubNode(Content node) {
244 return node.getHandle().startsWith(getWrappedContent().getHandle());
245 }
246
247 public boolean isInherited() {
248 return this.inherited;
249 }
250 }