KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > info > magnolia > cms > beans > config > ObservedManager


1 /**
2  *
3  * Magnolia and its source-code is licensed under the LGPL.
4  * You may copy, adapt, and redistribute this file for commercial or non-commercial use.
5  * When copying, adapting, or redistributing this document in keeping with the guidelines above,
6  * you are required to provide proper attribution to obinary.
7  * If you reproduce or distribute the document without making any substantive modifications to its content,
8  * please use the following attribution line:
9  *
10  * Copyright 1993-2006 obinary Ltd. (http://www.obinary.com) All rights reserved.
11  *
12  */

13 package info.magnolia.cms.beans.config;
14
15 import info.magnolia.cms.core.Content;
16 import info.magnolia.cms.core.HierarchyManager;
17 import info.magnolia.cms.util.ObservationUtil;
18 import info.magnolia.context.MgnlContext;
19
20 import java.util.ArrayList JavaDoc;
21 import java.util.Collections JavaDoc;
22 import java.util.HashSet JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Set JavaDoc;
26
27 import javax.jcr.observation.EventIterator;
28 import javax.jcr.observation.EventListener;
29
30 import org.apache.commons.collections.CollectionUtils;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34
35 /**
36  * A lot of manager are observed. Will mean that they reload the registered content after the content was changed. To
37  * centralize this code we use this abstract manager. A subclass will implement onRegister and onClear.
38  * @author philipp
39  */

40 public abstract class ObservedManager {
41
42     /**
43      * Logger
44      */

45     protected Logger log = LoggerFactory.getLogger(getClass());
46
47     /**
48      * Count of reload request
49      */

50     private int reloadRequestCount = 0;
51
52     /**
53      * True if this manager is realoading. used to avoid cycles.
54      */

55     private boolean reloading = false;
56
57     /**
58      * milli second the Reloader Thread sleeps
59      */

60     private static final long SLEEP_MILLIS = 1000;
61
62     /**
63      * UUIDs of the registered main nodes. They will get registered again after a change.
64      */

65     protected Set JavaDoc registeredUUIDs = new HashSet JavaDoc();
66
67     /**
68      * Register a node. The uuid is cached and then onRegister() called.
69      * @param node the node to register
70      */

71     public synchronized void register(Content node) {
72         if (node == null) {
73             log.warn("tried to register a not existing node!");
74             return;
75         }
76
77         ObservationUtil.registerChangeListener(ContentRepository.CONFIG, node.getHandle(), new EventListener() {
78
79             public void onEvent(EventIterator events) {
80                 reload();
81             }
82         });
83
84         try {
85             registeredUUIDs.add(node.getUUID());
86             onRegister(node);
87         }
88         catch (Exception JavaDoc e) {
89             log.warn("Was not able to register [" + node.getHandle() + "]", e);
90         }
91     }
92
93     /**
94      * Calls onClear and reregister the nodes by calling onRegister
95      */

96     public synchronized void reload() {
97         // if recalled in the same thread only
98
if (this.reloading == true) {
99             log.debug("this manager waiting for reloading: [{}]", this.getClass().getName());
100             this.reloadRequestCount++;
101             return;
102         }
103         setReloading(true);
104         this.reloadRequestCount = 0;
105         Reloader reloader = new Reloader(this, this.reloadRequestCount);
106         new Thread JavaDoc(reloader).start();
107     }
108
109     /**
110      * Reload a specifig node
111      * @param node
112      */

113     protected final void reload(Content node) {
114         onRegister(node);
115     }
116
117     /**
118      * Clears the registered uuids and calls onClear().
119      */

120     public final void clear() {
121         this.registeredUUIDs.clear();
122         onClear();
123     }
124
125     /**
126      * Registers a node
127      * @param node
128      */

129     protected abstract void onRegister(Content node);
130
131     /**
132      * The implementor should clear everthing. If needed the nodes will get registered.
133      */

134     protected abstract void onClear();
135
136     /**
137      * @return Returns the reloading.
138      */

139     public boolean isReloading() {
140         return reloading;
141     }
142
143     /**
144      * Sets the reloading flag
145      * @param reloading boolean
146      */

147     protected void setReloading(boolean reloading) {
148         this.reloading = reloading;
149     }
150
151     /**
152      * @return Returns the reloadRequestCount
153      */

154     protected int getReloadRequestCount() {
155         return reloadRequestCount;
156     }
157
158     /**
159      * Reloading is done in a separate thread. The thread sleeps for SLEEP_MILLIS milliseconds and checks if the
160      * reloadRequestCount of the observedManager has changed. If true it will remain sleeping. If false the real
161      * reloading starts.
162      * @author Ralf Hirning
163      */

164     private class Reloader implements Runnable JavaDoc {
165
166         /**
167          * reloadRequestCount before sleeping
168          */

169         private int lastReloadRequestCount = 0;
170
171         /**
172          * the ObservedManager
173          */

174         private ObservedManager observedManager;
175
176         /**
177          * Constructor
178          * @param observedManager ObservedManager
179          * @param reloadRequestCount reloadRequestCount of the observedManager
180          */

181         protected Reloader(ObservedManager observedManager, int reloadRequestCount) {
182             this.observedManager = observedManager;
183             this.lastReloadRequestCount = reloadRequestCount;
184         }
185
186         /**
187          * The Reloader thread's run method
188          */

189         public void run() {
190             while (true) {
191                 try {
192                     Thread.sleep(SLEEP_MILLIS);
193                 }
194                 catch (InterruptedException JavaDoc e) {
195                     // ok, go on
196
}
197
198                 // check if the reloadRequestCount of the observedManager has changed
199
int currentReloadRequestCount = this.observedManager.getReloadRequestCount();
200                 if (currentReloadRequestCount > lastReloadRequestCount) {
201                     lastReloadRequestCount = currentReloadRequestCount;
202                 }
203                 else {
204                     // allow creation of a new Reloader
205
this.observedManager.setReloading(false);
206
207                     // Call onClear and reregister the nodes by calling onRegister
208
this.observedManager.onClear();
209
210                     HierarchyManager hm = MgnlContext.getSystemContext().getHierarchyManager(ContentRepository.CONFIG);
211                     
212                     // copy to avoid ConcurrentModificationException since the list get changed during iteration
213
List JavaDoc uuids = new ArrayList JavaDoc(this.observedManager.registeredUUIDs);
214
215                     for (Iterator JavaDoc iter = uuids.iterator(); iter.hasNext();) {
216                         String JavaDoc uuid = (String JavaDoc) iter.next();
217                         try {
218                             Content node = hm.getContentByUUID(uuid);
219                             this.observedManager.reload(node);
220                         }
221                         catch (Exception JavaDoc e) {
222                             this.observedManager.registeredUUIDs.remove(uuid);
223                             log.warn("can't reload the the node [" + uuid + "]");
224                         }
225                     }
226                     return;
227                 }
228             }
229         }
230     }
231 }
232
Popular Tags