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.7
Committed: Thu Jan 18 23:10:44 2001 UTC (23 years, 4 months ago) by tdb
Branch: MAIN
Changes since 1.6: +3 -2 lines
Log Message:
Changes to reflect move of Component, ComponentStartException, and the
ReferenceManager from util to componentmanager.

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 ajm 1.4 * @author $Author: ajm4 $
27 tdb 1.7 * @version $Id: ConfigurationManagerServant.java,v 1.6 2000/12/12 18:26:52 ajm4 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.7 public final String REVISION = "$Revision: 1.6 $";
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.3 Configuration config = null;
84    
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     // we look for this entry in the systemConfig
93     String configFile = _systemConfig.getProperty("config." + source);
94 ajm 1.6 _logger.write(toString(), Logger.DEBUG, "looking for config tree in - " + configFile);
95 ajm 1.3
96     // if there is an entry
97     if (configFile != null) {
98     try {
99 ajm 1.4 // get the file list of includes etc + the system config
100     String fileList = _systemConfigFile + ";" + getIncludedFiles(configFile, "");
101 ajm 1.6 _logger.write(toString(), Logger.DEBUG, "config tree - " + fileList);
102 ajm 1.3
103     // build the properites here from the filelist....
104     StringTokenizer st = new StringTokenizer(fileList, ";");
105    
106     // some holders for variables
107     File currentFile;
108     long lastModified, newLastModified;
109     Properties properties, prevProperties;
110    
111     // the root of all configurations will be the system config
112     // so we need to open the properties of that
113     Properties defaultProperties = new Properties();
114     currentFile = new File(_configPath, _systemConfigFile);
115     lastModified = currentFile.lastModified();
116     defaultProperties.load(new FileInputStream(currentFile));
117    
118     // This loop then iterates over the file list
119     // creates the properties to be passed to the
120     // Configuration constructor
121     do {
122     properties = new Properties(defaultProperties);
123     currentFile = new File(_configPath, st.nextToken());
124     newLastModified = currentFile.lastModified();
125     if (newLastModified > lastModified) {
126     lastModified = newLastModified;
127     }
128     properties.load(new FileInputStream(currentFile));
129     defaultProperties = properties;
130     } while (st.hasMoreTokens());
131    
132     // this creates the configuration, all nice, ready to be returned
133 ajm 1.6 ConfigurationServant ref = new ConfigurationServant(properties, fileList, lastModified);
134     org.omg.CORBA.Object objRef = _refman.getRootPOA().servant_to_reference(ref);
135 ajm 1.3 config = ConfigurationHelper.narrow(objRef);
136    
137     } catch (Exception e) {
138     // not sure what to do here
139 ajm 1.6 // so we just log the error
140     _logger.write(toString(), Logger.ERROR, "ERROR - " + e.getMessage());
141 ajm 1.3 }
142    
143 ajm 1.4 // if there isn't an entry for the requested config
144 ajm 1.3 } else {
145 ajm 1.6 _logger.write(toString(), Logger.DEBUG, "no configured config, returning " + _systemConfigFile);
146 ajm 1.3 config = _systemConfig;
147     }
148    
149     // if this is null at this point, then there will have been an error
150     return config;
151     }
152    
153    
154     /**
155     * When passed a file list and a current value for the lastModified
156     * of the current configuration, this method compares the value
157     * to the actual value of the configuration files to determine
158     * whether or not the configuration has been modified.
159     *
160     * @param fileList a list of files that the caller uses for configuration
161     * @param lastModified the last modified date of the callers configuration
162     *
163     * @return whether or not the configuration has been modified
164     */
165     public boolean isModified(String fileList, long lastModified) {
166     StringTokenizer st = new StringTokenizer(fileList, ";");
167     long newLastModified;
168     File currentFile;
169     while (st.hasMoreTokens()) {
170     currentFile = new File(_configPath, st.nextToken());
171     newLastModified = currentFile.lastModified();
172     if (newLastModified > lastModified) {
173     return true;
174     }
175     }
176     return false;
177     }
178 ajm 1.6
179 ajm 1.3 /**
180     * Overrides the {@link java.lang.Object#toString() Object.toString()}
181     * method to provide clean logging (every class should have this).
182     *
183 ajm 1.6 * This uses the uk.ac.ukc.iscream.util.FormatName class
184     * to format the toString()
185     *
186 ajm 1.3 * @return the name of this class and its CVS revision
187     */
188     public String toString() {
189 ajm 1.6 return FormatName.getName(
190     _name,
191     getClass().getName(),
192     REVISION);
193 ajm 1.3 }
194    
195     //---PRIVATE METHODS---
196    
197     /**
198     * This is a recursive function private to this class.
199     * It constructs a hierarchy of files as a ";" serperated
200     * string which can be used to read in the configuration.
201     * This function calls itself.
202     *
203     * @param currentFile the current file to be processed
204 ajm 1.4 * @param readFiles used for recursion purposes only, these are the files it has read so far
205     *
206 ajm 1.3 * @return the current list that has been constructed
207     *
208     * @throws IOException if there is trouble reading the file
209     * @throws FileNotFoundException is there is trouble finding the file
210 ajm 1.4 * @throws CircularIncludeException this is if a circular include is detected
211 ajm 1.3 */
212 ajm 1.4 private String getIncludedFiles(String currentFile, String readFiles) throws IOException, FileNotFoundException, Exception {
213    
214     // check for circular include here
215     if (hasDuplicate(currentFile, readFiles) || currentFile.equals(_systemConfigFile)) {
216     throw new CircularIncludeException(currentFile + " is included more than once");
217     }
218    
219     // if there wasn't, we're gonna use this file, so make a note of it as read
220     // (note the use of the ";", this is for the hasDuplicate, function)
221     readFiles = readFiles + currentFile + ";";
222    
223 ajm 1.3 Properties properties = new Properties();
224     properties.load(new FileInputStream(new File(_configPath, currentFile)));
225 ajm 1.4
226     // get the include property
227 ajm 1.3 String includes = properties.getProperty("include");
228 ajm 1.4
229     // if we're the last file with no includes, return our name
230 ajm 1.3 if (includes == null) {
231     return currentFile;
232 ajm 1.4
233     // otherwise, recurse over our includes
234 ajm 1.3 } else {
235     StringTokenizer st = new StringTokenizer(includes, ";");
236     String returnList= "";
237     while (st.hasMoreTokens()) {
238 ajm 1.4 returnList = getIncludedFiles(st.nextToken(), readFiles) + ";" + returnList;
239 ajm 1.3 }
240 ajm 1.4
241 ajm 1.3 return returnList + currentFile;
242     }
243     }
244    
245     /**
246 ajm 1.4 * This simple method checks to see if a given
247     * file exists in the given list.
248     *
249     * @param file the file to check the list for
250     * @param fileList the list to check
251     *
252     * @return if the given file appeard in the list
253     */
254     private boolean hasDuplicate(String file, String fileList) {
255     StringTokenizer st = new StringTokenizer(fileList, ";");
256     while (st.hasMoreTokens()) {
257     if (file.equals(st.nextToken())) {
258     return true;
259     }
260     }
261     return false;
262     }
263    
264     /**
265 ajm 1.3 * Opens and loads the system configuration into the
266     * local reference _systemConfig
267     */
268     private void loadSystemConfig() {
269 ajm 1.6 _logger.write(this.toString(), Logger.SYSMSG, "reloading " + _systemConfigFile);
270 ajm 1.3 // get a reference to the system config and store it
271     try {
272     // create the properties for the configuration
273     File systemConfigFile = new File(_configPath, _systemConfigFile);
274     Properties systemConfigHolder = new Properties();
275     systemConfigHolder.load(new FileInputStream(systemConfigFile));
276    
277     // create the servant
278 ajm 1.6 ConfigurationServant ref = new ConfigurationServant(systemConfigHolder, _systemConfigFile, systemConfigFile.lastModified());
279     org.omg.CORBA.Object objRef = _refman.getRootPOA().servant_to_reference(ref);
280 ajm 1.3
281     // narrow it to a Configuration
282     _systemConfig = ConfigurationHelper.narrow(objRef);
283    
284     } catch (Exception e) {
285 ajm 1.6 _logger.write(toString(), Logger.FATAL, "ERROR: " + e.getMessage());
286 ajm 1.3 }
287     }
288    
289     //---ACCESSOR/MUTATOR METHODS---
290    
291     //---ATTRIBUTES---
292    
293     /**
294 ajm 1.6 * This is the friendly identifier of the
295     * component this class is running in.
296     * eg, a Filter may be called "filter1",
297     * If this class does not have an owning
298     * component, a name from the configuration
299     * can be placed here. This name could also
300     * be changed to null for utility classes.
301     */
302     private String _name = Core.NAME;
303    
304     /**
305     * This holds a reference to the
306     * system logger that is being used.
307 ajm 1.3 */
308 ajm 1.6 private Logger _logger = ReferenceManager.getInstance().getLogger();
309 ajm 1.3
310     /**
311 ajm 1.6 * A reference to the reference manager in use
312 ajm 1.3 */
313 ajm 1.6 private ReferenceManager _refman = ReferenceManager.getInstance();
314 ajm 1.3
315     /**
316     * The root path to all configurations
317     */
318     private String _configPath;
319    
320     /**
321     * The name of the file that contains the system configuration
322     */
323     private String _systemConfigFile;
324    
325     /**
326     * An instance of the system config
327     */
328     private Configuration _systemConfig;
329    
330     //---STATIC ATTRIBUTES---
331    
332     }