View Javadoc

1   /*
2    * Copyright (c) 2004 UNINETT FAS
3    *
4    * This program is free software; you can redistribute it and/or modify it
5    * under the terms of the GNU General Public License as published by the Free
6    * Software Foundation; either version 2 of the License, or (at your option)
7    * any later version.
8    *
9    * This program is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11   * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12   * more details.
13   *
14   * You should have received a copy of the GNU General Public License along with
15   * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16   * Place - Suite 330, Boston, MA 02111-1307, USA.
17   *
18   */
19  
20  package no.feide.moria.directory;
21  
22  import java.io.File;
23  import java.io.FileInputStream;
24  import java.io.FileNotFoundException;
25  import java.io.IOException;
26  import java.io.ObjectInputStream;
27  import java.util.TimerTask;
28  import no.feide.moria.directory.index.DirectoryManagerIndex;
29  import no.feide.moria.log.MessageLogger;
30  
31  /***
32   * This is the task responsible for periodically checking for a new index file,
33   * and if necessary, update the existing index. <br>
34   * <br>
35   * Note that this implementation relies on
36   * <code>no.feide.moria.directory.index.SerializableIndex</code> as the index
37   * implementation. To change the index implementation, the method
38   * <code>readIndex()</code> needs to be modified.
39   */
40  public class IndexUpdater
41  extends TimerTask {
42  
43      /*** Used for logging. */
44      private final MessageLogger log = new MessageLogger(IndexUpdater.class);
45  
46      /*** The location of the index file. */
47      private final String filename;
48  
49      /*** The timestamp of the last read index file. Initially set to 0 (zero). */
50      private long timestamp = 0;
51  
52      /*** The instance of Directory Manager that created this task. */
53      private final DirectoryManager owner;
54  
55  
56      /***
57       * Constructor.
58       * @param dm
59       *            The instance of Directory Manager that created this instance.
60       *            Required since <code>IndexUpdater</code> uses this object
61       *            directly to update its index. Cannot be <code>null</code>.
62       * @param indexFilename
63       *            The index filename. Cannot be <code>null</code>.
64       * @throws NullPointerException
65       *             If <code>dm</code> or <code>indexFilename</code> is
66       *             <code>null</code>.
67       */
68      public IndexUpdater(final DirectoryManager dm, final String indexFilename) {
69  
70          super();
71  
72          // Sanity checks.
73          if (dm == null)
74              throw new NullPointerException("Directory Manager cannot be NULL");
75          if (indexFilename == null)
76              throw new NullPointerException("Index file name cannot be NULL");
77  
78          // Set some local variables.
79          owner = dm;
80          filename = indexFilename;
81  
82      }
83  
84  
85      /***
86       * Performs the periodic update of the DirectoryManager's index, by calling
87       * the <code>DirectoryManager.updateIndex(DirectoryManagerIndex)</code>
88       * method.
89       * @see java.lang.Runnable#run()
90       * @see DirectoryManager#updateIndex(DirectoryManagerIndex)
91       */
92      public final void run() {
93  
94          owner.updateIndex(readIndex());
95  
96      }
97  
98  
99      /***
100      * Reads an index file and create a new index object. <br>
101      * <br>
102      * Note that this method is also called by
103      * <code>DirectoryManager.setConfig(Properties)</code> to force through an
104      * initial update of the index.
105      * @return The newly read index, as an object implementing the
106      *         <code>DirectoryManagerIndex</code> interface. Will return
107      *         <code>null</code> if this method has already been used to
108      *         successfully read an index file, and the file has not been
109      *         updated since (based on the file's timestamp on disk, as per the
110      *         <code>File.lastModified()</code> method).
111      * @see java.io.File#lastModified()
112      * @see DirectoryManager#setConfig(java.util.Properties)
113      */
114     protected final DirectoryManagerIndex readIndex() {
115 
116         // Check if the index file exists.
117         File indexFile = new File(filename);
118         if (!indexFile.isFile())
119             log.logInfo("Index file '" + filename + "' does not exist");
120 
121         // Check if we have received a newer index file than the one previously
122         // read.
123         if (timestamp >= indexFile.lastModified())
124             return null; // No update necessary.
125         timestamp = indexFile.lastModified();
126 
127         DirectoryManagerIndex index = null;
128         try {
129 
130             // Read the new index from file.
131             ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename));
132             index = (DirectoryManagerIndex) in.readObject();
133             in.close();
134 
135         } catch (FileNotFoundException e) {
136             // Unlikely we'll ever get here, but we have to catch the exception.
137             log.logInfo("Index file '" + filename + "' does not exist");
138         } catch (IOException e) {
139             log.logInfo("Unable to read index from file '" + filename + "'", e);
140         } catch (ClassNotFoundException e) {
141             log.logInfo("Unable to instantiate index object", e);
142         }
143 
144         timestamp = indexFile.lastModified();
145         log.logInfo("Index has been updated");
146         return index;
147 
148     }
149 
150 }