Source Code Cross Referenced for ConfigManager.java in  » Web-Services » xins » org » xins » server » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Services » xins » org.xins.server 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $Id: ConfigManager.java,v 1.60 2007/09/18 08:45:05 agoubard Exp $
003:         *
004:         * Copyright 2003-2007 Orange Nederland Breedband B.V.
005:         * See the COPYRIGHT file for redistribution and use restrictions.
006:         */
007:        package org.xins.server;
008:
009:        import java.io.File;
010:        import java.io.FileInputStream;
011:        import java.io.FileNotFoundException;
012:        import java.io.IOException;
013:        import java.io.InputStream;
014:        import java.net.URL;
015:        import java.util.Enumeration;
016:        import java.util.Iterator;
017:        import java.util.Properties;
018:        import java.util.StringTokenizer;
019:
020:        import javax.servlet.ServletConfig;
021:
022:        import org.apache.log4j.LogManager;
023:        import org.apache.log4j.PropertyConfigurator;
024:        import org.apache.log4j.helpers.NullEnumeration;
025:
026:        import org.xins.common.MandatoryArgumentChecker;
027:        import org.xins.common.Utils;
028:        import org.xins.common.collections.InvalidPropertyValueException;
029:        import org.xins.common.collections.PropertiesPropertyReader;
030:        import org.xins.common.collections.PropertyReader;
031:        import org.xins.common.collections.PropertyReaderUtils;
032:        import org.xins.common.collections.StatsPropertyReader;
033:        import org.xins.common.collections.UniqueProperties;
034:        import org.xins.common.io.FileWatcher;
035:        import org.xins.common.io.HTTPFileWatcher;
036:        import org.xins.common.text.TextUtils;
037:        import org.xins.logdoc.LogCentral;
038:        import org.xins.logdoc.UnsupportedLocaleException;
039:
040:        /**
041:         * Manager for the runtime configuration file. Owns the watcher for the config
042:         * file and is responsible for triggering actions when the file has actually
043:         * changed.
044:         *
045:         * @version $Revision: 1.60 $ $Date: 2007/09/18 08:45:05 $
046:         * @author <a href="mailto:mees.witteman@orange-ftgroup.com">Mees Witteman</a>
047:         * @author <a href="mailto:anthony.goubard@japplis.com">Anthony Goubard</a>
048:         * @author <a href="mailto:ernst@ernstdehaan.com">Ernst de Haan</a>
049:         */
050:        final class ConfigManager {
051:
052:            /**
053:             * The name of the system property that specifies the location of the
054:             * configuration file.
055:             */
056:            static final String CONFIG_FILE_SYSTEM_PROPERTY = "org.xins.server.config";
057:
058:            /**
059:             * The name of the runtime property that specifies the interval
060:             * for the configuration file modification checks, in seconds.
061:             */
062:            static final String CONFIG_RELOAD_INTERVAL_PROPERTY = "org.xins.server.config.reload";
063:
064:            /**
065:             * The name of the runtime property that specifies the list of runtime
066:             * properties file to include. The paths must be relative to the
067:             * current config file.
068:             */
069:            static final String CONFIG_INCLUDE_PROPERTY = "org.xins.server.config.include";
070:
071:            /**
072:             * The default configuration file modification check interval, in seconds.
073:             */
074:            static final int DEFAULT_CONFIG_RELOAD_INTERVAL = 60;
075:
076:            // XXX: Consider adding state checking
077:            /**
078:             * The object to synchronize on when reading and initializing from the
079:             * runtime configuration file.
080:             */
081:            private static final Object RUNTIME_PROPERTIES_LOCK = new Object();
082:
083:            /**
084:             * The <code>Engine</code> that owns this <code>ConfigManager</code>. Never
085:             * <code>null</code>.
086:             */
087:            private final Engine _engine;
088:
089:            /**
090:             * Servlet configuration. Never <code>null</code>.
091:             */
092:            private final ServletConfig _config;
093:
094:            /**
095:             * The listener that is notified when the configuration file changes. Only
096:             * one instance is created ever.
097:             */
098:            private final ConfigurationFileListener _configFileListener;
099:
100:            /**
101:             * The name of the runtime configuration file. Initially <code>null</code>.
102:             */
103:            private String _configFile;
104:
105:            /**
106:             * The name of the all runtime configuration files included in the main config file.
107:             * Can be <code>null</code> or empty.
108:             */
109:            private String[] _configFiles;
110:
111:            /**
112:             * The String representation of the config files. Initialy <code>null</code>.
113:             */
114:            private String _configFilesPath;
115:
116:            /**
117:             * Watcher for the runtime configuration file. Initially <code>null</code>.
118:             */
119:            private FileWatcher _configFileWatcher;
120:
121:            /**
122:             * The set of properties read from the runtime configuration file. Never
123:             * <code>null</code>.
124:             */
125:            private StatsPropertyReader _runtimeProperties;
126:
127:            /**
128:             * Flag indicating that the runtime properties were read correcly.
129:             */
130:            private boolean _propertiesRead;
131:
132:            /**
133:             * Constructs a new <code>ConfigManager</code> object.
134:             *
135:             * @param engine
136:             *    the {@link Engine} that owns this <code>ConfigManager</code>, cannot
137:             *    be <code>null</code>.
138:             *
139:             * @param config
140:             *    the servlet configuration, cannot be <code>null</code>.
141:             *
142:             * @throws IllegalArgumentException
143:             *    if <code>engine == null || config == null</code>.
144:             */
145:            ConfigManager(Engine engine, ServletConfig config)
146:                    throws IllegalArgumentException {
147:
148:                // Check preconditions
149:                MandatoryArgumentChecker.check("engine", engine, "config",
150:                        config);
151:
152:                // Initialize fields
153:                _engine = engine;
154:                _config = config;
155:                _configFileListener = new ConfigurationFileListener();
156:            }
157:
158:            /**
159:             * Initializes the logging subsystem with fallback default settings.
160:             */
161:            static void configureLoggerFallback() {
162:
163:                Properties settings = new Properties();
164:
165:                // Send all log messages to the logger named 'console'
166:                settings.setProperty("log4j.rootLogger", "ALL, console");
167:
168:                // Define an appender for the console
169:                settings.setProperty("log4j.appender.console",
170:                        "org.apache.log4j.ConsoleAppender");
171:
172:                // Use a pattern-layout for the appender
173:                settings.setProperty("log4j.appender.console.layout",
174:                        "org.apache.log4j.PatternLayout");
175:
176:                // Define the pattern for the appender
177:                settings.setProperty(
178:                        "log4j.appender.console.layout.ConversionPattern",
179:                        "%6c{1} %-6p %x %m%n");
180:
181:                // Do not show the debug logs produced by XINS.
182:                settings.setProperty("log4j.logger.org.xins.", "INFO");
183:
184:                // Perform Log4J configuration
185:                PropertyConfigurator.configure(settings);
186:            }
187:
188:            /**
189:             * Determines the name of the runtime configuration file. The system
190:             * properties will be queried first. If they do not provide it, then the
191:             * servlet initialization properties are tried. Once determined, the name
192:             * will be stored internally.
193:             */
194:            void determineConfigFile() {
195:
196:                // Get the value of the appropriate system property
197:                String configFile = null;
198:                try {
199:                    configFile = System
200:                            .getProperty(CONFIG_FILE_SYSTEM_PROPERTY);
201:                } catch (SecurityException exception) {
202:                    Log.log_3230(exception, CONFIG_FILE_SYSTEM_PROPERTY);
203:                }
204:
205:                // If the name of the configuration file is not set in a system property
206:                // (typically passed on the command-line) try to get it from the servlet
207:                // initialization properties (typically set in a web.xml file)
208:                if (configFile == null || configFile.length() < 1) {
209:                    Log.log_3231(CONFIG_FILE_SYSTEM_PROPERTY);
210:                    configFile = _config
211:                            .getInitParameter(CONFIG_FILE_SYSTEM_PROPERTY);
212:                }
213:
214:                // Store the name of the configuration file
215:                _configFile = configFile;
216:            }
217:
218:            /**
219:             * Unifies the file separator character on the _configFile property and then
220:             * reads the runtime properties file, initializes the logging subsystem
221:             * with the read properties and then stores those properties on the engine.
222:             * If the _configFile is empty, then an empty set of properties is set on
223:             * the engine.
224:             */
225:            void readRuntimeProperties() {
226:
227:                UniqueProperties properties = new UniqueProperties();
228:                InputStream in = null;
229:
230:                // If the value is not set only localhost can access the API.
231:                // NOTE: Don't trim the configuration file name, since it may start
232:                //       with a space or other whitespace character.
233:                if (_configFile == null) {
234:
235:                    // Try to find a xins.properties file in the WEB-INF directory
236:                    in = _engine
237:                            .getResourceAsStream("/WEB-INF/xins.properties");
238:                    if (in == null) {
239:
240:                        // Use the default settings
241:                        Log.log_3205(CONFIG_FILE_SYSTEM_PROPERTY);
242:                        _runtimeProperties = null;
243:                        _propertiesRead = true;
244:                        return;
245:                    } else {
246:                        Log.log_3248();
247:                    }
248:                }
249:
250:                boolean propertiesRead = false;
251:                _configFilesPath = _configFile;
252:
253:                synchronized (ConfigManager.RUNTIME_PROPERTIES_LOCK) {
254:
255:                    try {
256:                        if (in != null) {
257:                            properties.load(in);
258:                            in.close();
259:                        } else if (!_configFile.startsWith("http://")
260:                                && !_configFile.startsWith("https://")) {
261:
262:                            // Unify the file separator character
263:                            _configFile = _configFile.replace('/',
264:                                    File.separatorChar);
265:                            _configFile = _configFile.replace('\\',
266:                                    File.separatorChar);
267:
268:                            properties = readLocalRuntimeProperties();
269:                        } else {
270:                            properties = readHTTPRuntimeProperties();
271:                        }
272:                        propertiesRead = true;
273:
274:                        // Security issue
275:                    } catch (SecurityException exception) {
276:                        Log.log_3302(exception, _configFilesPath);
277:
278:                        // No such file
279:                    } catch (FileNotFoundException exception) {
280:                        String detail = TextUtils.trim(exception.getMessage(),
281:                                null);
282:                        Log.log_3301(_configFilesPath, detail);
283:
284:                        // Other I/O error
285:                    } catch (IOException exception) {
286:                        Log.log_3303(exception, _configFilesPath);
287:                    }
288:
289:                    // Initialize the logging subsystem
290:                    Log.log_3300(_configFilesPath);
291:
292:                    // Attempt to configure Log4J
293:                    configureLogger(properties);
294:
295:                    if (!properties.isUnique()) {
296:                        Log.log_3311(_configFilesPath);
297:                        propertiesRead = false;
298:                    }
299:
300:                    if (propertiesRead) {
301:
302:                        // Convert to a PropertyReader
303:                        PropertyReader pr = new PropertiesPropertyReader(
304:                                properties);
305:                        _runtimeProperties = new StatsPropertyReader(pr);
306:                    }
307:                    _propertiesRead = propertiesRead;
308:                }
309:            }
310:
311:            /**
312:             * Read the runtime properties files when files are specified locally.
313:             *
314:             * @return
315:             *    The runtime properties read from the files, never <code>null</code>.
316:             *
317:             * @throws IOException
318:             *    if the file cannot be found or be read.
319:             */
320:            private UniqueProperties readLocalRuntimeProperties()
321:                    throws IOException {
322:                UniqueProperties properties = new UniqueProperties();
323:                InputStream in = null;
324:                try {
325:
326:                    // Open file, load properties, close file
327:                    in = new FileInputStream(_configFile);
328:                    properties.load(in);
329:
330:                    // Read the included files
331:                    if (properties.getProperty(CONFIG_INCLUDE_PROPERTY) != null
332:                            && !properties.getProperty(CONFIG_INCLUDE_PROPERTY)
333:                                    .trim().equals("")) {
334:                        StringTokenizer stInclude = new StringTokenizer(
335:                                properties.getProperty(CONFIG_INCLUDE_PROPERTY),
336:                                ",");
337:                        File baseFile = new File(_configFile).getParentFile();
338:                        _configFiles = new String[stInclude.countTokens() + 1];
339:                        _configFiles[0] = _configFile;
340:                        _configFilesPath += "+ [";
341:                        int i = 0;
342:                        while (stInclude.hasMoreTokens()) {
343:                            String nextInclude = stInclude.nextToken().trim()
344:                                    .replace('/', File.separatorChar).replace(
345:                                            '\\', File.separatorChar);
346:                            File includeFile = new File(baseFile, nextInclude);
347:                            FileInputStream isInclude = new FileInputStream(
348:                                    includeFile);
349:                            properties.load(isInclude);
350:                            isInclude.close();
351:                            _configFiles[i + 1] = nextInclude;
352:                            _configFilesPath += nextInclude + ";";
353:                            i++;
354:                        }
355:                        _configFilesPath += "]";
356:                    } else {
357:                        _configFiles = new String[1];
358:                        _configFiles[0] = _configFile;
359:                    }
360:
361:                    // Always close the input stream
362:                } finally {
363:                    if (in != null) {
364:                        try {
365:                            in.close();
366:                        } catch (Throwable exception) {
367:                            Utils.logIgnoredException(exception);
368:                        }
369:                    }
370:                }
371:                return properties;
372:            }
373:
374:            /**
375:             * Read the runtime properties files when files are specified locally.
376:             *
377:             * @return
378:             *    The runtime properties read from the URLs, never <code>null</code>.
379:             *
380:             * @throws IOException
381:             *    if the URL cannot be created or if the connection to the URL failed.
382:             */
383:            private UniqueProperties readHTTPRuntimeProperties()
384:                    throws IOException {
385:                UniqueProperties properties = new UniqueProperties();
386:                InputStream in = null;
387:                try {
388:
389:                    // Open file, load properties, close file
390:                    URL configURL = new URL(_configFile);
391:                    in = configURL.openStream();
392:                    properties.load(in);
393:
394:                    // Read the included files
395:                    if (properties.getProperty(CONFIG_INCLUDE_PROPERTY) != null
396:                            && !properties.getProperty(CONFIG_INCLUDE_PROPERTY)
397:                                    .trim().equals("")) {
398:                        StringTokenizer stInclude = new StringTokenizer(
399:                                properties.getProperty(CONFIG_INCLUDE_PROPERTY),
400:                                ",");
401:                        _configFiles = new String[stInclude.countTokens() + 1];
402:                        _configFiles[0] = _configFile;
403:                        _configFilesPath += "+ [";
404:                        int i = 0;
405:                        while (stInclude.hasMoreTokens()) {
406:                            String nextInclude = stInclude.nextToken().trim()
407:                                    .replace('/', File.separatorChar).replace(
408:                                            '\\', File.separatorChar);
409:                            URL includeFile = new URL(configURL, nextInclude);
410:                            InputStream isInclude = includeFile.openStream();
411:                            properties.load(isInclude);
412:                            isInclude.close();
413:                            _configFiles[i + 1] = nextInclude;
414:                            _configFilesPath += nextInclude + ";";
415:                            i++;
416:                        }
417:                        _configFilesPath += "]";
418:                    } else {
419:                        _configFiles = new String[1];
420:                        _configFiles[0] = _configFile;
421:                    }
422:
423:                    // Always close the input stream
424:                } finally {
425:                    if (in != null) {
426:                        try {
427:                            in.close();
428:                        } catch (Throwable exception) {
429:                            Utils.logIgnoredException(exception);
430:                        }
431:                    }
432:                }
433:                return properties;
434:            }
435:
436:            /**
437:             * Gets the runtime properties.
438:             *
439:             * @return
440:             *    the runtime properties, never <code>null</code>.
441:             */
442:            PropertyReader getRuntimeProperties() {
443:                if (_runtimeProperties == null) {
444:                    return PropertyReaderUtils.EMPTY_PROPERTY_READER;
445:                } else {
446:                    return _runtimeProperties;
447:                }
448:            }
449:
450:            /**
451:             * Determines the reload interval for the config file, initializes the API
452:             * if the interval has changed and starts the config file watcher.
453:             */
454:            void init() {
455:
456:                // Determine the reload interval
457:                int interval = DEFAULT_CONFIG_RELOAD_INTERVAL;
458:                if (_configFile != null) {
459:                    try {
460:                        interval = determineConfigReloadInterval();
461:
462:                        // If the interval could not be parsed, then use the default
463:                    } catch (InvalidPropertyValueException exception) {
464:                        // ignore
465:                    }
466:                }
467:
468:                // Initialize the API
469:                boolean initialized = _engine.initAPI();
470:
471:                // Start the configuration file watch interval, if the location of the
472:                // file is set and the interval is greater than 0
473:                if (_configFile != null && interval > 0) {
474:                    startConfigFileWatcher(interval);
475:                }
476:
477:                // API initialized successfully, so log each unused property...
478:                if (initialized) {
479:                    logUnusedRuntimeProperties();
480:
481:                    // ...and log that the framework was (re)initialized
482:                    Log.log_3415();
483:                }
484:            }
485:
486:            /**
487:             * Logs the unused runtime properties. Properties for Log4J (those starting
488:             * with <code>"log4j."</code> are ignored.
489:             */
490:            private void logUnusedRuntimeProperties() {
491:                if (_runtimeProperties != null) {
492:                    Iterator unused = _runtimeProperties.getUnused().getNames();
493:                    while (unused.hasNext()) {
494:                        String name = (String) unused.next();
495:                        if (name != null) {
496:                            if (!name.startsWith("log4j.")) {
497:                                Log.log_3434(name);
498:                            }
499:                        }
500:                    }
501:                }
502:            }
503:
504:            /**
505:             * Starts the runtime configuration file watch thread.
506:             *
507:             * @param interval
508:             *    the interval in seconds, must be greater than or equal to 1.
509:             *
510:             * @throws IllegalStateException
511:             *    if no runtime configuration file is specified or if there is already
512:             *    a file watcher.
513:             *
514:             * @throws IllegalArgumentException
515:             *    if <code>interval &lt; 1</code>.
516:             */
517:            void startConfigFileWatcher(int interval)
518:                    throws IllegalStateException, IllegalArgumentException {
519:
520:                // Check state: Config file must be set
521:                if (_configFile == null || _configFile.length() < 1) {
522:                    throw new IllegalStateException(
523:                            "Name of runtime configuration file not set.");
524:
525:                    // Check state: File watcher cannot exist yet
526:                } else if (_configFileWatcher != null) {
527:                    throw new IllegalStateException(
528:                            "Runtime configuration file watcher exists.");
529:
530:                    // Check arguments
531:                } else if (interval < 1) {
532:                    throw new IllegalArgumentException("interval (" + interval
533:                            + ") < 1");
534:                }
535:
536:                // Create and start a file watch thread
537:                if (_configFile.startsWith("http://")
538:                        || _configFile.startsWith("https://")) {
539:                    _configFileWatcher = new HTTPFileWatcher(_configFiles,
540:                            interval, _configFileListener);
541:                } else {
542:                    _configFileWatcher = new FileWatcher(_configFiles,
543:                            interval, _configFileListener);
544:                }
545:                _configFileWatcher.start();
546:            }
547:
548:            /**
549:             * Re-initializes the configuration file listener if there is no file
550:             * watcher; otherwise interrupts the file watcher.
551:             */
552:            void reloadPropertiesIfChanged() {
553:                if (_configFileWatcher == null) {
554:                    _configFileListener.reinit();
555:                } else {
556:                    synchronized (_configFileWatcher) {
557:                        _configFileWatcher.notifyAll();
558:                    }
559:                }
560:            }
561:
562:            /**
563:             * Initializes the logging subsystem.
564:             *
565:             * @param properties
566:             *    the runtime properties containing the settings for the logging
567:             *    subsystem, cannot be <code>null</code>.
568:             *
569:             * @throws IllegalArgumentException
570:             *    if <code>properties == null</code>.
571:             */
572:            void configureLogger(Properties properties)
573:                    throws IllegalArgumentException {
574:
575:                // Check preconditions
576:                MandatoryArgumentChecker.check("properties", properties);
577:
578:                // Reset Log4J configuration
579:                LogManager.getLoggerRepository().resetConfiguration();
580:
581:                // Make possible to have an API specific logger
582:                String apiLogger = properties.getProperty("log4j.rootLogger."
583:                        + _config.getServletName());
584:                if (apiLogger != null) {
585:                    properties.setProperty("log4j.rootLogger", apiLogger);
586:                }
587:
588:                // Reconfigure Log4J
589:                PropertyConfigurator.configure(properties);
590:
591:                // Determine if Log4J is properly initialized
592:                Enumeration appenders = LogManager.getLoggerRepository()
593:                        .getRootLogger().getAllAppenders();
594:
595:                // If the properties did not include Log4J configuration settings, then
596:                // fallback to default settings
597:                if (appenders instanceof  NullEnumeration) {
598:                    Log.log_3304(_configFilesPath);
599:                    configureLoggerFallback();
600:
601:                    // Otherwise log that custom Log4J configuration settings were applied
602:                } else {
603:                    Log.log_3305();
604:                }
605:            }
606:
607:            /**
608:             * Determines the interval for checking the runtime properties file for
609:             * modifications.
610:             *
611:             * @return
612:             *    the interval to use, always &gt;= 1.
613:             *
614:             * @throws InvalidPropertyValueException
615:             *    if the interval cannot be determined because it does not qualify as a
616:             *    positive 32-bit unsigned integer number.
617:             */
618:            int determineConfigReloadInterval()
619:                    throws InvalidPropertyValueException {
620:
621:                // Check state
622:                if (_configFile == null || _configFile.length() < 1) {
623:                    throw new IllegalStateException(
624:                            "Name of runtime configuration file not set.");
625:                }
626:
627:                // Get the runtime property
628:                String prop = CONFIG_RELOAD_INTERVAL_PROPERTY;
629:                String s = _runtimeProperties.get(prop);
630:                int interval;
631:
632:                // If the property is set, parse it
633:                if (s != null && s.length() >= 1) {
634:                    try {
635:                        interval = Integer.parseInt(s);
636:
637:                        // Negative value
638:                        if (interval < 0) {
639:                            Log.log_3409(_configFilesPath, prop, s);
640:                            throw new InvalidPropertyValueException(prop, s,
641:                                    "Negative value.");
642:
643:                            // Non-negative value
644:                        } else {
645:                            Log.log_3410(_configFilesPath, s);
646:                        }
647:
648:                        // Not a valid number string
649:                    } catch (NumberFormatException nfe) {
650:                        Log.log_3409(_configFilesPath, prop, s);
651:                        throw new InvalidPropertyValueException(prop, s,
652:                                "Not a 32-bit integer number.");
653:                    }
654:
655:                    // Property not set, use the default
656:                } else {
657:                    Log.log_3408(_configFilesPath, prop,
658:                            DEFAULT_CONFIG_RELOAD_INTERVAL);
659:                    interval = DEFAULT_CONFIG_RELOAD_INTERVAL;
660:                }
661:
662:                return interval;
663:            }
664:
665:            /**
666:             * Determines the log locale.
667:             *
668:             * @return
669:             *    <code>false</code> if the specified locale is not supported,
670:             *    <code>true</code> otherwise.
671:             */
672:            boolean determineLogLocale() {
673:
674:                String newLocale = null;
675:
676:                // If we have runtime properties, then get the log locale
677:                if (_runtimeProperties != null) {
678:                    newLocale = _runtimeProperties
679:                            .get(LogCentral.LOG_LOCALE_PROPERTY);
680:                }
681:
682:                // If the log locale is set, apply it
683:                if (newLocale != null) {
684:                    String currentLocale = LogCentral.getLocale();
685:                    if (!currentLocale.equals(newLocale)) {
686:                        Log.log_3306(currentLocale, newLocale);
687:                        try {
688:                            LogCentral.setLocale(newLocale);
689:                            Log.log_3307(currentLocale, newLocale);
690:                        } catch (UnsupportedLocaleException exception) {
691:                            Log.log_3308(currentLocale, newLocale);
692:                            return false;
693:                        }
694:                    }
695:
696:                    // No property defines the locale, use the default
697:                } else {
698:                    LogCentral.useDefaultLocale();
699:                }
700:
701:                return true;
702:            }
703:
704:            /**
705:             * Indicates whether the runtime property file was read successfully.
706:             *
707:             * @return
708:             *    <code>true</code> if the runtime properties are loaded correctly,
709:             *    <code>false</code> otherwise.
710:             */
711:            boolean propertiesRead() {
712:                return _propertiesRead;
713:            }
714:
715:            /**
716:             * Stops the config file watcher thread.
717:             */
718:            void destroy() {
719:
720:                // Stop the FileWatcher
721:                if (_configFileWatcher != null) {
722:                    try {
723:                        _configFileWatcher.end();
724:                    } catch (Throwable exception) {
725:                        Utils.logIgnoredException(exception);
726:                    }
727:                    _configFileWatcher = null;
728:                }
729:            }
730:
731:            /**
732:             * Listener that reloads the configuration file if it changes.
733:             *
734:             * @version $Revision: 1.60 $ $Date: 2007/09/18 08:45:05 $
735:             * @author <a href="mailto:ernst@ernstdehaan.com">Ernst de Haan</a>
736:             *
737:             * @since XINS 1.0.0
738:             */
739:            private final class ConfigurationFileListener implements 
740:                    FileWatcher.Listener {
741:
742:                /**
743:                 * Constructs a new <code>ConfigurationFileListener</code> object.
744:                 */
745:                private ConfigurationFileListener() {
746:                    // empty
747:                }
748:
749:                /**
750:                 * Re-initializes the framework. The run-time properties are re-read,
751:                 * the configuration file reload interval is determined, the API is
752:                 * re-initialized and then the new interval is applied to the watch
753:                 * thread for the configuration file.
754:                 */
755:                private void reinit() {
756:
757:                    if (_configFile != null) {
758:                        Log.log_3407(_configFile);
759:                    } else {
760:                        Log.log_3407("/WEB-INF/xins.properties");
761:                    }
762:
763:                    boolean reinitialized;
764:
765:                    synchronized (RUNTIME_PROPERTIES_LOCK) {
766:
767:                        // Apply the new runtime settings to the logging subsystem
768:                        readRuntimeProperties();
769:
770:                        // Re-initialize the API
771:                        reinitialized = _engine.initAPI();
772:
773:                        // Update the file watch interval if needed
774:                        updateFileWatcher();
775:                    }
776:
777:                    // API re-initialized successfully, so log each unused property...
778:                    if (reinitialized) {
779:                        logUnusedRuntimeProperties();
780:
781:                        // ...and log that the framework was reinitialized
782:                        Log.log_3415();
783:                    }
784:                }
785:
786:                /**
787:                 * Updates the file watch interval and initializes the file watcher if
788:                 * needed.
789:                 */
790:                private void updateFileWatcher() {
791:
792:                    if (_configFileWatcher == null) {
793:                        return;
794:                    }
795:
796:                    // Determine the interval
797:                    int newInterval;
798:                    try {
799:                        newInterval = determineConfigReloadInterval();
800:                    } catch (InvalidPropertyValueException exception) {
801:                        // Logging is already done in determineConfigReloadInterval()
802:                        return;
803:                    }
804:
805:                    // Update the file watch interval
806:                    int oldInterval = _configFileWatcher.getInterval();
807:
808:                    if (oldInterval != newInterval) {
809:                        if (newInterval == 0 && _configFileWatcher != null) {
810:                            _configFileWatcher.end();
811:                            _configFileWatcher = null;
812:                        } else if (newInterval > 0
813:                                && _configFileWatcher == null) {
814:                            if (_configFile.startsWith("http://")
815:                                    || _configFile.startsWith("https://")) {
816:                                _configFileWatcher = new HTTPFileWatcher(
817:                                        _configFiles, newInterval,
818:                                        _configFileListener);
819:                            } else {
820:                                _configFileWatcher = new FileWatcher(
821:                                        _configFiles, newInterval,
822:                                        _configFileListener);
823:                            }
824:                            _configFileWatcher.start();
825:                        } else {
826:                            _configFileWatcher.setInterval(newInterval);
827:                            Log.log_3403(_configFilesPath, oldInterval,
828:                                    newInterval);
829:                        }
830:                    }
831:                }
832:
833:                /**
834:                 * Callback method called when the configuration file is found while it
835:                 * was previously not found.
836:                 *
837:                 * <p>This will trigger re-initialization.
838:                 */
839:                public void fileFound() {
840:                    reinit();
841:                }
842:
843:                /**
844:                 * Callback method called when the configuration file is (still) not
845:                 * found.
846:                 *
847:                 * <p>The implementation of this method does not perform any actions.
848:                 */
849:                public void fileNotFound() {
850:                    Log.log_3400(_configFilesPath);
851:                }
852:
853:                /**
854:                 * Callback method called when the configuration file is (still) not
855:                 * modified.
856:                 *
857:                 * <p>The implementation of this method does not perform any actions.
858:                 */
859:                public void fileNotModified() {
860:                }
861:
862:                /**
863:                 * Callback method called when the configuration file could not be
864:                 * examined due to a <code>SecurityException</code>.
865:                 *
866:                 * <p>The implementation of this method does not perform any actions.
867:                 *
868:                 * @param exception
869:                 *    the caught security exception, should not be <code>null</code>
870:                 *    (although this is not checked).
871:                 */
872:                public void securityException(SecurityException exception) {
873:                    Log.log_3401(exception, _configFilesPath);
874:                }
875:
876:                /**
877:                 * Callback method called when the configuration file is modified since
878:                 * the last time it was checked.
879:                 *
880:                 * <p>This will trigger re-initialization.
881:                 */
882:                public void fileModified() {
883:                    reinit();
884:                }
885:            }
886:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.