View Javadoc

1   /*
2    * Copyright 2000-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  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                             // if fragment has some uncommitted changes
201                             if (fragment.isDirty())
202                             {
203                                 //and update the stored timestamp
204                                 Enumeration en = files.keys();
205                                 while (en.hasMoreElements())
206                                 {
207                                     String f = (String) en.nextElement();
208                                     //get  Current time
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                     // make sure to reset the state of all fragments
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 }