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.6
Committed: Tue Dec 12 18:26:52 2000 UTC (23 years, 5 months ago) by ajm
Branch: MAIN
Changes since 1.5: +49 -33 lines
Log Message:
tidied up the code

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 java.util.*;
7 import java.io.*;
8
9 /**
10 * This class is essentially a Configuration factory.
11 * This class implements the Configurator IDL and allows
12 * other classes in the system ot obtain their Configuration
13 *
14 * On construction it requires a reference to the RootPOA
15 * to allow it to create Configuration objects to be
16 * returned.
17 *
18 * It also relies on the System.properties to set internal values.
19 *
20 * ###
21 * A point to note is that this class does NOT yet manage
22 * created configurations which may cause memory problems!
23 * ###
24 *
25 * @author $Author: ajm4 $
26 * @version $Id: ConfigurationManagerServant.java,v 1.5 2000/11/29 21:27:08 ajm4 Exp $
27 */
28 class ConfigurationManagerServant extends ConfigurationManagerPOA {
29
30 //---FINAL ATTRIBUTES---
31
32 /**
33 * The current CVS revision of this class
34 */
35 public final String REVISION = "$Revision: 1.5 $";
36
37 //---STATIC METHODS---
38
39 //---CONSTRUCTORS---
40
41 /**
42 * Creates a new ConfiguratorServant
43 * This class uses the System.properties to set internal values
44 */
45 ConfigurationManagerServant() {
46 // assign some local variables
47 _configPath = System.getProperty("uk.ac.ukc.iscream.ConfigurationLocation");
48 _systemConfigFile = System.getProperty("uk.ac.ukc.iscream.SystemConfigurationFile");
49
50 // load the system config
51 loadSystemConfig();
52
53 // log our status
54 _logger.write(toString(), Logger.SYSINIT, "started");
55 _logger.write(toString(), Logger.SYSMSG, "configuration location - " + _configPath);
56 _logger.write(toString(), Logger.SYSMSG, "system configuration file - " + _systemConfigFile);
57 }
58
59 //---PUBLIC METHODS---
60
61 /**
62 * Returns a Configuration object which contains
63 * the configuration data requested by the calling
64 * object.
65 *
66 * This method will look in the systemConfig file
67 * for an entry for this "source", if there is no
68 * entry it returns a refernce to the system
69 * config. If there are any errors in reading the
70 * configuration, it returns null, the caller is
71 * expected to be able to handle this.
72 *
73 * This method also checks to see if the system.conf
74 * file has been updated and reloads its reference if
75 * needed.
76 *
77 * @param source the configuration required
78 * @return the Configuration
79 */
80 public Configuration getConfiguration(String source) {
81 _logger.write(toString(), Logger.SYSMSG, "got request for " + source);
82 Configuration config = null;
83
84 // check to see if we need to reload the system config
85 // because it has changed
86 if (isModified(_systemConfig.getFileList(), _systemConfig.getLastModified())) {
87 _logger.write(toString(), Logger.SYSMSG, "system config changed");
88 loadSystemConfig();
89 }
90
91 // we look for this entry in the systemConfig
92 String configFile = _systemConfig.getProperty("config." + source);
93 _logger.write(toString(), Logger.DEBUG, "looking for config tree in - " + configFile);
94
95 // if there is an entry
96 if (configFile != null) {
97 try {
98 // get the file list of includes etc + the system config
99 String fileList = _systemConfigFile + ";" + getIncludedFiles(configFile, "");
100 _logger.write(toString(), Logger.DEBUG, "config tree - " + fileList);
101
102 // build the properites here from the filelist....
103 StringTokenizer st = new StringTokenizer(fileList, ";");
104
105 // some holders for variables
106 File currentFile;
107 long lastModified, newLastModified;
108 Properties properties, prevProperties;
109
110 // the root of all configurations will be the system config
111 // so we need to open the properties of that
112 Properties defaultProperties = new Properties();
113 currentFile = new File(_configPath, _systemConfigFile);
114 lastModified = currentFile.lastModified();
115 defaultProperties.load(new FileInputStream(currentFile));
116
117 // This loop then iterates over the file list
118 // creates the properties to be passed to the
119 // Configuration constructor
120 do {
121 properties = new Properties(defaultProperties);
122 currentFile = new File(_configPath, st.nextToken());
123 newLastModified = currentFile.lastModified();
124 if (newLastModified > lastModified) {
125 lastModified = newLastModified;
126 }
127 properties.load(new FileInputStream(currentFile));
128 defaultProperties = properties;
129 } while (st.hasMoreTokens());
130
131 // this creates the configuration, all nice, ready to be returned
132 ConfigurationServant ref = new ConfigurationServant(properties, fileList, lastModified);
133 org.omg.CORBA.Object objRef = _refman.getRootPOA().servant_to_reference(ref);
134 config = ConfigurationHelper.narrow(objRef);
135
136 } catch (Exception e) {
137 // not sure what to do here
138 // so we just log the error
139 _logger.write(toString(), Logger.ERROR, "ERROR - " + e.getMessage());
140 }
141
142 // if there isn't an entry for the requested config
143 } else {
144 _logger.write(toString(), Logger.DEBUG, "no configured config, returning " + _systemConfigFile);
145 config = _systemConfig;
146 }
147
148 // if this is null at this point, then there will have been an error
149 return config;
150 }
151
152
153 /**
154 * When passed a file list and a current value for the lastModified
155 * of the current configuration, this method compares the value
156 * to the actual value of the configuration files to determine
157 * whether or not the configuration has been modified.
158 *
159 * @param fileList a list of files that the caller uses for configuration
160 * @param lastModified the last modified date of the callers configuration
161 *
162 * @return whether or not the configuration has been modified
163 */
164 public boolean isModified(String fileList, long lastModified) {
165 StringTokenizer st = new StringTokenizer(fileList, ";");
166 long newLastModified;
167 File currentFile;
168 while (st.hasMoreTokens()) {
169 currentFile = new File(_configPath, st.nextToken());
170 newLastModified = currentFile.lastModified();
171 if (newLastModified > lastModified) {
172 return true;
173 }
174 }
175 return false;
176 }
177
178 /**
179 * Overrides the {@link java.lang.Object#toString() Object.toString()}
180 * method to provide clean logging (every class should have this).
181 *
182 * This uses the uk.ac.ukc.iscream.util.FormatName class
183 * to format the toString()
184 *
185 * @return the name of this class and its CVS revision
186 */
187 public String toString() {
188 return FormatName.getName(
189 _name,
190 getClass().getName(),
191 REVISION);
192 }
193
194 //---PRIVATE METHODS---
195
196 /**
197 * This is a recursive function private to this class.
198 * It constructs a hierarchy of files as a ";" serperated
199 * string which can be used to read in the configuration.
200 * This function calls itself.
201 *
202 * @param currentFile the current file to be processed
203 * @param readFiles used for recursion purposes only, these are the files it has read so far
204 *
205 * @return the current list that has been constructed
206 *
207 * @throws IOException if there is trouble reading the file
208 * @throws FileNotFoundException is there is trouble finding the file
209 * @throws CircularIncludeException this is if a circular include is detected
210 */
211 private String getIncludedFiles(String currentFile, String readFiles) throws IOException, FileNotFoundException, Exception {
212
213 // check for circular include here
214 if (hasDuplicate(currentFile, readFiles) || currentFile.equals(_systemConfigFile)) {
215 throw new CircularIncludeException(currentFile + " is included more than once");
216 }
217
218 // if there wasn't, we're gonna use this file, so make a note of it as read
219 // (note the use of the ";", this is for the hasDuplicate, function)
220 readFiles = readFiles + currentFile + ";";
221
222 Properties properties = new Properties();
223 properties.load(new FileInputStream(new File(_configPath, currentFile)));
224
225 // get the include property
226 String includes = properties.getProperty("include");
227
228 // if we're the last file with no includes, return our name
229 if (includes == null) {
230 return currentFile;
231
232 // otherwise, recurse over our includes
233 } else {
234 StringTokenizer st = new StringTokenizer(includes, ";");
235 String returnList= "";
236 while (st.hasMoreTokens()) {
237 returnList = getIncludedFiles(st.nextToken(), readFiles) + ";" + returnList;
238 }
239
240 return returnList + currentFile;
241 }
242 }
243
244 /**
245 * This simple method checks to see if a given
246 * file exists in the given list.
247 *
248 * @param file the file to check the list for
249 * @param fileList the list to check
250 *
251 * @return if the given file appeard in the list
252 */
253 private boolean hasDuplicate(String file, String fileList) {
254 StringTokenizer st = new StringTokenizer(fileList, ";");
255 while (st.hasMoreTokens()) {
256 if (file.equals(st.nextToken())) {
257 return true;
258 }
259 }
260 return false;
261 }
262
263 /**
264 * Opens and loads the system configuration into the
265 * local reference _systemConfig
266 */
267 private void loadSystemConfig() {
268 _logger.write(this.toString(), Logger.SYSMSG, "reloading " + _systemConfigFile);
269 // get a reference to the system config and store it
270 try {
271 // create the properties for the configuration
272 File systemConfigFile = new File(_configPath, _systemConfigFile);
273 Properties systemConfigHolder = new Properties();
274 systemConfigHolder.load(new FileInputStream(systemConfigFile));
275
276 // create the servant
277 ConfigurationServant ref = new ConfigurationServant(systemConfigHolder, _systemConfigFile, systemConfigFile.lastModified());
278 org.omg.CORBA.Object objRef = _refman.getRootPOA().servant_to_reference(ref);
279
280 // narrow it to a Configuration
281 _systemConfig = ConfigurationHelper.narrow(objRef);
282
283 } catch (Exception e) {
284 _logger.write(toString(), Logger.FATAL, "ERROR: " + e.getMessage());
285 }
286 }
287
288 //---ACCESSOR/MUTATOR METHODS---
289
290 //---ATTRIBUTES---
291
292 /**
293 * This is the friendly identifier of the
294 * component this class is running in.
295 * eg, a Filter may be called "filter1",
296 * If this class does not have an owning
297 * component, a name from the configuration
298 * can be placed here. This name could also
299 * be changed to null for utility classes.
300 */
301 private String _name = Core.NAME;
302
303 /**
304 * This holds a reference to the
305 * system logger that is being used.
306 */
307 private Logger _logger = ReferenceManager.getInstance().getLogger();
308
309 /**
310 * A reference to the reference manager in use
311 */
312 private ReferenceManager _refman = ReferenceManager.getInstance();
313
314 /**
315 * The root path to all configurations
316 */
317 private String _configPath;
318
319 /**
320 * The name of the file that contains the system configuration
321 */
322 private String _systemConfigFile;
323
324 /**
325 * An instance of the system config
326 */
327 private Configuration _systemConfig;
328
329 //---STATIC ATTRIBUTES---
330
331 }