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.filter;
35
36 import info.magnolia.jcr.decoration.ContentDecoratorNodeIterator;
37 import info.magnolia.jcr.decoration.ContentDecoratorNodeWrapper;
38 import info.magnolia.jcr.predicate.JCRMgnlPropertyHidingPredicate;
39 import info.magnolia.jcr.wrapper.ChildFilteringContentDecorator;
40 import info.magnolia.jcr.wrapper.PropertyFilteringContentDecorator;
41 import info.magnolia.rest.delivery.jcr.decorator.ReferenceExpandDecorator;
42 import info.magnolia.rest.delivery.jcr.decorator.ReferenceExpandWrapper;
43 import info.magnolia.rest.reference.ReferenceDefinition;
44
45 import java.util.ArrayList;
46 import java.util.Collections;
47 import java.util.List;
48
49 import javax.jcr.Node;
50 import javax.jcr.NodeIterator;
51 import javax.jcr.RepositoryException;
52
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
55
56
57
58
59 public class FilteringContentDecoratorBuilder implements Cloneable {
60 private static final Logger log = LoggerFactory.getLogger(FilteringContentDecoratorBuilder.class);
61
62 private List<String> childNodeTypes = new ArrayList<>();
63 private boolean includeSystemProperties;
64 private int depth;
65 private List<ReferenceDefinition> references = new ArrayList<>();
66
67 public FilteringContentDecoratorBuilder childNodeTypes(List<String> childrenNodeTypes) {
68 this.childNodeTypes = childrenNodeTypes;
69 return this;
70 }
71
72 public FilteringContentDecoratorBuilder includeSystemProperties(boolean includeSystemProperties) {
73 this.includeSystemProperties = includeSystemProperties;
74 return this;
75 }
76
77 public FilteringContentDecoratorBuilder depth(int depth) {
78 this.depth = depth;
79 return this;
80 }
81
82 public FilteringContentDecoratorBuilder references(List<ReferenceDefinition> references) {
83 this.references = references;
84 return this;
85 }
86
87 public Node wrapNode(Node node) {
88 if (!childNodeTypes.isEmpty()) {
89 node = new ContentDecoratorNodeWrapper<>(node, new ChildFilteringContentDecorator(new NodeTypesPredicate(childNodeTypes), true));
90 }
91
92 if (!includeSystemProperties) {
93 node = new ContentDecoratorNodeWrapper<>(node, new PropertyFilteringContentDecorator(new JCRMgnlPropertyHidingPredicate()));
94 }
95
96 if (depth >= 0) {
97 ChildFilteringContentDecorator depthDecorator = new ChildFilteringContentDecorator(new DepthFilteringPredicate(getDepth(node), getDepth(node) + depth), true);
98 node = new ContentDecoratorNodeWrapper<>(node, depthDecorator);
99 }
100
101 if (references != null && !references.isEmpty()) {
102 FilteringContentDecoratorBuilder expandDecorators = this.clone();
103 expandDecorators
104 .childNodeTypes(Collections.emptyList())
105 .depth(-1);
106
107 node = new ReferenceExpandWrapper(node, references, expandDecorators);
108 }
109
110 return node;
111 }
112
113 public NodeIterator wrapNodeIterator(NodeIterator nodeIterator) {
114
115 if (!childNodeTypes.isEmpty()) {
116 nodeIterator = new ChildNodeTypesFilteringNodeIterator(nodeIterator, childNodeTypes);
117 }
118
119 if (!includeSystemProperties) {
120 nodeIterator = new ContentDecoratorNodeIterator(nodeIterator, new PropertyFilteringContentDecorator(new JCRMgnlPropertyHidingPredicate()));
121 }
122
123 if (depth >= 0) {
124 nodeIterator = new DepthFilteringDecoratorNodeIterator(nodeIterator, depth);
125 }
126
127 if (references != null && !references.isEmpty()) {
128 FilteringContentDecoratorBuilder expandDecorators = this.clone();
129 expandDecorators
130 .childNodeTypes(Collections.emptyList())
131 .depth(-1);
132
133 nodeIterator = new ContentDecoratorNodeIterator(nodeIterator, new ReferenceExpandDecorator(references, expandDecorators));
134 }
135
136 return nodeIterator;
137 }
138
139 private int getDepth(Node node) {
140 try {
141 return node.getDepth();
142 } catch (RepositoryException e) {
143 return 0;
144 }
145 }
146
147 @Override
148 public FilteringContentDecoratorBuilder clone() {
149 try {
150 return (FilteringContentDecoratorBuilder) super.clone();
151 } catch (CloneNotSupportedException e) {
152 log.warn("Cannot clone new builder!", e);
153 }
154
155 return new FilteringContentDecoratorBuilder();
156 }
157 }