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 info.magnolia.context.MgnlContext;
37 import info.magnolia.observation.WorkspaceEventListenerRegistration;
38
39 import javax.jcr.RepositoryException;
40 import javax.jcr.observation.Event;
41 import javax.jcr.observation.EventIterator;
42 import javax.jcr.observation.EventListener;
43
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47
48
49
50 public abstract class WorkspaceObservingManager {
51
52 private static final Logger log = LoggerFactory.getLogger(WorkspaceObservingManager.class);
53 private final Object reloadMonitor = new Object();
54
55 private final String workspace;
56 private final boolean includeSubNodes;
57 private final String[] nodeTypes;
58 private final String observedPath;
59 private final int eventTypesMask;
60
61 private long delay = 1000;
62 private long maxDelay = 5000;
63
64 private WorkspaceEventListenerRegistration.Handle handle = null;
65
66 public WorkspaceObservingManager(String workspace, String observedPath, boolean includeSubNodes, String[] nodeTypes, int eventTypesMask) {
67 this.workspace = workspace;
68 this.observedPath = observedPath;
69 this.includeSubNodes = includeSubNodes;
70 this.nodeTypes = nodeTypes;
71 this.eventTypesMask = eventTypesMask;
72 }
73
74 public WorkspaceObservingManager(String workspace, String observedPath, boolean includeSubNodes, String[] nodeTypes) {
75 this(workspace, observedPath, includeSubNodes, nodeTypes, Event.NODE_ADDED | Event.NODE_REMOVED | Event.NODE_MOVED | Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED | Event.PROPERTY_REMOVED);
76 }
77
78 public WorkspaceObservingManager(String workspace, String observedPath, boolean includeSubNodes, String nodeType) {
79 this(workspace, observedPath, includeSubNodes, nodeType == null ? null : new String[]{nodeType});
80 }
81
82 public void start() {
83 onStart();
84
85 registerChangeListener(instantiateEventListener());
86
87 synchronized (reloadMonitor) {
88 try {
89 reload();
90 } catch (RepositoryException e) {
91 log.error("Error reloading", e);
92 }
93 }
94 }
95
96 protected void onStart() {
97
98 if (handle != null) {
99 try {
100 handle.unregister();
101 } catch (RepositoryException e) {
102 log.error("Unable to remove event listener from workspace {}", workspace, e);
103 }
104 }
105 }
106
107 protected void registerChangeListener(final EventListener eventListener) {
108 try {
109 handle = WorkspaceEventListenerRegistration.observe(workspace, observedPath, eventListener)
110 .withSubNodes(isIncludeSubNodes())
111 .withNodeTypes(getNodeTypes())
112 .withEventTypesMask(getEventTypesMask())
113 .withDelay(getDelay(), getMaxDelay())
114 .register();
115 } catch (RepositoryException e) {
116 log.warn("Error occurred during registration of an event listener", e);
117 }
118 }
119
120 protected EventListener instantiateEventListener() {
121 return new EventListener() {
122 @Override
123 public void onEvent(EventIterator events) {
124 synchronized (reloadMonitor) {
125 MgnlContext.doInSystemContext(new MgnlContext.VoidOp() {
126 @Override
127 public void doExec() {
128 try {
129 reload();
130 } catch (RepositoryException e) {
131 log.error("Error reloading", e);
132 }
133 }
134 }, true);
135 }
136 }
137 };
138 }
139
140 protected abstract void reload() throws RepositoryException;
141
142 protected String getWorkspace() {
143 return workspace;
144 }
145
146 protected boolean isIncludeSubNodes() {
147 return includeSubNodes;
148 }
149
150 protected String[] getNodeTypes() {
151 return nodeTypes;
152 }
153
154 protected String getObservedPath() {
155 return observedPath;
156 }
157
158 protected int getEventTypesMask() {
159 return eventTypesMask;
160 }
161
162
163
164
165
166 protected Object getReloadMonitor() {
167 return reloadMonitor;
168 }
169
170 public long getDelay() {
171 return delay;
172 }
173
174
175
176
177
178 public void setDelay(long delay) {
179 this.delay = delay;
180 }
181
182 public long getMaxDelay() {
183 return maxDelay;
184 }
185
186
187
188
189
190 public void setMaxDelay(long maxDelay) {
191 this.maxDelay = maxDelay;
192 }
193
194 }