KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jetspeed > services > registry > RegistryWatcher


1 /*
2  * Copyright 2000-2001,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.jetspeed.services.registry;
18
19 import java.io.File JavaDoc;
20 import java.io.FileFilter JavaDoc;
21 import java.util.Enumeration JavaDoc;
22 import java.util.Hashtable JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.Map JavaDoc;
25
26 // Jetspeed classes
27
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
28 import org.apache.jetspeed.services.logging.JetspeedLogger;
29
30 /**
31  * Monitors a Registry directory and notifies the associated Registry
32  * of file updates.
33  *
34  * @author <a HREF="mailto:raphael@apache.org">Raphaël Luta</a>
35  * @version $Id: RegistryWatcher.java,v 1.10 2004/02/23 03:31:50 jford Exp $
36  */

37 public class RegistryWatcher extends Thread JavaDoc
38 {
39     /**
40      * Static initialization of the logger for this class
41      */

42     private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(RegistryWatcher.class.getName());
43     
44     /** Minimum scan rate for evaluating file refresh */
45     public static final int SCAN_RATE = 10;
46
47     /**
48     The files monitored by this watcher
49     */

50     private Hashtable JavaDoc files = new Hashtable JavaDoc();
51
52     /**
53     the refresh rate, in milliseconds, to use for monitoring this file
54     */

55     private long refreshRate = 0;
56
57     /**
58     The object that relies on this RegsitryWatcher
59     */

60     private FileRegistry subscriber = null;
61
62     /**
63     The filter to use for filtering registry files
64     */

65     private FileFilter JavaDoc filter = null;
66
67     /**
68      * This object marks that we are done
69     */

70     private boolean done = false;
71
72     /**
73      * Creates a default RegistryWatcher
74      */

75     public RegistryWatcher()
76     {
77         setDaemon(true);
78         setPriority(Thread.MIN_PRIORITY);
79     }
80
81     /** Modifies the subscriber to this Watcher
82      *
83      * @param registry the new registry subscriber
84      */

85     public void setSubscriber(FileRegistry registry)
86     {
87         synchronized (this)
88         {
89             if (subscriber!=null)
90             {
91                 Enumeration JavaDoc en = files.keys();
92                 while(en.hasMoreElements())
93                 {
94                     try
95                     {
96                         subscriber.removeFragment(((File JavaDoc)en.nextElement()).getCanonicalPath());
97                     }
98                     catch (Exception JavaDoc e)
99                     {
100                         logger.error("RegistryWatcher: Can't remove fragment", e);
101                     }
102                 }
103             }
104
105             this.subscriber = registry;
106
107             if (subscriber!=null)
108             {
109                 Enumeration JavaDoc en = files.keys();
110                 while(en.hasMoreElements())
111                 {
112                     try
113                     {
114                         subscriber.loadFragment(((File JavaDoc)en.nextElement()).getCanonicalPath());
115                     }
116                     catch (Exception JavaDoc e)
117                     {
118                         logger.error("RegistryWatcher: Can't load fragment", e);
119                     }
120                 }
121             }
122         }
123     }
124
125     /** @return the subscriber to this watcher */
126     public FileRegistry getSubscriber()
127     {
128         return this.subscriber;
129     }
130
131     /** Sets the refresh rate for this watcher
132      * @param refresh the refresh rate in seconds
133      */

134     public void setRefreshRate(long refresh)
135     {
136         this.refreshRate = (( refresh > SCAN_RATE ) ? refresh : SCAN_RATE) * 1000;
137     }
138
139     /** @return the refresh rate, in seconds, of this watcher */
140     public long getRefreshRate()
141     {
142         return refreshRate / 1000;
143     }
144
145     /** Sets the file filter for selecting the registry files
146      * @param filter the file filter to use
147      */

148     public void setFilter(FileFilter JavaDoc filter)
149     {
150         this.filter = filter;
151     }
152
153     /** @return the file filter used by this watcher instance */
154     public FileFilter JavaDoc getFilter()
155     {
156         return filter;
157     }
158
159     /** Change the base file or directory to be monitored by this watcher
160      *
161      * @param f the file or directory to monitor
162      */

163     public void changeBase(File JavaDoc f)
164     {
165         synchronized (this)
166         {
167             if (this.subscriber!=null)
168             {
169                 Enumeration JavaDoc en = files.keys();
170                 while (en.hasMoreElements())
171                 {
172                     try
173                     {
174                         subscriber.removeFragment(((File JavaDoc)en.nextElement()).getCanonicalPath());
175                     }
176                     catch (Exception JavaDoc e)
177                     {
178                         logger.error("RegistryWatcher: Can't remove fragment", e);
179                     }
180                 }
181             }
182             files.clear();
183             findFiles(f);
184         }
185     }
186
187     /**
188      * Refresh the monitored file list
189      *
190      * @param f the file or directory to monitor
191      */

192     private void findFiles(File JavaDoc f)
193     {
194         File JavaDoc[] contents = null;
195
196         if (f.exists() && f.canRead())
197         {
198             this.files.put(f,new Long JavaDoc(f.lastModified()));
199
200             if (f.isDirectory())
201             {
202
203                 if (filter != null)
204                     contents = f.listFiles(filter);
205                 else
206                     contents = f.listFiles();
207
208                 if (contents!=null)
209                 {
210                     for (int i=0; i< contents.length; i++)
211                     {
212                         files.put(contents[i],new Long JavaDoc(contents[i].lastModified()));
213
214                         if (subscriber!=null)
215                         {
216                             try
217                             {
218                                 subscriber.loadFragment(contents[i].getCanonicalPath());
219                             }
220                             catch (Exception JavaDoc e)
221                             {
222                                 logger.error("RegistryWatcher: Can't load fragment", e);
223                             }
224                         }
225                     }
226                 }
227             }
228         }
229     }
230
231     /**
232      * <p>Main routine for the monitor which periodically checks whether
233      * the filex have been modified.</p>
234      * The algorithm used does not guarantee a constant refresh rate
235      * between invocations.
236      */

237     public void run()
238     {
239         try
240         {
241             while(!done)
242             {
243                 boolean needRefresh = false;
244
245                 synchronized (this)
246                 {
247                     Map JavaDoc fragments = subscriber.getFragmentMap();
248
249                     if (logger.isDebugEnabled())
250                     {
251                         logger.debug( "RegistryWatcher: Saving dirty fragments.");
252                     }
253
254                     Iterator JavaDoc i = fragments.keySet().iterator();
255                     while(i.hasNext())
256                     {
257                         try
258                         {
259                             String JavaDoc filename = (String JavaDoc)i.next();
260                             RegistryFragment fragment = (RegistryFragment)subscriber.getFragmentMap().get(filename);
261
262                             // if fragment has some uncommitted changes
263
if (fragment.isDirty())
264                             {
265                                 //save it to disk
266
subscriber.saveFragment(filename);
267
268                                 if (logger.isDebugEnabled())
269                                 {
270                                     logger.debug( "RegistryWatcher: Saved " + filename);
271                                 }
272
273                                 //and update the stored timestamp
274
Enumeration JavaDoc en = files.keys();
275                                 while(en.hasMoreElements())
276                                 {
277                                     File JavaDoc f = (File JavaDoc)en.nextElement();
278                                     if (filename.equals(f.getCanonicalPath()))
279                                     {
280                                         files.put(f,new Long JavaDoc(f.lastModified()));
281                                     }
282                                 }
283                             }
284                         }
285                         catch (Exception JavaDoc e)
286                         {
287                             logger.error("RegistryWatcher: exception during update",e);
288                         }
289                     }
290
291                     if (logger.isDebugEnabled())
292                     {
293                         logger.debug( "RegistryWatcher: Checking for updated files.");
294                     }
295
296                     Enumeration JavaDoc en = files.keys();
297                     while(en.hasMoreElements())
298                     {
299                         try
300                         {
301                             File JavaDoc f = (File JavaDoc)en.nextElement();
302                             long modified = ((Long JavaDoc)files.get(f)).longValue();
303
304                             if (!f.exists())
305                             {
306                                 files.remove(f);
307                             }
308                             else
309                             {
310                                 if (f.lastModified() > modified)
311                                 {
312                                     files.put(f,new Long JavaDoc(f.lastModified()));
313
314                                     if (f.isDirectory())
315                                     {
316                                         File JavaDoc[] contents = null;
317
318                                         if (filter != null)
319                                         {
320                                             contents = f.listFiles(filter);
321                                         }
322                                         else
323                                         {
324                                             contents = f.listFiles();
325                                         }
326
327                                         if (contents!=null)
328                                         {
329                                             for (int idx=0; idx< contents.length; idx++)
330                                             {
331                                                 if (files.get(contents[idx])==null)
332                                                 {
333                                                     files.put(contents[idx],new Long JavaDoc(contents[idx].lastModified()));
334
335                                                     if (subscriber!=null)
336                                                     {
337                                                         subscriber.loadFragment(contents[idx].getCanonicalPath());
338                                                     }
339                                                 }
340                                             }
341                                         }
342                                     }
343                                     else
344                                     {
345                                         subscriber.loadFragment(f.getCanonicalPath());
346                                     }
347
348                                     if (logger.isDebugEnabled())
349                                     {
350                                         logger.debug("RegistryWatcher: Refreshing because "
351                                                     + f.getCanonicalPath()
352                                                     + " was modified.("
353                                                     + f.lastModified()
354                                                     + " "
355                                                     + modified
356                                                     + ")");
357                                     }
358
359                                     RegistryFragment frag = (RegistryFragment)fragments.get(f.getCanonicalPath());
360
361                                     if (frag!=null)
362                                     {
363                                         frag.setChanged(true);
364                                     }
365
366                                     needRefresh = true;
367                                 }
368                             }
369                         }
370                         catch (Exception JavaDoc e)
371                         {
372                             logger.error("RegistryWatcher: exception during update",e);
373                         }
374                     }
375
376                     if (needRefresh)
377                     {
378                         subscriber.refresh();
379                         needRefresh = false;
380                     }
381
382                     // make sure to reset the state of all fragments
383
i = fragments.keySet().iterator();
384                     while(i.hasNext())
385                     {
386                         RegistryFragment frag = (RegistryFragment)fragments.get((String JavaDoc)i.next());
387                         frag.setDirty(false);
388                         frag.setChanged(false);
389                     }
390                 }
391
392                 sleep( refreshRate );
393             }
394         }
395         catch (InterruptedException JavaDoc e)
396         {
397             logger.error("RegistryWatcher: Stopping monitor: ", e);
398             return;
399         }
400     }
401
402     /**
403      * Mark that the watching thread should be stopped
404      */

405     public void setDone()
406     {
407         done = true;
408         logger.info("RegistryWatcher: Watching thread stop requested");
409     }
410
411 }
412
Popular Tags