ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/server/uk/org/iscream/cms/server/core/ConfigurationManagerServant.java
(Generate patch)

Comparing projects/cms/source/server/uk/org/iscream/cms/server/core/ConfigurationManagerServant.java (file contents):
Revision 1.1 by ajm, Mon Nov 20 17:11:44 2000 UTC vs.
Revision 1.12 by tdb, Thu Mar 1 20:22:21 2001 UTC

# Line 1 | Line 1
1   //---PACKAGE DECLARATION---
2 + package uk.ac.ukc.iscream.core;
3  
4   //---IMPORTS---
5 < import uk.ac.ukc.iscream.core.*;
5 > import uk.ac.ukc.iscream.util.*;
6 > import uk.ac.ukc.iscream.componentmanager.*;
7   import java.util.*;
8   import java.io.*;
7 import org.omg.CORBA.*;
8 import org.omg.PortableServer.*;
9  
10   /**
11   * This class is essentially a Configuration factory.
# Line 16 | Line 16 | import org.omg.PortableServer.*;
16   * to allow it to create Configuration objects to be
17   * returned.
18   *
19 + * It also relies on the System.properties to set internal values.
20 + *
21 + * ###
22 + * A point to note is that this class does NOT yet manage
23 + * created configurations which may cause memory problems!
24 + * ###
25 + *
26   * @author  $Author$
27   * @version $Id$
28   */
# Line 34 | Line 41 | class ConfigurationManagerServant extends Configuratio
41  
42      /**
43       * Creates a new ConfiguratorServant
44 <     *
38 <     * @param rootPOARef a reference to the RootPOA
39 <     * @param logRef a reference to the Logger
44 >     * This class uses the System.properties to set internal values
45       */
46 <    ConfigurationManagerServant(POA rootPOARef, Logger logRef) {
47 <        try {
48 <            _configPath = System.getProperty("uk.ac.ukc.iscream.ConfigurationLocation");
49 <            _systemConfigFile = System.getProperty("uk.ac.ukc.iscream.SystemConfigurationFile");
50 <            Properties systemConfigHolder = new Properties();
51 <            File systemConfigFile = new File(_configPath, _systemConfigFile);
52 <            systemConfigHolder.load(new FileInputStream(systemConfigFile));
53 <            ConfigurationServant ref = new ConfigurationServant(systemConfigHolder,systemConfigFile.lastModified(), _logRef);
54 <            org.omg.CORBA.Object objRef = _rootPOARef.servant_to_reference(ref);
55 <            _systemConfig = ConfigurationHelper.narrow(objRef);
56 <            _rootPOARef = rootPOARef;
57 <            _logRef = logRef;
53 <            _logRef.write(this.toString(), Logger.SYSINIT, "started");
54 <            _logRef.write(this.toString(), Logger.SYSMSG, "configuration location - " + _configPath);
55 <            _logRef.write(this.toString(), Logger.SYSMSG, "system configuration file - " + _systemConfigFile);
56 <        } catch (Exception e) {
57 <            // not sure what to do here
58 <            System.err.println("CONFIGURATION MANAGER ERROR: " + e);
59 <            e.printStackTrace(System.out);
60 <        
61 <        }
46 >    ConfigurationManagerServant() {
47 >        // assign some local variables
48 >        _configPath = System.getProperty("uk.ac.ukc.iscream.ConfigurationLocation");
49 >        _systemConfigFile = System.getProperty("uk.ac.ukc.iscream.SystemConfigurationFile");
50 >
51 >        // load the system config
52 >        loadSystemConfig();
53 >
54 >        // log our status
55 >        _logger.write(toString(), Logger.SYSINIT, "started");
56 >        _logger.write(toString(), Logger.SYSMSG, "configuration location - " + _configPath);
57 >        _logger.write(toString(), Logger.SYSMSG, "system configuration file - " + _systemConfigFile);
58      }
59  
60   //---PUBLIC METHODS---
# Line 68 | Line 64 | class ConfigurationManagerServant extends Configuratio
64       * the configuration data requested by the calling
65       * object.
66       *
67 <     * If this method returns a null, that is an indication
68 <     * that no configuration currently exists for the requested
69 <     * source.  The caller should handle appropriately.
67 >     * This method will look in the systemConfig file
68 >     * for an entry for this "source", if there is no
69 >     * entry it returns a refernce to the system
70 >     * config.  If there are any errors in reading the
71 >     * configuration, it returns null, the caller is
72 >     * expected to be able to handle this.
73       *
74 +     * This method also checks to see if the system.conf
75 +     * file has been updated and reloads its reference if
76 +     * needed.
77 +     *
78       * @param source the configuration required
79       * @return the Configuration
80       */
81      public Configuration getConfiguration(String source) {
82 <        _logRef.write(this.toString(), Logger.SYSMSG, "got request for " + source);
82 >        _logger.write(toString(), Logger.SYSMSG, "got request for " + source);
83 >
84          
85 <        Configuration config = null;
86 <        String configFile = _systemConfig.getProperty(source);
87 <        if (configFile != null) {
88 <            try {
89 <                String fileList = getIncludedFiles(configFile, configFile);            
86 <              
87 <            // build the properites here from the filelist....
88 <            StringTokenizer st = new StringTokenizer(fileList, ",");
89 <            } catch (Exception e) {
90 <                // not sure what to do here
91 <                System.err.println("CONFIGURATION MANAGER ERROR: " + e);
92 <                e.printStackTrace(System.out);
93 <            }
94 <            
95 <            // on error...config remains null
96 <        } else {
97 <            config = _systemConfig;
85 >        // check to see if we need to reload the system config
86 >        // because it has changed
87 >        if (isModified(_systemConfig.getFileList(), _systemConfig.getLastModified())) {
88 >            _logger.write(toString(), Logger.SYSMSG, "system config changed");
89 >            loadSystemConfig();
90          }
91 <        return config;
92 <    }
91 >
92 >        // search config for group membership
93 >        LinkedList groups = getGroupMembership(source);
94 >
95 >        // add the hosts individual config to the start of the list
96 >        groups.addFirst(source);
97 >
98 >        Iterator i = groups.iterator();
99 >        String fileList = "";
100 >        while (i.hasNext()) {
101 >            String groupName = (String) i.next();
102 >            _logger.write(toString(), Logger.DEBUG, "looking for config entry for - " + groupName);
103 >            // we look for this entry in the systemConfig
104 >            String configFile = _systemConfig.getProperty("config." + groupName);
105 >            // if there is a config entry then
106 >            if (configFile != null) {
107 >                _logger.write(toString(), Logger.DEBUG, "looking for config tree in - " + configFile);
108      
109 <    private String getIncludedFiles(String currentFile, String fileList) throws IOException, FileNotFoundException {
110 <        Properties properties = new Properties();
104 <        properties.load(new FileInputStream(new File(_configPath, currentFile)));
105 <        String includes = properties.getProperty("include");
106 <        StringTokenizer st = new StringTokenizer(includes, ",");
107 <        String returnList = "";
108 <        while (st.hasMoreTokens()) {
109 <            String nextFile = st.nextToken();
110 <            returnList += getIncludedFiles(nextFile, nextFile + "," + fileList );
111 <        }
112 <        return returnList;
113 <    }
114 <     /*  
115 <        // get the requested config file
116 <        File configurationFile = new File(_configPath, getFileName(source));
117 <        
118 <        try {
119 <            // if we can't read it, we return null
120 <            if (configurationFile.canRead() == false) {
121 <                // do nothing, then we return null.
122 <            
123 <            // otherwise we return the Configuration
124 <            } else {
125 <                // create the servant for it
126 <                ConfigurationServant ref = new ConfigurationServant(configurationFile, _logRef);
127 <        
128 <                // narrow and return the Configuration
109 >                // get the file list of includes etc + the system config
110 >                String groupFileList = null;
111                  try {
112 <                    org.omg.CORBA.Object objRef = _rootPOARef.servant_to_reference(ref);
131 <                    configuration = ConfigurationHelper.narrow(objRef);
132 <                    
112 >                    groupFileList = getIncludedFiles(configFile, "") + ";";
113                  } catch (Exception e) {
114                      // not sure what to do here
115 <                    System.err.println("ERROR: " + e);
116 <                    e.printStackTrace(System.out);
115 >                    // so we just log the error
116 >                    _logger.write(toString(), Logger.ERROR, "ERROR - " + e);
117                  }
118 +                if (groupFileList != null) {
119 +                    fileList += groupFileList;
120 +                }
121 +            } else {
122 +                _logger.write(toString(), Logger.DEBUG, "no config entry for - " + groupName);
123              }
139        
140        // if a SecurityManager is in place and it denies
141        // read access, then we just want to return false
142        } catch (SecurityException e) {
143            // do nothing it will return null
124          }
125 +        // add the system config as the final check
126 +        fileList += _systemConfigFile + ";";
127 +        _logger.write(toString(), Logger.DEBUG, "config tree - " + fileList);
128          
129 <        return configuration;
129 >        // build the configuration
130 >        Configuration config = buildConfiguration(fileList);
131 >        
132 >        // if this is null at this point, then there will have been an error
133 >        return config;
134      }
135 <   */
135 >    
136 >    
137      /**
138 <     * When passed a source and a current value for the lastModified
138 >     * When passed a file list and a current value for the lastModified
139       * of the current configuration, this method compares the value
140 <     * to the actual value of the configuration file to determine
140 >     * to the actual value of the configuration files to determine
141       * whether or not the configuration has been modified.
142       *
143 +     * @param fileList a list of files that the caller uses for configuration
144 +     * @param lastModified the last modified date of the callers configuration
145 +     *
146       * @return whether or not the configuration has been modified
147       */
148 <    public boolean isModified(String source, long currentLastModified) {
149 <        return new File(getFileName(source)).lastModified() > currentLastModified;
148 >    public boolean isModified(String fileList, long lastModified) {
149 >        StringTokenizer st = new StringTokenizer(fileList, ";");
150 >        long newLastModified;
151 >        File currentFile;
152 >        while (st.hasMoreTokens()) {
153 >            currentFile = new File(_configPath, st.nextToken());
154 >            newLastModified = currentFile.lastModified();
155 >            if (newLastModified > lastModified) {
156 >                return true;
157 >            }
158 >        }
159 >        return false;
160      }
161 <    
161 >
162      /**
163       * Overrides the {@link java.lang.Object#toString() Object.toString()}
164       * method to provide clean logging (every class should have this).
165       *
166 +     * This uses the uk.ac.ukc.iscream.util.FormatName class
167 +     * to format the toString()
168 +     *
169       * @return the name of this class and its CVS revision
170       */
171      public String toString() {
172 <        return this.getClass().getName() + "(" + REVISION.substring(11, REVISION.length() - 2) + ")";
172 >        return FormatName.getName(
173 >            _name,
174 >            getClass().getName(),
175 >            REVISION);
176      }
177 +
178   //---PRIVATE METHODS---
179  
180      /**
181 <     * Constructs the name of a configuration file from a
182 <     * configuration source that is passed to it.
181 >     * This is a recursive function private to this class.
182 >     * It constructs a hierarchy of files as a ";" serperated
183 >     * string which can be used to read in the configuration.
184 >     * This function calls itself.
185 >     *
186 >     * @param currentFile the current file to be processed
187 >     * @param readFiles used for recursion purposes only, these are the files it has read so far
188       *
189 <     * @param source the source name
190 <     * @return the filename for the sources configuration
189 >     * @return the current list that has been constructed
190 >     *
191 >     * @throws IOException if there is trouble reading the file
192 >     * @throws FileNotFoundException is there is trouble finding the file
193 >     * @throws CircularIncludeException this is if a circular include is detected
194       */
195 <    private String getFileName(String source) {
196 <        return source + ".properties";
195 >    private String getIncludedFiles(String currentFile, String readFiles) throws IOException, FileNotFoundException, Exception {
196 >        
197 >        // check for circular include here
198 >        if (hasDuplicate(currentFile, readFiles) || currentFile.equals(_systemConfigFile)) {
199 >            throw new CircularIncludeException(currentFile + " is included more than once");
200 >        }
201 >        
202 >        // if there wasn't, we're gonna use this file, so make a note of it as read
203 >        // (note the use of the ";", this is for the hasDuplicate, function)
204 >        readFiles = readFiles + currentFile + ";";
205 >
206 >        Properties properties = new Properties();
207 >        properties.load(new FileInputStream(new File(_configPath, currentFile)));
208 >        
209 >        // get the include property
210 >        String includes = properties.getProperty("include");
211 >
212 >        // if we're the last file with no includes, return our name
213 >        if (includes == null) {
214 >            return currentFile;
215 >        
216 >        // otherwise, recurse over our includes
217 >        } else {
218 >            StringTokenizer st = new StringTokenizer(includes, ";");
219 >            String returnList= "";
220 >            while (st.hasMoreTokens()) {
221 >                returnList = getIncludedFiles(st.nextToken(), readFiles) + ";" + returnList;
222 >            }
223 >            
224 >            return returnList + currentFile;
225 >        }
226      }
227  
228 +    /**
229 +     * This simple method checks to see if a given
230 +     * file exists in the given list.
231 +     *
232 +     * @param file the file to check the list for
233 +     * @param fileList the list to check
234 +     *
235 +     * @return if the given file appeard in the list
236 +     */
237 +    private boolean hasDuplicate(String file, String fileList) {
238 +        StringTokenizer st = new StringTokenizer(fileList, ";");
239 +        while (st.hasMoreTokens()) {
240 +            if (file.equals(st.nextToken())) {
241 +                return true;
242 +            }
243 +        }
244 +        return false;
245 +    }
246 +
247 +    /**
248 +     * Opens and loads the system configuration into the
249 +     * local reference _systemConfig
250 +     */
251 +    private void loadSystemConfig() {
252 +        _logger.write(this.toString(), Logger.SYSMSG, "reloading " + _systemConfigFile);
253 +        // get a reference to the system config and store it
254 +        try {
255 +            // create the properties for the configuration
256 +            File systemConfigFile = new File(_configPath, _systemConfigFile);
257 +            _systemConfigHolder = new Properties();
258 +            _systemConfigHolder.load(new FileInputStream(systemConfigFile));
259 +            
260 +            // create the servant
261 +            ConfigurationServant ref = new ConfigurationServant(_systemConfigHolder, _systemConfigFile, systemConfigFile.lastModified());
262 +            org.omg.CORBA.Object objRef = _refman.getRootPOA().servant_to_reference(ref);
263 +            
264 +            // narrow it to a Configuration
265 +            _systemConfig = ConfigurationHelper.narrow(objRef);
266 +            
267 +        } catch (Exception e) {
268 +            _logger.write(toString(), Logger.FATAL, "ERROR: " + e.getMessage());
269 +        }
270 +    }
271 +
272 +    /**
273 +     * Parses the system configuration file
274 +     * for group membership entries.
275 +     *
276 +     * It looks for all entries of group.<name>
277 +     * which contain the given source name
278 +     *
279 +     * @param source the source to find membership for
280 +     *
281 +     * @return the list of groups that this source is a member of
282 +     */
283 +    private LinkedList getGroupMembership(String source) {
284 +        LinkedList groupMembership = new LinkedList();        
285 +        Iterator i = new TreeSet(_systemConfigHolder.keySet()).iterator();
286 +        while(i.hasNext()) {
287 +            String key = (String) i.next();
288 +            if (key.startsWith("group.")) {
289 +                String group = _systemConfig.getProperty(key);
290 +                if (group.indexOf(source) != -1) {
291 +                    groupMembership.add(key.substring(6));
292 +                }
293 +            }  
294 +        }
295 +        return groupMembership;
296 +    }    
297 +
298 +    /**
299 +     * Build the properties as a Configuration to be
300 +     * returned to the caller
301 +     *
302 +     * @param fileList the list of files to build the configuration from
303 +     *
304 +     * @return the built Configuration
305 +     */
306 +    private Configuration buildConfiguration(String fileList) {
307 +        Configuration config = null;
308 +
309 +        // if there is an entry
310 +        if (!fileList.equals("")) {
311 +            try {
312 +                
313 +                // build the properites here from the filelist....
314 +                StringTokenizer st = new StringTokenizer(fileList, ";");
315 +                
316 +                // some holders for variables
317 +                File currentFile;
318 +                long lastModified, newLastModified;
319 +                Properties properties, prevProperties;
320 +                
321 +                // the root of all configurations will be the system config
322 +                // so we need to open the properties of that
323 +                Properties defaultProperties = new Properties();
324 +                currentFile = new File(_configPath, _systemConfigFile);
325 +                lastModified = currentFile.lastModified();
326 +                defaultProperties.load(new FileInputStream(currentFile));
327 +                
328 +                // This loop then iterates over the file list
329 +                // creates the properties to be passed to the
330 +                // Configuration constructor
331 +                do {
332 +                    properties = new Properties(defaultProperties);
333 +                    currentFile = new File(_configPath, st.nextToken());
334 +                    newLastModified = currentFile.lastModified();
335 +                    if (newLastModified > lastModified) {
336 +                        lastModified = newLastModified;
337 +                    }
338 +                    properties.load(new FileInputStream(currentFile));
339 +                    defaultProperties = properties;
340 +                } while (st.hasMoreTokens());
341 +
342 +                // this creates the configuration, all nice, ready to be returned
343 +                ConfigurationServant ref = new ConfigurationServant(properties, fileList, lastModified);
344 +                org.omg.CORBA.Object objRef = _refman.getRootPOA().servant_to_reference(ref);
345 +                config = ConfigurationHelper.narrow(objRef);
346 +
347 +            } catch (Exception e) {
348 +                // not sure what to do here
349 +                // so we just log the error
350 +                _logger.write(toString(), Logger.ERROR, "ERROR - " + e);
351 +            }
352 +            
353 +        // if there isn't an entry for the requested config
354 +        } else {
355 +            _logger.write(toString(), Logger.DEBUG, "no configured config, returning " + _systemConfigFile);
356 +            config = _systemConfig;
357 +        }
358 +        return config;
359 +    }
360 +
361   //---ACCESSOR/MUTATOR METHODS---
362  
363   //---ATTRIBUTES---
364  
365      /**
366 <     * Local storage of the RootPOA
366 >     * This is the friendly identifier of the
367 >     * component this class is running in.
368 >     * eg, a Filter may be called "filter1",
369 >     * If this class does not have an owning
370 >     * component,  a name from the configuration
371 >     * can be placed here.  This name could also
372 >     * be changed to null for utility classes.
373       */
374 <    private POA _rootPOARef;
374 >    private String _name = Core.NAME;
375 >
376 >    /**
377 >     * This holds a reference to the
378 >     * system logger that is being used.
379 >     */
380 >    private Logger _logger = ReferenceManager.getInstance().getLogger();
381      
382      /**
383 <     * Local storage of the Logger
383 >     * A reference to the reference manager in use
384       */
385 <    private Logger _logRef;
385 >    private ReferenceManager _refman = ReferenceManager.getInstance();
386      
387      /**
388       * The root path to all configurations
389       */
390      private String _configPath;
391      
392 +    /**
393 +     * The name of the file that contains the system configuration
394 +     */
395      private String _systemConfigFile;
396      
397 +    /**
398 +     * An instance of the system config
399 +     */
400      private Configuration _systemConfig;
401 +    
402 +    /**
403 +     * The system config file represented by a
404 +     * properties object.
405 +     */
406 +    private Properties _systemConfigHolder;
407      
408   //---STATIC ATTRIBUTES---
409      

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines