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 java.util.ArrayList;
37 import java.util.Collections;
38 import java.util.List;
39 import javax.jcr.Node;
40 import javax.jcr.RepositoryException;
41 import javax.jcr.Session;
42 import javax.jcr.observation.EventIterator;
43 import javax.jcr.observation.EventListener;
44
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 import info.magnolia.context.MgnlContext;
49 import info.magnolia.module.ModuleRegistry;
50 import info.magnolia.repository.RepositoryConstants;
51
52
53
54
55
56
57
58
59
60 public abstract class ModuleConfigurationObservingManager {
61
62 protected final Logger log = LoggerFactory.getLogger(getClass());
63
64 private final Object reloadMonitor = new Object();
65 private final String pathWithinModule;
66 private final ModuleRegistry moduleRegistry;
67 private final List<String> observedPaths = new ArrayList<String>();
68
69 protected ModuleConfigurationObservingManager(String pathWithinModule, ModuleRegistry moduleRegistry) {
70 this.pathWithinModule = pathWithinModule;
71 this.moduleRegistry = moduleRegistry;
72 }
73
74 public void start() {
75
76 for (String moduleName : moduleRegistry.getModuleNames()) {
77 String path = "/modules/" + moduleName + "/" + pathWithinModule;
78 observedPaths.add(path);
79 }
80
81 final EventListener eventListener = ObservationUtil.instanciateDeferredEventListener(new EventListener() {
82
83 @Override
84 public void onEvent(EventIterator events) {
85 synchronized (reloadMonitor) {
86 MgnlContext.doInSystemContext(new MgnlContext.VoidOp(){
87 @Override
88 public void doExec() {
89 reload();
90 }
91 }, true);
92 }
93 }
94 }, 1000, 5000);
95
96 for (String observedPath : observedPaths) {
97 ObservationUtil.registerChangeListener(RepositoryConstants.CONFIG, observedPath, new EventListener(){
98
99 @Override
100 public void onEvent(EventIterator events) {
101 eventListener.onEvent(events);
102 }
103 });
104 }
105
106 synchronized (reloadMonitor) {
107 reload();
108 }
109 }
110
111 protected void reload() {
112 try {
113 List<Node> nodes = getObservedNodes();
114 reload(nodes);
115 } catch (RepositoryException e) {
116 log.error("Reload of observed nodes failed", e);
117 }
118 }
119
120 protected void reload(List<Node> nodes) throws RepositoryException {
121 onClear();
122 for (Node node : nodes) {
123 try {
124 onRegister(node);
125 } catch (Exception e) {
126 log.warn("Failed to reload the node [" + node.getPath() + "]");
127 }
128 }
129 }
130
131 protected void onClear() throws RepositoryException {
132 }
133
134 protected void onRegister(Node node) throws RepositoryException {
135 }
136
137 private List<Node> getObservedNodes() throws RepositoryException {
138
139 Session session = getSession();
140
141 List<Node> nodes = new ArrayList<Node>();
142 for (String observedPath : observedPaths) {
143 try {
144 if (session.nodeExists(observedPath)) {
145 nodes.add(session.getNode(observedPath));
146 }
147 } catch (RepositoryException e) {
148 log.error("Failed to acquire node for observed path [" + observedPath + "]", e);
149 }
150 }
151 return nodes;
152 }
153
154 protected Session getSession() throws RepositoryException {
155 return MgnlContext.getSystemContext().getJCRSession(RepositoryConstants.CONFIG);
156 }
157
158 protected List<String> getObservedPaths() {
159 return Collections.unmodifiableList(observedPaths);
160 }
161
162
163
164
165
166 protected Object getReloadMonitor() {
167 return reloadMonitor;
168 }
169 }