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
Revision: 1.13
Committed: Thu Mar 1 21:06:58 2001 UTC (23 years, 2 months ago) by tdb
Branch: MAIN
Changes since 1.12: +8 -11 lines
Log Message:
Restructed the build configuration routine to include files in the correct order

File Contents

# User Rev Content
1 ajm 1.3 //---PACKAGE DECLARATION---
2 ajm 1.5 package uk.ac.ukc.iscream.core;
3 ajm 1.3
4     //---IMPORTS---
5 ajm 1.6 import uk.ac.ukc.iscream.util.*;
6 tdb 1.7 import uk.ac.ukc.iscream.componentmanager.*;
7 ajm 1.3 import java.util.*;
8     import java.io.*;
9    
10     /**
11     * This class is essentially a Configuration factory.
12     * This class implements the Configurator IDL and allows
13     * other classes in the system ot obtain their Configuration
14     *
15     * On construction it requires a reference to the RootPOA
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 ajm 1.6 * ###
22     * A point to note is that this class does NOT yet manage
23     * created configurations which may cause memory problems!
24     * ###
25     *
26 tdb 1.13 * @author $Author: tdb1 $
27     * @version $Id: ConfigurationManagerServant.java,v 1.12 2001/03/01 20:22:21 tdb1 Exp $
28 ajm 1.3 */
29     class ConfigurationManagerServant extends ConfigurationManagerPOA {
30    
31     //---FINAL ATTRIBUTES---
32    
33     /**
34     * The current CVS revision of this class
35     */
36 tdb 1.13 public final String REVISION = "$Revision: 1.12 $";
37 ajm 1.3
38     //---STATIC METHODS---
39    
40     //---CONSTRUCTORS---
41    
42     /**
43     * Creates a new ConfiguratorServant
44     * This class uses the System.properties to set internal values
45     */
46 ajm 1.6 ConfigurationManagerServant() {
47 ajm 1.3 // 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 ajm 1.6 _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 ajm 1.3 }
59    
60     //---PUBLIC METHODS---
61    
62     /**
63     * Returns a Configuration object which contains
64     * the configuration data requested by the calling
65     * object.
66     *
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 ajm 1.6 _logger.write(toString(), Logger.SYSMSG, "got request for " + source);
83 ajm 1.8
84 ajm 1.3
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 ajm 1.6 _logger.write(toString(), Logger.SYSMSG, "system config changed");
89 ajm 1.3 loadSystemConfig();
90     }
91    
92 ajm 1.8 // search config for group membership
93     LinkedList groups = getGroupMembership(source);
94 ajm 1.3
95 ajm 1.8 // add the hosts individual config to the start of the list
96     groups.addFirst(source);
97 ajm 1.3
98 ajm 1.8 Iterator i = groups.iterator();
99     String fileList = "";
100     while (i.hasNext()) {
101     String groupName = (String) i.next();
102 ajm 1.11 _logger.write(toString(), Logger.DEBUG, "looking for config entry for - " + groupName);
103 ajm 1.8 // we look for this entry in the systemConfig
104     String configFile = _systemConfig.getProperty("config." + groupName);
105 ajm 1.11 // 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     // get the file list of includes etc + the system config
110     String groupFileList = null;
111     try {
112     groupFileList = getIncludedFiles(configFile, "") + ";";
113     } catch (Exception e) {
114     // not sure what to do here
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 tdb 1.12 }
124 ajm 1.3 }
125 ajm 1.8 // add the system config as the final check
126 tdb 1.13 fileList = _systemConfigFile + ";" + fileList;
127 ajm 1.8 _logger.write(toString(), Logger.DEBUG, "config tree - " + fileList);
128    
129     // build the configuration
130     Configuration config = buildConfiguration(fileList);
131 ajm 1.3
132     // if this is null at this point, then there will have been an error
133     return config;
134     }
135    
136    
137     /**
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 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 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 ajm 1.6
162 ajm 1.3 /**
163     * Overrides the {@link java.lang.Object#toString() Object.toString()}
164     * method to provide clean logging (every class should have this).
165     *
166 ajm 1.6 * This uses the uk.ac.ukc.iscream.util.FormatName class
167     * to format the toString()
168     *
169 ajm 1.3 * @return the name of this class and its CVS revision
170     */
171     public String toString() {
172 ajm 1.6 return FormatName.getName(
173     _name,
174     getClass().getName(),
175     REVISION);
176 ajm 1.3 }
177    
178     //---PRIVATE METHODS---
179    
180     /**
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 ajm 1.4 * @param readFiles used for recursion purposes only, these are the files it has read so far
188     *
189 ajm 1.3 * @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 ajm 1.4 * @throws CircularIncludeException this is if a circular include is detected
194 ajm 1.3 */
195 ajm 1.4 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 ajm 1.3 Properties properties = new Properties();
207     properties.load(new FileInputStream(new File(_configPath, currentFile)));
208 ajm 1.4
209     // get the include property
210 ajm 1.3 String includes = properties.getProperty("include");
211 ajm 1.4
212     // if we're the last file with no includes, return our name
213 ajm 1.3 if (includes == null) {
214     return currentFile;
215 ajm 1.4
216     // otherwise, recurse over our includes
217 ajm 1.3 } else {
218     StringTokenizer st = new StringTokenizer(includes, ";");
219     String returnList= "";
220     while (st.hasMoreTokens()) {
221 ajm 1.4 returnList = getIncludedFiles(st.nextToken(), readFiles) + ";" + returnList;
222 ajm 1.3 }
223 ajm 1.4
224 ajm 1.3 return returnList + currentFile;
225     }
226     }
227    
228     /**
229 ajm 1.4 * 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 ajm 1.3 * Opens and loads the system configuration into the
249     * local reference _systemConfig
250     */
251     private void loadSystemConfig() {
252 ajm 1.6 _logger.write(this.toString(), Logger.SYSMSG, "reloading " + _systemConfigFile);
253 ajm 1.3 // 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 ajm 1.8 _systemConfigHolder = new Properties();
258     _systemConfigHolder.load(new FileInputStream(systemConfigFile));
259    
260 ajm 1.3 // create the servant
261 ajm 1.8 ConfigurationServant ref = new ConfigurationServant(_systemConfigHolder, _systemConfigFile, systemConfigFile.lastModified());
262 ajm 1.6 org.omg.CORBA.Object objRef = _refman.getRootPOA().servant_to_reference(ref);
263 ajm 1.3
264     // narrow it to a Configuration
265     _systemConfig = ConfigurationHelper.narrow(objRef);
266    
267     } catch (Exception e) {
268 ajm 1.6 _logger.write(toString(), Logger.FATAL, "ERROR: " + e.getMessage());
269 ajm 1.3 }
270     }
271    
272 ajm 1.8 /**
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 ajm 1.10 if (!fileList.equals("")) {
311 ajm 1.8 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 tdb 1.13 long lastModified, newLastModified = 0;
319 ajm 1.8 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    
325     // This loop then iterates over the file list
326     // creates the properties to be passed to the
327     // Configuration constructor
328 tdb 1.13 while (st.hasMoreTokens()) {
329 ajm 1.8 properties = new Properties(defaultProperties);
330     currentFile = new File(_configPath, st.nextToken());
331     newLastModified = currentFile.lastModified();
332     if (newLastModified > lastModified) {
333     lastModified = newLastModified;
334     }
335     properties.load(new FileInputStream(currentFile));
336     defaultProperties = properties;
337 tdb 1.13 }
338 ajm 1.8
339     // this creates the configuration, all nice, ready to be returned
340     ConfigurationServant ref = new ConfigurationServant(properties, fileList, lastModified);
341     org.omg.CORBA.Object objRef = _refman.getRootPOA().servant_to_reference(ref);
342     config = ConfigurationHelper.narrow(objRef);
343 tdb 1.13 _logger.write(toString(), Logger.DEBUG, "returning built configuration");
344 ajm 1.8 } catch (Exception e) {
345     // not sure what to do here
346     // so we just log the error
347 ajm 1.10 _logger.write(toString(), Logger.ERROR, "ERROR - " + e);
348 ajm 1.8 }
349    
350     // if there isn't an entry for the requested config
351     } else {
352     _logger.write(toString(), Logger.DEBUG, "no configured config, returning " + _systemConfigFile);
353     config = _systemConfig;
354     }
355     return config;
356     }
357    
358 ajm 1.3 //---ACCESSOR/MUTATOR METHODS---
359    
360     //---ATTRIBUTES---
361    
362     /**
363 ajm 1.6 * This is the friendly identifier of the
364     * component this class is running in.
365     * eg, a Filter may be called "filter1",
366     * If this class does not have an owning
367     * component, a name from the configuration
368     * can be placed here. This name could also
369     * be changed to null for utility classes.
370     */
371     private String _name = Core.NAME;
372    
373     /**
374     * This holds a reference to the
375     * system logger that is being used.
376 ajm 1.3 */
377 ajm 1.6 private Logger _logger = ReferenceManager.getInstance().getLogger();
378 ajm 1.3
379     /**
380 ajm 1.6 * A reference to the reference manager in use
381 ajm 1.3 */
382 ajm 1.6 private ReferenceManager _refman = ReferenceManager.getInstance();
383 ajm 1.3
384     /**
385     * The root path to all configurations
386     */
387     private String _configPath;
388    
389     /**
390     * The name of the file that contains the system configuration
391     */
392     private String _systemConfigFile;
393    
394     /**
395     * An instance of the system config
396     */
397     private Configuration _systemConfig;
398 ajm 1.8
399     /**
400     * The system config file represented by a
401     * properties object.
402     */
403     private Properties _systemConfigHolder;
404 ajm 1.3
405     //---STATIC ATTRIBUTES---
406    
407     }