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.observation;
35
36 import info.magnolia.ui.api.ioc.UiContextScoped;
37 import info.magnolia.ui.datasource.jcr.JcrDatasourceDefinition;
38 import info.magnolia.ui.framework.ioc.Destructible;
39 import info.magnolia.ui.observation.DatasourceObservation;
40
41 import java.util.Set;
42 import java.util.function.Consumer;
43 import java.util.stream.Stream;
44
45 import javax.inject.Inject;
46 import javax.jcr.observation.Event;
47
48 import org.apache.commons.lang3.StringUtils;
49
50 import com.google.common.collect.Sets;
51 import com.machinezoo.noexception.Exceptions;
52 import com.vaadin.shared.Registration;
53 import com.vaadin.ui.UI;
54
55
56
57
58 @UiContextScoped
59 public class JcrDataSourceObservation implements DatasourceObservation, Destructible {
60
61 private final JcrDatasourceDefinition datasourceDefinition;
62 private final JcrObservation jcrObservation;
63 private final Set<Registration> registrations = Sets.newConcurrentHashSet();
64 private final UI ui;
65
66 @Inject
67 JcrDataSourceObservation(JcrDatasourceDefinition datasourceDefinition, JcrObservation jcrObservation, UI ui) {
68 this.datasourceDefinition = datasourceDefinition;
69 this.jcrObservation = jcrObservation;
70 this.ui = ui;
71 }
72
73 @Override
74 public Registration register(Runnable action) {
75 Consumer<Stream<Event>> consumer = events -> {
76 if (!ui.isAttached()) {
77 destroy();
78 return;
79 }
80
81 boolean applicableEventPresent = events
82 .map(Exceptions.wrap().function(Event::getPath))
83 .map(path -> StringUtils.substringBeforeLast(path, "/") + "/")
84 .anyMatch(path -> StringUtils.startsWith(path, this.datasourceDefinition.getRootPath()));
85
86 if (applicableEventPresent) {
87 if (ui.isAttached()) {
88 ui.access(() -> {
89 action.run();
90 ui.push();
91 });
92 }
93 }
94 };
95
96 this.jcrObservation.register(consumer, datasourceDefinition.getWorkspace());
97
98 Registration observationRegistration = new Registration() {
99 @Override
100 public void remove() {
101 jcrObservation.unregister(consumer, datasourceDefinition.getWorkspace());
102 registrations.remove(this);
103 }
104 };
105 registrations.add(observationRegistration);
106
107 return observationRegistration;
108 }
109
110 @Override
111 public void destroy() {
112 registrations.forEach(Registration::remove);
113 }
114 }