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.Collection;
37 import java.util.Comparator;
38 import java.util.LinkedHashMap;
39 import java.util.SortedMap;
40 import java.util.TreeMap;
41
42 import javax.jcr.RepositoryException;
43
44 import info.magnolia.cms.core.AbstractContent;
45 import info.magnolia.cms.core.Content;
46 import info.magnolia.cms.core.NodeData;
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 public class ExtendingContentWrapper extends ContentWrapper {
70
71 private static final String EXTENDING_NODE_DATA = "extends";
72
73 private boolean extending;
74
75 private Content extendedContent;
76
77 public ExtendingContentWrapper(Content wrappedContent) {
78 super(wrappedContent);
79 try {
80 extending = getWrappedContent().hasNodeData(EXTENDING_NODE_DATA);
81 if (extending) {
82
83 extendedContent = wrapIfNeeded(getWrappedContent().getNodeData(EXTENDING_NODE_DATA).getReferencedContent());
84 }
85 }
86 catch (RepositoryException e) {
87 throw new RuntimeException("Can't wrap node [" + wrappedContent + "]", e);
88 }
89 }
90
91
92
93
94
95 protected ExtendingContentWrapper(Content wrappedContent, Content extendedContent) {
96 super(wrapIfNeeded(wrappedContent));
97 this.extending = true;
98
99 this.extendedContent = wrapIfNeeded(extendedContent);
100 }
101
102 private static Content wrapIfNeeded(Content content) {
103 if (content instanceof ExtendingContentWrapper) {
104 return content;
105 }
106 return new ExtendingContentWrapper(content);
107 }
108
109 public boolean isExtending() {
110 return this.extending;
111 }
112
113 @Override
114 public boolean hasContent(String name) throws RepositoryException {
115 if (getWrappedContent().hasContent(name)) {
116 return true;
117 }
118 else if (extending && extendedContent.hasContent(name)) {
119 return true;
120 }
121 return false;
122 }
123
124 @Override
125 public Content getContent(String name) throws RepositoryException {
126 Content content;
127 if (getWrappedContent().hasContent(name)) {
128 content = getWrappedContent().getContent(name);
129 }
130 else if (extending && extendedContent.hasContent(name)) {
131 content = extendedContent.getContent(name);
132 }
133 else {
134
135 content = getWrappedContent().getContent(name);
136 }
137 return wrap(content);
138 }
139
140 @Override
141 public Collection<Content> getChildren(ContentFilter filter, String namePattern, Comparator<Content> orderCriteria) {
142 Collection<Content> directChildren = ((AbstractContent)getWrappedContent()).getChildren(filter, namePattern, orderCriteria);
143 if (extending) {
144 Collection<Content> inheritedChildren = ((AbstractContent)extendedContent).getChildren(filter, namePattern, orderCriteria);
145
146 LinkedHashMap<String, Content> merged = new LinkedHashMap<String, Content>();
147 for (Content content : inheritedChildren) {
148 merged.put(content.getName(), content);
149 }
150 for (Content content : directChildren) {
151 merged.put(content.getName(), content);
152 }
153 return wrapContentNodes(merged.values());
154 }
155 else {
156 return wrapContentNodes(directChildren);
157 }
158 }
159
160 @Override
161 public NodeData getNodeData(String name) {
162 try {
163 if (getWrappedContent().hasNodeData(name)) {
164 return wrap(getWrappedContent().getNodeData(name));
165 }
166 else if (extending && extendedContent.hasNodeData(name)) {
167 return wrap(extendedContent.getNodeData(name));
168 }
169 else {
170 return wrap(getWrappedContent().getNodeData(name));
171 }
172 }
173 catch (RepositoryException e) {
174 throw new RuntimeException("Can't read nodedata from extended node [" + extendedContent + "]", e);
175 }
176 }
177
178 @Override
179 public Collection<NodeData> getNodeDataCollection() {
180 Collection<NodeData> directChildren = getWrappedContent().getNodeDataCollection();
181 if (extending) {
182 Collection<NodeData> inheritedChildren = extendedContent.getNodeDataCollection();
183
184 SortedMap<String, NodeData> merged = new TreeMap<String, NodeData>();
185 for (NodeData nodeData : inheritedChildren) {
186 merged.put(nodeData.getName(), nodeData);
187 }
188 for (NodeData nodeData : directChildren) {
189 merged.put(nodeData.getName(), nodeData);
190 }
191 return wrapNodeDatas(merged.values());
192 }
193 else {
194 return wrapNodeDatas(directChildren);
195 }
196 }
197
198 protected Content wrap(Content node) {
199
200 try {
201 if (extending && extendedContent.hasContent(node.getName())) {
202
203 Content extendedSubContent = extendedContent.getContent(node.getName());
204 return new ExtendingContentWrapper(node, extendedSubContent);
205 }
206 }
207 catch (RepositoryException e) {
208 throw new RuntimeException("Can't wrap " + node, e);
209 }
210 return new ExtendingContentWrapper(node);
211 }
212
213 }