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.ui.contentapp;
35
36 import static java.util.Spliterators.spliterator;
37
38 import info.magnolia.context.Context;
39 import info.magnolia.jcr.RuntimeRepositoryException;
40 import info.magnolia.ui.datasource.jcr.JcrDatasourceDefinition;
41 import info.magnolia.ui.framework.datasource.components.HierarchySupport;
42
43 import java.util.ArrayList;
44 import java.util.List;
45 import java.util.Optional;
46 import java.util.Spliterator;
47 import java.util.stream.Stream;
48 import java.util.stream.StreamSupport;
49
50 import javax.inject.Inject;
51 import javax.inject.Provider;
52 import javax.jcr.Item;
53 import javax.jcr.Node;
54 import javax.jcr.NodeIterator;
55 import javax.jcr.RepositoryException;
56 import javax.jcr.Session;
57
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61 import lombok.SneakyThrows;
62
63
64
65
66 public class JcrWorkspaceHierarchySupport implements HierarchySupport<Item> {
67
68 private static final Logger log = LoggerFactory.getLogger(JcrWorkspaceHierarchySupport.class);
69
70 private final JcrDatasourceDefinition jcrDatasourceDefinition;
71 private final Provider<Context> contextProvider;
72
73 @Inject
74 public JcrWorkspaceHierarchySupport(JcrDatasourceDefinition jcrDatasourceDefinition, Provider<Context> contextProvider) {
75 this.jcrDatasourceDefinition = jcrDatasourceDefinition;
76 this.contextProvider = contextProvider;
77 }
78
79 @Override
80 @SneakyThrows
81 public Stream<Item> getRootItems() {
82 return nodeIteratorToStream(getSession().getRootNode().getNodes());
83 }
84
85 @Override
86 @SneakyThrows
87 public Stream<Item> getChildren(Item parent) {
88 if (!parent.isNode()) {
89 return Stream.empty();
90 }
91 return nodeIteratorToStream(((Node) parent).getNodes());
92 }
93
94 @Override
95 public Stream<Item> getParents(Item item) {
96 try {
97 if (!item.isNode()) {
98 return Stream.of(item.getParent());
99 }
100 final List<Item> parents = new ArrayList<>();
101 Optional<Item> parent = getDirectParent(item);
102 while (parent.isPresent()) {
103 parents.add(parent.get());
104 parent = getDirectParent(parent.get());
105 }
106 return parents.stream();
107 } catch (RepositoryException e) {
108 log.debug("Failed to resolve Node parent");
109 return Stream.empty();
110 }
111 }
112
113 @Override
114 @SneakyThrows
115 public Optional<Item> getDirectParent(Item item) {
116 if (item.getDepth() == 0) {
117 return Optional.empty();
118 }
119
120 return Optional.of(item.getParent());
121 }
122
123 @SuppressWarnings("unchecked")
124 private Stream<Item> nodeIteratorToStream(NodeIterator nodeIterator) {
125 return StreamSupport.stream(
126 spliterator(
127 nodeIterator,
128 nodeIterator.getSize(),
129 Spliterator.DISTINCT | Spliterator.NONNULL),
130 false);
131 }
132
133 private Session getSession() {
134 try {
135 return this.contextProvider.get().getJCRSession(this.jcrDatasourceDefinition.getWorkspace());
136 } catch (RepositoryException e) {
137 throw new RuntimeRepositoryException(e);
138 }
139 }
140 }