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.rest.delivery.jcr.decorator;
35
36 import info.magnolia.jcr.util.NodeUtil;
37 import info.magnolia.jcr.wrapper.DelegateNodeWrapper;
38
39 import java.util.Collection;
40 import java.util.Collections;
41 import java.util.HashSet;
42 import java.util.Iterator;
43 import java.util.List;
44 import java.util.Set;
45 import java.util.stream.Collectors;
46
47 import javax.jcr.Item;
48 import javax.jcr.Node;
49 import javax.jcr.NodeIterator;
50 import javax.jcr.Property;
51 import javax.jcr.PropertyIterator;
52 import javax.jcr.RepositoryException;
53
54 import org.apache.jackrabbit.commons.ItemNameMatcher;
55 import org.apache.jackrabbit.commons.iterator.NodeIteratorAdapter;
56 import org.apache.jackrabbit.commons.iterator.PropertyIteratorAdapter;
57 import org.apache.jackrabbit.spi.commons.iterator.Iterators;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61 import com.google.common.collect.Lists;
62
63
64
65
66 public class AdditionNodeWrapper extends DelegateNodeWrapper {
67 private static final Logger log = LoggerFactory.getLogger(AdditionNodeWrapper.class);
68
69 private final String placeholderName;
70 private final List<Item> additionItems;
71
72 public AdditionNodeWrapper(Node node, String placeholderName, List<Item> additionItems) {
73 super(node);
74 this.placeholderName = placeholderName;
75 this.additionItems = additionItems;
76 }
77
78 public AdditionNodeWrapper(Node node, String placeholderName) {
79 this(node, placeholderName, Collections.emptyList());
80 }
81
82 public AdditionNodeWrapper(Node node, List<Item> additionItems) {
83 this(node, null, additionItems);
84 }
85
86 @Override
87 public void setWrappedNode(Node node) {
88 this.wrapped = node;
89 }
90
91 protected List<Item> getAdditionItems() {
92 return additionItems;
93 }
94
95 @Override
96 public String getName() throws RepositoryException {
97 return placeholderName == null ? super.getName() : placeholderName;
98 }
99
100 @Override
101 public PropertyIterator getProperties() throws RepositoryException {
102 return getProperties("*");
103 }
104
105 @Override
106 public PropertyIterator getProperties(String namePattern) throws RepositoryException {
107 return getProperties(new String[] { namePattern });
108 }
109
110 @Override
111 public PropertyIterator getProperties(String[] nameGlobs) throws RepositoryException {
112 Iterator<Property> properties = Iterators.properties(super.getProperties(nameGlobs));
113
114 List<Property> merged = Lists.newArrayList(properties);
115 List<Property> resolvedProperties = getAdditionItems().stream()
116 .filter(item -> {
117 try {
118 return !item.isNode() && ItemNameMatcher.matches(item.getName(), nameGlobs);
119 } catch (RepositoryException e) {
120 log.warn("Cannot get name of item {}:", item, e);
121 }
122
123 return false;
124 })
125 .map(item -> (Property) item)
126 .collect(Collectors.toList());
127 merged.addAll(resolvedProperties);
128
129 return new PropertyIteratorAdapter(merged);
130 }
131
132 @Override
133 public boolean hasNodes() throws RepositoryException {
134 boolean hasNodes = getAdditionItems().stream().anyMatch(Item::isNode);
135 return hasNodes || super.hasNodes();
136 }
137
138 @Override
139 public boolean hasProperties() throws RepositoryException {
140 boolean hasProperties = getAdditionItems().stream().anyMatch(item -> !item.isNode());
141 return hasProperties || super.hasProperties();
142 }
143
144 @Override
145 public NodeIterator getNodes() throws RepositoryException {
146 return getNodes("*");
147 }
148
149 @Override
150 public NodeIterator getNodes(String namePattern) throws RepositoryException {
151 return getNodes(new String[] { namePattern });
152 }
153
154 @Override
155 public NodeIterator getNodes(String[] nameGlobs) throws RepositoryException {
156 Collection<Node> children = NodeUtil.getCollectionFromNodeIterator(getWrappedNode().getNodes(nameGlobs));
157
158 Set<Node> merged = new HashSet<>();
159 for (Node child : children) {
160 for (Item item : getAdditionItems()) {
161 if (!item.isNode()) {
162 continue;
163 }
164
165
166 if (child.getName().equals(item.getName())) {
167 child = new AdditionNodeWrapper(child, Lists.newArrayList (((Node) item).getProperties()));
168 } else if (!getWrappedNode().hasNode(item.getName())) {
169 merged.add((Node) item);
170 }
171 }
172
173 merged.add(child);
174 }
175
176 return new NodeIteratorAdapter(merged);
177 }
178 }