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.12
Committed: Thu Mar 1 20:22:21 2001 UTC (23 years, 2 months ago) by tdb
Branch: MAIN
Changes since 1.11: +3 -2 lines
Log Message:
Opps, missing } !

File Contents

# Content
1 //---PACKAGE DECLARATION---
2 package uk.ac.ukc.iscream.core;
3
4 //---IMPORTS---
5 import uk.ac.ukc.iscream.util.*;
6 import uk.ac.ukc.iscream.componentmanager.*;
7 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 * ###
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: ajm4 $
27 * @version $Id: ConfigurationManagerServant.java,v 1.11 2001/03/01 19:42:20 ajm4 Exp $
28 */
29 class ConfigurationManagerServant extends ConfigurationManagerPOA {
30
31 //---FINAL ATTRIBUTES---
32
33 /**
34 * The current CVS revision of this class
35 */
36 public final String REVISION = "$Revision: 1.11 $";
37
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 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---
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 _logger.write(toString(), Logger.SYSMSG, "got request for " + source);
83
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 _logger.write(toString(), Logger.SYSMSG, "system config changed");
89 loadSystemConfig();
90 }
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 // 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 }
124 }
125 // add the system config as the final check
126 fileList += _systemConfigFile + ";";
127 _logger.write(toString(), Logger.DEBUG, "config tree - " + fileList);
128
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
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
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 FormatName.getName(
173 _name,
174 getClass().getName(),
175 REVISION);
176 }
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 * @param readFiles used for recursion purposes only, these are the files it has read so far
188 *
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 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 * 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 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 * A reference to the reference manager in use
384 */
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
410 }