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 }
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 @Override
210 public NodeData getNodeData(String name) {
211 try {
212 if (getWrappedContent().hasNodeData(name)) {
213 return getWrappedContent().getNodeData(name);
214 }
215 Content inherited = getContentSafely(findNextAnchor(), resolveInnerPath());
216 if(inherited != null){
217 return inherited.getNodeData(name);
218 }
219 }
220 catch (RepositoryException e) {
221 throw new RuntimeException("Can't inherit nodedata " + name + " for " + getWrappedContent(), e);
222
223 }
224
225 return super.getNodeData(name);
226 }
227
228 @Override
229 public boolean hasNodeData(String name) throws RepositoryException {
230 try {
231 if (getWrappedContent().hasNodeData(name)) {
232 return getWrappedContent().hasNodeData(name);
233 }
234 Content inherited = getContentSafely(findNextAnchor(), resolveInnerPath());
235 if (inherited != null) {
236 return inherited.hasNodeData(name);
237 }
238 } catch (RepositoryException e) {
239 throw new RuntimeException("Can't inherit nodedata " + name + " for " + getWrappedContent(), e);
240
241 }
242
243 return super.hasNodeData(name);
244 }
245
246
247
248
249 @Override
250 protected Content wrap(Content node) {
251
252 if(node instanceof InheritanceContentWrapper){
253 return node;
254 }
255 return new InheritanceContentWrapper(node, start);
256 }
257
258
259
260
261 public boolean isInherited() {
262 return !getWrappedContent().getHandle().startsWith(start.getHandle());
263 }
264
265 }