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.module.ModuleRegistry;
38 import info.magnolia.observation.WorkspaceEventListenerRegistration;
39 import info.magnolia.repository.RepositoryConstants;
40
41 import java.util.ArrayList;
42 import java.util.LinkedHashMap;
43 import java.util.List;
44 import java.util.Map;
45
46 import javax.jcr.Node;
47 import javax.jcr.RepositoryException;
48 import javax.jcr.Session;
49 import javax.jcr.observation.EventListener;
50
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 import com.google.common.collect.Lists;
55
56
57
58
59
60
61
62 public abstract class ModuleConfigurationObservingManager extends WorkspaceObservingManager {
63
64 private final Logger log = LoggerFactory.getLogger(getClass());
65
66 private final String pathWithinModule;
67 private final ModuleRegistry moduleRegistry;
68 private final Map<String, WorkspaceEventListenerRegistration.Handle> pathToListenerMap = new LinkedHashMap<>();
69
70 protected ModuleConfigurationObservingManager(String pathWithinModule, ModuleRegistry moduleRegistry) {
71 super(RepositoryConstants.CONFIG, null, true, (String[]) null);
72
73 this.pathWithinModule = pathWithinModule;
74 this.moduleRegistry = moduleRegistry;
75 }
76
77 @Override
78 protected void registerChangeListener(final EventListener eventListener) {
79 for (Map.Entry<String, WorkspaceEventListenerRegistration.Handle> entry : pathToListenerMap.entrySet()) {
80 try {
81 WorkspaceEventListenerRegistration.Handle listenerRegistration = WorkspaceEventListenerRegistration.observe(getWorkspace(), entry.getKey(), instantiateEventListener())
82 .withSubNodes(isIncludeSubNodes())
83 .withNodeTypes(getNodeTypes())
84 .withEventTypesMask(getEventTypesMask())
85 .withDelay(getDelay(), getMaxDelay())
86 .register();
87 entry.setValue(listenerRegistration);
88 } catch (RepositoryException e) {
89 log.warn("Error occurred during registration of an event listener", e);
90 }
91 }
92 }
93
94 @Override
95 protected void onStart() {
96
97 for (WorkspaceEventListenerRegistration.Handle listenerRegistrationHandle : pathToListenerMap.values()) {
98 try {
99 listenerRegistrationHandle.unregister();
100 } catch (RepositoryException e) {
101 log.error("Unable to remove event listener from workspace {}", getWorkspace(), e);
102 }
103 }
104 pathToListenerMap.clear();
105 for (String moduleName : moduleRegistry.getModuleNames()) {
106 String path = "/modules/" + moduleName + "/" + pathWithinModule;
107 pathToListenerMap.put(path, null);
108 }
109 }
110
111 @Override
112 protected void reload() {
113 try {
114 List<Node> nodes = getObservedNodes();
115 reload(nodes);
116 } catch (RepositoryException e) {
117 log.error("Reload of observed nodes failed", e);
118 }
119 }
120
121 protected void reload(List<Node> nodes) throws RepositoryException {
122 onClear();
123 for (Node node : nodes) {
124 try {
125 onRegister(node);
126 } catch (Exception e) {
127 log.warn("Failed to reload the node [{}]", node.getPath());
128 }
129 }
130 }
131
132 protected void onClear() throws RepositoryException {
133
134 }
135
136 protected void onRegister(Node node) throws RepositoryException {
137
138 }
139
140 protected List<Node> getObservedNodes() throws RepositoryException {
141
142 Session session = getSession();
143
144 List<Node> nodes = new ArrayList<Node>();
145 for (String observedPath : pathToListenerMap.keySet()) {
146 try {
147 if (session.nodeExists(observedPath)) {
148 nodes.add(session.getNode(observedPath));
149 }
150 } catch (RepositoryException e) {
151 log.error("Failed to acquire node for observed path [{}]", observedPath, e);
152 }
153 }
154 return nodes;
155 }
156
157 protected Session getSession() throws RepositoryException {
158 return MgnlContext.getSystemContext().getJCRSession(RepositoryConstants.CONFIG);
159 }
160
161 protected List<String> getObservedPaths() {
162 return Lists.newArrayList(pathToListenerMap.keySet());
163 }
164
165 }