1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.jetspeed.services.registry;
17
18 import org.apache.turbine.util.Log;
19 import java.util.Enumeration;
20 import java.util.Hashtable;
21 import java.util.Iterator;
22 import java.util.Map;
23 import java.util.Vector;
24 import java.text.SimpleDateFormat;
25
26 /***
27 * Registry watcher for Database Registry service.
28 * Keeps any cached registry entries refreshed with backend database.
29 *
30 * @author <a href="mailto:susinha@cisco.com">Suchisubhra Sinha</a>
31 * @version $Id: DatabaseRegistryWatcher.java,v 1.2 2004/02/23 03:31:50 jford Exp $
32 */
33 public class DatabaseRegistryWatcher extends Thread
34 {
35 /*** Minimum scan rate for evaluating file refresh */
36 public static final int SCAN_RATE = 10;
37
38 /***
39 The files monitored by this watcher
40 */
41 private Hashtable files = new Hashtable();
42
43 /***
44 the refresh rate, in milliseconds, to use for monitoring this file
45 */
46 private long refreshRate = 0;
47
48 /***
49 The object that relies on this RegsitryWatcher
50 */
51 private FileRegistry subscriber = null;
52
53 /***
54 * This object marks that we are done
55 */
56 private boolean done = false;
57
58 /***
59 * Creates a default RegistryWatcher
60 */
61 public DatabaseRegistryWatcher()
62 {
63 setDaemon(true);
64 setPriority(Thread.MIN_PRIORITY);
65 }
66
67 /*** Modifies the subscriber to this Watcher
68 *
69 * @param registry the new registry subscriber
70 */
71 public void setSubscriber(FileRegistry registry)
72 {
73 synchronized (this)
74 {
75 if (subscriber != null)
76 {
77 Enumeration en = files.keys();
78 while (en.hasMoreElements())
79 {
80 try
81 {
82 subscriber.removeFragment(((String) en.nextElement()));
83 }
84 catch (Exception e)
85 {
86 Log.error("RegistryWatcher: Can't remove fragment", e);
87 }
88 }
89 }
90 this.subscriber = registry;
91 if (subscriber != null)
92 {
93 Enumeration en = files.keys();
94 while (en.hasMoreElements())
95 {
96 try
97 {
98 subscriber.loadFragment(((String) en.nextElement()));
99 }
100 catch (Exception e)
101 {
102 Log.error("RegistryWatcher: Can't load fragment", e);
103 }
104 }
105 }
106 }
107 }
108 /*** @return the subscriber to this watcher */
109 public FileRegistry getSubscriber()
110 {
111 return this.subscriber;
112 }
113 /*** Sets the refresh rate for this watcher
114 * @param refresh the refresh rate in seconds
115 */
116 public void setRefreshRate(long refresh)
117 {
118 this.refreshRate = ((refresh > SCAN_RATE) ? refresh : SCAN_RATE) * 1000;
119 }
120 /*** @return the refresh rate, in seconds, of this watcher */
121 public long getRefreshRate()
122 {
123 return refreshRate / 1000;
124 }
125 /*** Change the base file to be monitored by this watcher
126 *
127 * @param f the file to monitor
128 */
129 public void changeBase(Vector f)
130 {
131 synchronized (this)
132 {
133 if (this.subscriber != null)
134 {
135 Enumeration en = files.keys();
136 while (en.hasMoreElements())
137 {
138 try
139 {
140 subscriber.removeFragment(((String) en.nextElement()));
141 }
142 catch (Exception e)
143 {
144 Log.error("RegistryWatcher: Can't remove fragment", e);
145 }
146 }
147 }
148 files.clear();
149 findFiles(f);
150 }
151 }
152 /***
153 * Refresh the monitored file list
154 *
155 * @param f the file or directory to monitor
156 */
157 private void findFiles(Vector s)
158 {
159 Enumeration en = s.elements();
160 while (en.hasMoreElements())
161 {
162 String f = (String) en.nextElement();
163 if (f != null)
164 {
165 this.files.put(f, "now");
166 }
167 }
168 }
169 /***
170 * <p>Main routine for the monitor which periodically checks whether
171 * the filex have been modified.</p>
172 * The algorithm used does not guarantee a constant refresh rate
173 * between invocations.
174 */
175 public void run()
176 {
177 try
178 {
179 while (!done)
180 {
181 boolean needRefresh = false;
182 synchronized (this)
183 {
184 Map fragments = subscriber.getFragmentMap();
185 if (Log.getLogger().isDebugEnabled())
186 {
187 Log.debug("RegistryWatcher: Saving dirty fragments.");
188 }
189 Iterator i = fragments.keySet().iterator();
190 while (i.hasNext())
191 {
192 try
193 {
194 String filename = (String) i.next();
195 RegistryFragment fragment =
196 (RegistryFragment) subscriber
197 .getFragmentMap()
198 .get(
199 filename);
200
201 if (fragment.isDirty())
202 {
203
204 Enumeration en = files.keys();
205 while (en.hasMoreElements())
206 {
207 String f = (String) en.nextElement();
208
209 SimpleDateFormat sdf =
210 new SimpleDateFormat("dd-mm-yyyy hh:mm:ss");
211 java.util.Date now = new java.util.Date();
212 String currentTime = sdf.format(now);
213 if (filename.equals(f))
214 {
215 files.put(f, currentTime);
216 }
217 }
218 }
219 }
220 catch (Exception e)
221 {
222 Log.error(
223 "RegistryWatcher: exception during update",
224 e);
225 }
226 }
227 if (Log.getLogger().isDebugEnabled())
228 {
229 Log.debug(
230 "RegistryWatcher: Checking for updated files.");
231 }
232 Enumeration en = files.keys();
233 while (en.hasMoreElements())
234 {
235 try
236 {
237 String f = (String) en.nextElement();
238 String modified = (String) files.get(f);
239 subscriber.loadFragment(f);
240 RegistryFragment frag =
241 (RegistryFragment) fragments.get(f);
242 if (frag != null)
243 {
244 frag.setChanged(true);
245 }
246 needRefresh = true;
247 }
248 catch (Exception e)
249 {
250 Log.error(
251 "RegistryWatcher: exception during update",
252 e);
253 }
254 }
255 if (needRefresh)
256 {
257 subscriber.refresh();
258 needRefresh = false;
259 }
260
261 i = fragments.keySet().iterator();
262 while (i.hasNext())
263 {
264 RegistryFragment frag =
265 (RegistryFragment) fragments.get((String) i.next());
266 frag.setDirty(false);
267 frag.setChanged(false);
268 }
269 }
270 sleep(refreshRate);
271 }
272 }
273 catch (InterruptedException e)
274 {
275 Log.error("RegistryWatcher: Stopping monitor: ");
276 Log.error(e);
277 return;
278 }
279 }
280 /***
281 * Mark that the watching thread should be stopped
282 */
283 public void setDone()
284 {
285 done = true;
286 Log.info("RegistryWatcher: Watching thread stop requested");
287 }
288 }