KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > carol > util > configuration > ConfigurationRepository


1 /**
2  * Copyright (C) 2005 - Bull S.A.
3  *
4  * CAROL: Common Architecture for RMI ObjectWeb Layer
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: ConfigurationRepository.java,v 1.2 2005/04/11 12:39:20 benoitf Exp $
23  * --------------------------------------------------------------------------
24  */

25 package org.objectweb.carol.util.configuration;
26
27 import java.io.IOException JavaDoc;
28 import java.io.InputStream JavaDoc;
29 import java.net.URL JavaDoc;
30 import java.net.URLConnection JavaDoc;
31 import java.util.Enumeration JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.util.Map JavaDoc;
35 import java.util.Properties JavaDoc;
36 import java.util.Set JavaDoc;
37
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40
41 import org.objectweb.carol.util.mbean.MBeanUtils;
42
43 /**
44  * This class handle all rmi configuration available at runtime for carol.<br>
45  * Configurations could be added/removed after the startup of carol
46  * @author Florent Benoit
47  */

48 public class ConfigurationRepository {
49
50     /**
51      * Logger
52      */

53     private static Log logger = LogFactory.getLog(ConfigurationRepository.class);
54
55     /**
56      * Default properties (content of carol-default.properties file)
57      */

58     private static Properties JavaDoc defaultProperties = null;
59
60     /**
61      * Configuration of the server (not the protocols)
62      */

63     private static ServerConfiguration serverConfiguration = null;
64
65     /**
66      * List of protocols configured (and that Carol can manage)
67      */

68     private static Map JavaDoc managedProtocols = null;
69
70     /**
71      * List of protocols used at runtime
72      */

73     private static Map JavaDoc managedConfigurations = null;
74
75     /**
76      * Thread Local for protocol context propagation
77      */

78     private static InheritableThreadLocal JavaDoc threadLocal = null;
79
80     /**
81      * Default configuration to fallback when there is a missing config in
82      * thread
83      */

84     private static ProtocolConfiguration defaultConfiguration = null;
85
86     /**
87      * Properties of the carol configuration
88      */

89     private static Properties JavaDoc properties = null;
90
91     /**
92      * Initialization is done
93      */

94     private static boolean initDone = false;
95
96     /**
97      * No public constructor, singleton
98      */

99     private ConfigurationRepository() {
100     }
101
102     /**
103      * Check that the configuration is done
104      */

105     protected static void checkInitialized() {
106         if (!initDone) {
107             try {
108                 if (logger.isDebugEnabled()) {
109                     logger.debug("Do the configuration as the configuration was not yet done!");
110                 }
111                 init();
112             } catch (ConfigurationException ce) {
113                 IllegalStateException JavaDoc ise = new IllegalStateException JavaDoc(
114                         "Configuration of carol was not done and when trying to initialize it, it fails.");
115                 ise.initCause(ce);
116                 throw ise;
117             }
118         }
119     }
120
121     /**
122      * Checks that carol is initialized
123      */

124     protected static void checkConfigured() {
125         // check that init is done.
126
checkInitialized();
127         if (managedConfigurations == null) {
128             throw new IllegalStateException JavaDoc("Cannot find a configuration, carol was not configured");
129         }
130     }
131
132     /**
133      * @return a list of current configurations
134      */

135     public static ProtocolConfiguration[] getConfigurations() {
136         checkConfigured();
137         Set JavaDoc set = managedConfigurations.keySet();
138         ProtocolConfiguration[] configs = new ProtocolConfiguration[set.size()];
139         int c = 0;
140         for (Iterator JavaDoc it = set.iterator(); it.hasNext();) {
141             String JavaDoc key = (String JavaDoc) it.next();
142             configs[c] = (ProtocolConfiguration) managedConfigurations.get(key);
143             c++;
144         }
145         return configs;
146
147     }
148
149     /**
150      * Gets a configuration with the given name
151      * @param configName name of the configuration
152      * @return configuration object associated to the given name
153      */

154     public static ProtocolConfiguration getConfiguration(String JavaDoc configName) {
155         checkConfigured();
156         return (ProtocolConfiguration) managedConfigurations.get(configName);
157     }
158
159     /**
160      * Gets a protocol with the given name
161      * @param protocolName name of the protocol
162      * @return protocol object associated to the given name
163      */

164     public static Protocol getProtocol(String JavaDoc protocolName) {
165         checkConfigured();
166         return (Protocol) managedProtocols.get(protocolName);
167     }
168
169     /**
170      * Build a new configuration for a given protocol
171      * @param configurationName the name of the configuration
172      * @param protocolName name of the protocol
173      * @return a new configuration object for a given protocol
174      * @throws ConfigurationException if no configuration can be built
175      */

176     public static ProtocolConfiguration newConfiguration(String JavaDoc configurationName, String JavaDoc protocolName)
177             throws ConfigurationException {
178         checkConfigured();
179         Protocol p = null;
180
181         // Check that there is no configuration existing with the same name
182
if (managedConfigurations.get(configurationName) != null) {
183             throw new ConfigurationException("There is an existing configuration with the name '" + configurationName
184                     + "'. Use another name.");
185         }
186
187         // Get configured protocol
188
if (managedProtocols != null) {
189             p = (Protocol) managedProtocols.get(protocolName);
190         }
191         if (p == null) {
192             throw new ConfigurationException("Protocol '" + protocolName + "' doesn't exists in carol. Cannot build");
193         }
194
195         return new ProtocolConfigurationImpl(configurationName, p, new Properties JavaDoc());
196     }
197
198     /**
199      * Set the current configuration object
200      * @param config the configuration to set as current configuration
201      * @return previous value of the configuration which was set
202      */

203     public static ProtocolConfiguration setCurrentConfiguration(ProtocolConfiguration config) {
204         checkConfigured();
205         ProtocolConfiguration old = getCurrentConfiguration();
206         threadLocal.set(config);
207         return old;
208     }
209
210     /**
211      * @return current carol configuration
212      */

213     public static ProtocolConfiguration getCurrentConfiguration() {
214         checkConfigured();
215         Object JavaDoc o = threadLocal.get();
216         if (o != null) {
217             return (ProtocolConfiguration) o;
218         } else {
219             return defaultConfiguration;
220         }
221     }
222
223     /**
224      * Initialize Carol configurations with the carol.properties URL
225      * @param carolPropertiesFileURL URL rerencing the configuration file
226      * @throws ConfigurationException if no properties can be loaded
227      */

228     public static void init(URL JavaDoc carolPropertiesFileURL) throws ConfigurationException {
229         init(carolPropertiesFileURL, null, null);
230     }
231
232     /**
233      * Initialize Carol configurations with MBeans
234      * @param idMbeanServer the identifier to retrieve MBeanServer object
235      * @param serverName the name of the server for creating mbeans
236      * @throws ConfigurationException if no properties can be loaded
237      */

238     public static void init(String JavaDoc idMbeanServer, String JavaDoc serverName) throws ConfigurationException {
239         init(Thread.currentThread().getContextClassLoader().getResource(CarolDefaultValues.CAROL_CONFIGURATION_FILE),
240                 idMbeanServer, serverName);
241     }
242
243     /**
244      * } Initialize Carol configurations with the carol.properties URL
245      * @param carolPropertiesFileURL URL rerencing the configuration file
246      * @param idMbeanServer the identifier to retrieve MBeanServer object
247      * @param serverName the name of the server for creating mbeans
248      * @throws ConfigurationException if no properties can be loaded
249      */

250     public static void init(URL JavaDoc carolPropertiesFileURL, String JavaDoc idMbeanServer, String JavaDoc serverName)
251             throws ConfigurationException {
252         if (initDone) {
253             return;
254         }
255         Properties JavaDoc carolDefaultProperties = getDefaultProperties();
256         Properties JavaDoc carolProperties = getPropertiesFromURL(carolPropertiesFileURL);
257
258         /*
259          * Merge two properties file in following order : carol properties
260          * overwrite default values
261          */

262         properties = mergeProperties(carolDefaultProperties, carolProperties);
263
264         // Extract general configuration
265
serverConfiguration = new ServerConfiguration(properties);
266
267         // Reinit protocols
268
managedProtocols = new HashMap JavaDoc();
269         managedConfigurations = new HashMap JavaDoc();
270
271         // Reset thread local
272
threadLocal = new InheritableThreadLocal JavaDoc();
273
274         // Now build protocols objects by extracting them
275
int propertyBeginLength = CarolDefaultValues.CAROL_PREFIX.length();
276         int propertyEndLength = CarolDefaultValues.FACTORY_PREFIX.length();
277         for (Enumeration JavaDoc e = properties.propertyNames(); e.hasMoreElements();) {
278             String JavaDoc key = (String JavaDoc) e.nextElement();
279             // Detect protocol name on all matching carol.XXXX.context.factory
280
// properties
281
if (key.startsWith(CarolDefaultValues.CAROL_PREFIX) && key.endsWith(CarolDefaultValues.FACTORY_PREFIX)) {
282                 // Extract protocol name
283
String JavaDoc protocolName = key.substring(propertyBeginLength + 1, key.length() - propertyEndLength - 1);
284                 // Build protocol
285
if (logger.isDebugEnabled()) {
286                     logger.debug("Build protocol object for protocol name found '" + protocolName + "'.");
287                 }
288                 Protocol protocol = new Protocol(protocolName, properties);
289                 managedProtocols.put(protocolName, protocol);
290
291                 // if protocol is cmi, configure it
292
if (protocolName.equals("cmi")) {
293                     try {
294                         org.objectweb.carol.cmi.Config.setProperties(properties);
295                     } catch (NoClassDefFoundError JavaDoc ncdfe) {
296                         if (logger.isDebugEnabled()) {
297                             logger.debug("Cmi is not available, don't configure it.");
298                         }
299                     } catch (Exception JavaDoc ex) {
300                         TraceCarol.error("Cannot set the cmi configuration.", ex);
301                         throw new ConfigurationException("Cannot set the cmi configuration.", ex);
302                     }
303                 }
304             }
305         }
306
307         /*
308          * ... and finish with building configurations This is done by using
309          * protocols choosen by user
310          */

311
312         // read property in carol properties file
313
String JavaDoc protocols = properties.getProperty(CarolDefaultValues.PROTOCOLS_KEY);
314         String JavaDoc defaultProtocol = properties.getProperty(CarolDefaultValues.DEFAULT_PROTOCOLS_KEY);
315         if (defaultProtocol == null) {
316             throw new ConfigurationException("No default protocol defined with property '"
317                     + CarolDefaultValues.DEFAULT_PROTOCOLS_KEY + "', check your carol configuration.");
318         }
319         if (protocols == null) {
320             logger.info("No protocols were defined for property '" + CarolDefaultValues.PROTOCOLS_KEY
321                     + "', trying with default protocol = '" + defaultProtocol + "'.");
322             protocols = defaultProtocol;
323         }
324
325         // for each protocol, build a configuration object
326
String JavaDoc[] protocolsArray = protocols.split(",");
327
328         for (int p = 0; p < protocolsArray.length; p++) {
329             // protocol name
330
String JavaDoc pName = protocolsArray[p];
331
332             // is it present ?
333
Protocol protocol = (Protocol) managedProtocols.get(pName);
334             if (protocol == null) {
335                 throw new ConfigurationException("Cannot find a protocol with name '" + pName
336                         + "' in the list of available protocols.");
337             }
338             ProtocolConfiguration protoConfig = new ProtocolConfigurationImpl(pName, protocol, properties);
339             managedConfigurations.put(pName, protoConfig);
340         }
341
342         // set the default configuration to the first available protocol
343
if (protocolsArray[0] != null) {
344             defaultConfiguration = (ProtocolConfiguration) managedConfigurations.get(protocolsArray[0]);
345         }
346
347         if (idMbeanServer != null && serverName != null) {
348             initMbeans(idMbeanServer, serverName);
349         }
350
351         initDone = true;
352     }
353
354     /**
355      * Add a configuration
356      * @param protocolConfiguration the configuration to add
357      * @throws ConfigurationException if the configuration exists
358      */

359     public static void addConfiguration(ProtocolConfiguration protocolConfiguration) throws ConfigurationException {
360         String JavaDoc protocolConfigName = protocolConfiguration.getName();
361         if (managedConfigurations.get(protocolConfigName) != null) {
362             throw new ConfigurationException("The configuration named '" + protocolConfigName + "' already exist.");
363         }
364         managedConfigurations.put(protocolConfigName, protocolConfiguration);
365     }
366
367     /**
368      * Gets server configuration (made with carol-default.properties and
369      * carol.properties file)
370      * @return server configuration
371      */

372     public static ServerConfiguration getServerConfiguration() {
373         checkConfigured();
374         return serverConfiguration;
375     }
376
377     /**
378      * Merge content of two properties object (second overwrite first values)
379      * @param defaultValues default values
380      * @param values new values
381      * @return properties object with merge done
382      */

383     protected static Properties JavaDoc mergeProperties(Properties JavaDoc defaultValues, Properties JavaDoc values) {
384         Properties JavaDoc p = new Properties JavaDoc();
385         p.putAll(defaultValues);
386         // overwrite some
387
p.putAll(values);
388         return p;
389     }
390
391     /**
392      * Initialize Carol configurations with an URL of carol properties file
393      * found with Classloader
394      * @throws ConfigurationException if no properties can be loaded
395      */

396     public static void init() throws ConfigurationException {
397         init(Thread.currentThread().getContextClassLoader().getResource(CarolDefaultValues.CAROL_CONFIGURATION_FILE));
398     }
399
400     /**
401      * Initialize carol with default configuration file found in jar of carol
402      * @return properties object corresponding to carol-default.properties file
403      * @throws ConfigurationException if the properties file cannot be get
404      */

405     protected static Properties JavaDoc getDefaultProperties() throws ConfigurationException {
406         if (defaultProperties == null) {
407             // First, found the URL of this file
408
URL JavaDoc defaultConfigurationFile = Thread.currentThread().getContextClassLoader().getResource(
409                     CarolDefaultValues.CAROL_DEFAULT_CONFIGURATION_FILE);
410
411             defaultProperties = getPropertiesFromURL(defaultConfigurationFile);
412         }
413         return defaultProperties;
414
415     }
416
417     /**
418      * Gets a properties object based on given URL
419      * @param url URL from where build properties object
420      * @return properties object with data from the given URL
421      * @throws ConfigurationException if properties cannot be built
422      */

423     protected static Properties JavaDoc getPropertiesFromURL(URL JavaDoc url) throws ConfigurationException {
424         if (url == null) {
425             if (logger.isDebugEnabled()) {
426                 logger.debug("Return empty properties, URL is null");
427             }
428             return new Properties JavaDoc();
429         }
430
431         // Get inputStream + invalid cache
432
InputStream JavaDoc is = null;
433         try {
434             URLConnection JavaDoc urlConnect = null;
435             urlConnect = url.openConnection();
436             // disable cache
437
urlConnect.setDefaultUseCaches(false);
438
439             is = urlConnect.getInputStream();
440         } catch (IOException JavaDoc ioe) {
441             throw new ConfigurationException("Invalid URL '" + url + "' : " + ioe.getMessage(), ioe);
442         }
443
444         // Check inpustream
445
if (is == null) {
446             throw new ConfigurationException("No inputstream for URL '" + url + "'.");
447         }
448
449         // load properties from URL
450
Properties JavaDoc p = new Properties JavaDoc();
451         try {
452             p.load(is);
453         } catch (IOException JavaDoc ioe) {
454             throw new ConfigurationException("Could not load input stream of URL '" + url + "' : " + ioe.getMessage());
455         }
456
457         // close inputstream
458
try {
459             is.close();
460         } catch (IOException JavaDoc ioe) {
461             throw new ConfigurationException("Cannot close inputStream", ioe);
462         }
463
464         return p;
465     }
466
467     /**
468      * @return the default Configuration when no thread local is set.
469      */

470     public static ProtocolConfiguration getDefaultConfiguration() {
471         checkConfigured();
472         return defaultConfiguration;
473     }
474
475     /**
476      * @return the properties used by Carol configuration.
477      */

478     public static Properties JavaDoc getProperties() {
479         checkConfigured();
480         return properties;
481     }
482
483     /**
484      * @return the number of active protocols
485      */

486     public static int getActiveConfigurationsNumber() {
487         checkConfigured();
488         if (managedConfigurations != null) {
489             return managedConfigurations.size();
490         } else {
491             return 0;
492         }
493     }
494
495     /**
496      * Add interceptor at runtime for a given protocol
497      * @param protocolName protocol name
498      * @param interceptorInitializer Interceptor Intializer class name
499      * @throws ConfigurationException if interceptor cannot be added
500      */

501     public static void addInterceptors(String JavaDoc protocolName, String JavaDoc interceptorInitializer)
502             throws ConfigurationException {
503         checkConfigured();
504         Protocol protocol = getProtocol(protocolName);
505         if (protocol == null) {
506             throw new ConfigurationException("Cannot add interceptor on an unknown protocol '" + protocolName + "'.");
507         }
508         protocol.addInterceptor(interceptorInitializer);
509     }
510
511     /**
512      * Init the MBean for each configuration
513      * @param idMbeanServer the identifier to retrieve MBeanServer object
514      * @param serverName the name of the server for creating mbeans
515      * @throws ConfigurationException if MBeans are not created
516      */

517     protected static void initMbeans(String JavaDoc idMbeanServer, String JavaDoc serverName) throws ConfigurationException {
518
519         for (Iterator JavaDoc it = managedConfigurations.keySet().iterator(); it.hasNext();) {
520             String JavaDoc key = (String JavaDoc) it.next();
521             ProtocolConfiguration protocolConfiguration = (ProtocolConfiguration) managedConfigurations.get(key);
522             if (protocolConfiguration instanceof ProtocolConfigurationImplMBean) {
523                 MBeanUtils.registerProtocolConfigurationMBean((ProtocolConfigurationImplMBean) protocolConfiguration,
524                         logger, idMbeanServer, serverName);
525             }
526         }
527
528     }
529
530 }
531
Popular Tags