Source Code Cross Referenced for AbstractFileConfiguration.java in  » Library » Apache-commons-configuration-1.4-src » org » apache » commons » configuration » 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 » Library » Apache commons configuration 1.4 src » org.apache.commons.configuration 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         *
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:
018:        package org.apache.commons.configuration;
019:
020:        import java.io.File;
021:        import java.io.FileOutputStream;
022:        import java.io.IOException;
023:        import java.io.InputStream;
024:        import java.io.InputStreamReader;
025:        import java.io.OutputStream;
026:        import java.io.OutputStreamWriter;
027:        import java.io.Reader;
028:        import java.io.UnsupportedEncodingException;
029:        import java.io.Writer;
030:        import java.net.MalformedURLException;
031:        import java.net.URL;
032:        import java.util.Iterator;
033:
034:        import org.apache.commons.configuration.reloading.InvariantReloadingStrategy;
035:        import org.apache.commons.configuration.reloading.ReloadingStrategy;
036:        import org.apache.commons.lang.StringUtils;
037:        import org.apache.commons.logging.LogFactory;
038:
039:        /**
040:         * <p>Partial implementation of the <code>FileConfiguration</code> interface.
041:         * Developpers of file based configuration may want to extend this class,
042:         * the two methods left to implement are <code>{@link FileConfiguration#load(Reader)}</code>
043:         * and <code>{@link FileConfiguration#save(Writer)}</code>.</p>
044:         * <p>This base class already implements a couple of ways to specify the location
045:         * of the file this configuration is based on. The following possibilities
046:         * exist:
047:         * <ul><li>URLs: With the method <code>setURL()</code> a full URL to the
048:         * configuration source can be specified. This is the most flexible way. Note
049:         * that the <code>save()</code> methods support only <em>file:</em> URLs.</li>
050:         * <li>Files: The <code>setFile()</code> method allows to specify the
051:         * configuration source as a file. This can be either a relative or an
052:         * absolute file. In the former case the file is resolved based on the current
053:         * directory.</li>
054:         * <li>As file paths in string form: With the <code>setPath()</code> method a
055:         * full path to a configuration file can be provided as a string.</li>
056:         * <li>Separated as base path and file name: This is the native form in which
057:         * the location is stored. The base path is a string defining either a local
058:         * directory or a URL. It can be set using the <code>setBasePath()</code>
059:         * method. The file name, non surprisingly, defines the name of the configuration
060:         * file.</li></ul></p>
061:         * <p>Note that the <code>load()</code> methods do not wipe out the configuration's
062:         * content before the new configuration file is loaded. Thus it is very easy to
063:         * construct a union configuration by simply loading multiple configuration
064:         * files, e.g.</p>
065:         * <p><pre>
066:         * config.load(configFile1);
067:         * config.load(configFile2);
068:         * </pre></p>
069:         * <p>After executing this code fragment, the resulting configuration will
070:         * contain both the properties of configFile1 and configFile2. On the other
071:         * hand, if the current configuration file is to be reloaded, <code>clear()</code>
072:         * should be called first. Otherwise the properties are doubled. This behavior
073:         * is analogous to the behavior of the <code>load(InputStream)</code> method
074:         * in <code>java.util.Properties</code>.</p>
075:         *
076:         * @author Emmanuel Bourg
077:         * @version $Revision: 497574 $, $Date: 2007-01-18 22:02:55 +0100 (Do, 18 Jan 2007) $
078:         * @since 1.0-rc2
079:         */
080:        public abstract class AbstractFileConfiguration extends
081:                BaseConfiguration implements  FileConfiguration {
082:            /** Constant for the configuration reload event.*/
083:            public static final int EVENT_RELOAD = 20;
084:
085:            /** Stores the file name.*/
086:            protected String fileName;
087:
088:            /** Stores the base path.*/
089:            protected String basePath;
090:
091:            /** The auto save flag.*/
092:            protected boolean autoSave;
093:
094:            /** Holds a reference to the reloading strategy.*/
095:            protected ReloadingStrategy strategy;
096:
097:            /** A lock object for protecting reload operations.*/
098:            private Object reloadLock = new Object();
099:
100:            /** Stores the encoding of the configuration file.*/
101:            private String encoding;
102:
103:            /** Stores the URL from which the configuration file was loaded.*/
104:            private URL sourceURL;
105:
106:            /** A counter that prohibits reloading.*/
107:            private int noReload;
108:
109:            /**
110:             * Default constructor
111:             *
112:             * @since 1.1
113:             */
114:            public AbstractFileConfiguration() {
115:                initReloadingStrategy();
116:                setLogger(LogFactory.getLog(getClass()));
117:                addErrorLogListener();
118:            }
119:
120:            /**
121:             * Creates and loads the configuration from the specified file. The passed
122:             * in string must be a valid file name, either absolute or relativ.
123:             *
124:             * @param fileName The name of the file to load.
125:             *
126:             * @throws ConfigurationException Error while loading the file
127:             * @since 1.1
128:             */
129:            public AbstractFileConfiguration(String fileName)
130:                    throws ConfigurationException {
131:                this ();
132:
133:                // store the file name
134:                setFileName(fileName);
135:
136:                // load the file
137:                load();
138:            }
139:
140:            /**
141:             * Creates and loads the configuration from the specified file.
142:             *
143:             * @param file The file to load.
144:             * @throws ConfigurationException Error while loading the file
145:             * @since 1.1
146:             */
147:            public AbstractFileConfiguration(File file)
148:                    throws ConfigurationException {
149:                this ();
150:
151:                // set the file and update the url, the base path and the file name
152:                setFile(file);
153:
154:                // load the file
155:                if (file.exists()) {
156:                    load();
157:                }
158:            }
159:
160:            /**
161:             * Creates and loads the configuration from the specified URL.
162:             *
163:             * @param url The location of the file to load.
164:             * @throws ConfigurationException Error while loading the file
165:             * @since 1.1
166:             */
167:            public AbstractFileConfiguration(URL url)
168:                    throws ConfigurationException {
169:                this ();
170:
171:                // set the URL and update the base path and the file name
172:                setURL(url);
173:
174:                // load the file
175:                load();
176:            }
177:
178:            /**
179:             * Load the configuration from the underlying location.
180:             *
181:             * @throws ConfigurationException if loading of the configuration fails
182:             */
183:            public void load() throws ConfigurationException {
184:                if (sourceURL != null) {
185:                    load(sourceURL);
186:                } else {
187:                    load(getFileName());
188:                }
189:            }
190:
191:            /**
192:             * Locate the specified file and load the configuration. This does not
193:             * change the source of the configuration (i.e. the internally maintained file name).
194:             * Use one of the setter methods for this purpose.
195:             *
196:             * @param fileName the name of the file to be loaded
197:             * @throws ConfigurationException if an error occurs
198:             */
199:            public void load(String fileName) throws ConfigurationException {
200:                try {
201:                    URL url = ConfigurationUtils.locate(basePath, fileName);
202:
203:                    if (url == null) {
204:                        throw new ConfigurationException(
205:                                "Cannot locate configuration source "
206:                                        + fileName);
207:                    }
208:                    load(url);
209:                } catch (ConfigurationException e) {
210:                    throw e;
211:                } catch (Exception e) {
212:                    throw new ConfigurationException(e.getMessage(), e);
213:                }
214:            }
215:
216:            /**
217:             * Load the configuration from the specified file. This does not change
218:             * the source of the configuration (i.e. the internally maintained file
219:             * name). Use one of the setter methods for this purpose.
220:             *
221:             * @param file the file to load
222:             * @throws ConfigurationException if an error occurs
223:             */
224:            public void load(File file) throws ConfigurationException {
225:                try {
226:                    load(file.toURL());
227:                } catch (ConfigurationException e) {
228:                    throw e;
229:                } catch (Exception e) {
230:                    throw new ConfigurationException(e.getMessage(), e);
231:                }
232:            }
233:
234:            /**
235:             * Load the configuration from the specified URL. This does not change the
236:             * source of the configuration (i.e. the internally maintained file name).
237:             * Use on of the setter methods for this purpose.
238:             *
239:             * @param url the URL of the file to be loaded
240:             * @throws ConfigurationException if an error occurs
241:             */
242:            public void load(URL url) throws ConfigurationException {
243:                if (sourceURL == null) {
244:                    if (StringUtils.isEmpty(getBasePath())) {
245:                        // ensure that we have a valid base path
246:                        setBasePath(url.toString());
247:                    }
248:                    sourceURL = url;
249:                }
250:
251:                // throw an exception if the target URL is a directory
252:                File file = ConfigurationUtils.fileFromURL(url);
253:                if (file != null && file.isDirectory()) {
254:                    throw new ConfigurationException(
255:                            "Cannot load a configuration from a directory");
256:                }
257:
258:                InputStream in = null;
259:
260:                try {
261:                    in = url.openStream();
262:                    load(in);
263:                } catch (ConfigurationException e) {
264:                    throw e;
265:                } catch (Exception e) {
266:                    throw new ConfigurationException(e.getMessage(), e);
267:                } finally {
268:                    // close the input stream
269:                    try {
270:                        if (in != null) {
271:                            in.close();
272:                        }
273:                    } catch (IOException e) {
274:                        getLogger().warn("Could not close input stream", e);
275:                    }
276:                }
277:            }
278:
279:            /**
280:             * Load the configuration from the specified stream, using the encoding
281:             * returned by {@link #getEncoding()}.
282:             *
283:             * @param in the input stream
284:             *
285:             * @throws ConfigurationException if an error occurs during the load operation
286:             */
287:            public void load(InputStream in) throws ConfigurationException {
288:                load(in, getEncoding());
289:            }
290:
291:            /**
292:             * Load the configuration from the specified stream, using the specified
293:             * encoding. If the encoding is null the default encoding is used.
294:             *
295:             * @param in the input stream
296:             * @param encoding the encoding used. <code>null</code> to use the default encoding
297:             *
298:             * @throws ConfigurationException if an error occurs during the load operation
299:             */
300:            public void load(InputStream in, String encoding)
301:                    throws ConfigurationException {
302:                Reader reader = null;
303:
304:                if (encoding != null) {
305:                    try {
306:                        reader = new InputStreamReader(in, encoding);
307:                    } catch (UnsupportedEncodingException e) {
308:                        throw new ConfigurationException(
309:                                "The requested encoding is not supported, try the default encoding.",
310:                                e);
311:                    }
312:                }
313:
314:                if (reader == null) {
315:                    reader = new InputStreamReader(in);
316:                }
317:
318:                load(reader);
319:            }
320:
321:            /**
322:             * Save the configuration. Before this method can be called a valid file
323:             * name must have been set.
324:             *
325:             * @throws ConfigurationException if an error occurs or no file name has
326:             * been set yet
327:             */
328:            public void save() throws ConfigurationException {
329:                if (getFileName() == null) {
330:                    throw new ConfigurationException(
331:                            "No file name has been set!");
332:                }
333:
334:                if (sourceURL != null) {
335:                    save(sourceURL);
336:                } else {
337:                    save(fileName);
338:                }
339:                strategy.init();
340:            }
341:
342:            /**
343:             * Save the configuration to the specified file. This doesn't change the
344:             * source of the configuration, use setFileName() if you need it.
345:             *
346:             * @param fileName the file name
347:             *
348:             * @throws ConfigurationException if an error occurs during the save operation
349:             */
350:            public void save(String fileName) throws ConfigurationException {
351:                try {
352:                    File file = ConfigurationUtils.getFile(basePath, fileName);
353:                    if (file == null) {
354:                        throw new ConfigurationException(
355:                                "Invalid file name for save: " + fileName);
356:                    }
357:                    save(file);
358:                } catch (ConfigurationException e) {
359:                    throw e;
360:                } catch (Exception e) {
361:                    throw new ConfigurationException(e.getMessage(), e);
362:                }
363:            }
364:
365:            /**
366:             * Save the configuration to the specified URL if it's a file URL.
367:             * This doesn't change the source of the configuration, use setURL()
368:             * if you need it.
369:             *
370:             * @param url the URL
371:             *
372:             * @throws ConfigurationException if an error occurs during the save operation
373:             */
374:            public void save(URL url) throws ConfigurationException {
375:                File file = ConfigurationUtils.fileFromURL(url);
376:                if (file != null) {
377:                    save(file);
378:                } else {
379:                    throw new ConfigurationException("Could not save to URL "
380:                            + url);
381:                }
382:            }
383:
384:            /**
385:             * Save the configuration to the specified file. The file is created
386:             * automatically if it doesn't exist. This doesn't change the source
387:             * of the configuration, use {@link #setFile} if you need it.
388:             *
389:             * @param file the target file
390:             *
391:             * @throws ConfigurationException if an error occurs during the save operation
392:             */
393:            public void save(File file) throws ConfigurationException {
394:                OutputStream out = null;
395:
396:                try {
397:                    // create the file if necessary
398:                    createPath(file);
399:                    out = new FileOutputStream(file);
400:                    save(out);
401:                } catch (IOException e) {
402:                    throw new ConfigurationException(e.getMessage(), e);
403:                } finally {
404:                    // close the output stream
405:                    try {
406:                        if (out != null) {
407:                            out.close();
408:                        }
409:                    } catch (IOException e) {
410:                        getLogger().warn("Could not close output stream", e);
411:                    }
412:                }
413:            }
414:
415:            /**
416:             * Save the configuration to the specified stream, using the encoding
417:             * returned by {@link #getEncoding()}.
418:             *
419:             * @param out the output stream
420:             *
421:             * @throws ConfigurationException if an error occurs during the save operation
422:             */
423:            public void save(OutputStream out) throws ConfigurationException {
424:                save(out, getEncoding());
425:            }
426:
427:            /**
428:             * Save the configuration to the specified stream, using the specified
429:             * encoding. If the encoding is null the default encoding is used.
430:             *
431:             * @param out the output stream
432:             * @param encoding the encoding to use
433:             * @throws ConfigurationException if an error occurs during the save operation
434:             */
435:            public void save(OutputStream out, String encoding)
436:                    throws ConfigurationException {
437:                Writer writer = null;
438:
439:                if (encoding != null) {
440:                    try {
441:                        writer = new OutputStreamWriter(out, encoding);
442:                    } catch (UnsupportedEncodingException e) {
443:                        throw new ConfigurationException(
444:                                "The requested encoding is not supported, try the default encoding.",
445:                                e);
446:                    }
447:                }
448:
449:                if (writer == null) {
450:                    writer = new OutputStreamWriter(out);
451:                }
452:
453:                save(writer);
454:            }
455:
456:            /**
457:             * Return the name of the file.
458:             *
459:             * @return the file name
460:             */
461:            public String getFileName() {
462:                return fileName;
463:            }
464:
465:            /**
466:             * Set the name of the file. The passed in file name can contain a
467:             * relative path.
468:             * It must be used when referring files with relative paths from classpath.
469:             * Use <code>{@link AbstractFileConfiguration#setPath(String)
470:             * setPath()}</code> to set a full qualified file name.
471:             *
472:             * @param fileName the name of the file
473:             */
474:            public void setFileName(String fileName) {
475:                sourceURL = null;
476:                this .fileName = fileName;
477:            }
478:
479:            /**
480:             * Return the base path.
481:             *
482:             * @return the base path
483:             * @see FileConfiguration#getBasePath()
484:             */
485:            public String getBasePath() {
486:                return basePath;
487:            }
488:
489:            /**
490:             * Sets the base path. The base path is typically either a path to a
491:             * directory or a URL. Together with the value passed to the
492:             * <code>setFileName()</code> method it defines the location of the
493:             * configuration file to be loaded. The strategies for locating the file are
494:             * quite tolerant. For instance if the file name is already an absolute path
495:             * or a fully defined URL, the base path will be ignored. The base path can
496:             * also be a URL, in which case the file name is interpreted in this URL's
497:             * context. Because the base path is used by some of the derived classes for
498:             * resolving relative file names it should contain a meaningful value. If
499:             * other methods are used for determining the location of the configuration
500:             * file (e.g. <code>setFile()</code> or <code>setURL()</code>), the
501:             * base path is automatically set.
502:             *
503:             * @param basePath the base path.
504:             */
505:            public void setBasePath(String basePath) {
506:                sourceURL = null;
507:                this .basePath = basePath;
508:            }
509:
510:            /**
511:             * Return the file where the configuration is stored. If the base path is a
512:             * URL with a protocol different than &quot;file&quot;, or the configuration
513:             * file is within a compressed archive, the return value
514:             * will not point to a valid file object.
515:             *
516:             * @return the file where the configuration is stored; this can be <b>null</b>
517:             */
518:            public File getFile() {
519:                if (getFileName() == null) {
520:                    return null;
521:                } else {
522:                    if (sourceURL != null) {
523:                        return ConfigurationUtils.fileFromURL(sourceURL);
524:                    } else {
525:                        return ConfigurationUtils.getFile(getBasePath(),
526:                                getFileName());
527:                    }
528:                }
529:            }
530:
531:            /**
532:             * Set the file where the configuration is stored. The passed in file is
533:             * made absolute if it is not yet. Then the file's path component becomes
534:             * the base path and its name component becomes the file name.
535:             *
536:             * @param file the file where the configuration is stored
537:             */
538:            public void setFile(File file) {
539:                sourceURL = null;
540:                setFileName(file.getName());
541:                setBasePath((file.getParentFile() != null) ? file
542:                        .getParentFile().getAbsolutePath() : null);
543:            }
544:
545:            /**
546:             * Returns the full path to the file this configuration is based on. The
547:             * return value is a valid File path only if this configuration is based on
548:             * a file on the local disk.
549:             * If the configuration was loaded from a packed archive the returned value
550:             * is the string form of the URL from which the configuration was loaded.
551:             *
552:             * @return the full path to the configuration file
553:             */
554:            public String getPath() {
555:                String path = null;
556:                File file = getFile();
557:                // if resource was loaded from jar file may be null
558:                if (file != null) {
559:                    path = file.getAbsolutePath();
560:                }
561:
562:                // try to see if file was loaded from a jar
563:                if (path == null) {
564:                    if (sourceURL != null) {
565:                        path = sourceURL.getPath();
566:                    } else {
567:                        try {
568:                            path = ConfigurationUtils.getURL(getBasePath(),
569:                                    getFileName()).getPath();
570:                        } catch (MalformedURLException e) {
571:                            // simply ignore it and return null
572:                            ;
573:                        }
574:                    }
575:                }
576:
577:                return path;
578:            }
579:
580:            /**
581:             * Sets the location of this configuration as a full or relative path name.
582:             * The passed in path should represent a valid file name on the file system.
583:             * It must not be used to specify relative paths for files that exist
584:             * in classpath, either plain file system or compressed archive,
585:             * because this method expands any relative path to an absolute one which
586:             * may end in an invalid absolute path for classpath references.
587:             *
588:             * @param path the full path name of the configuration file
589:             */
590:            public void setPath(String path) {
591:                setFile(new File(path));
592:            }
593:
594:            /**
595:             * Return the URL where the configuration is stored.
596:             *
597:             * @return the configuration's location as URL
598:             */
599:            public URL getURL() {
600:                return (sourceURL != null) ? sourceURL : ConfigurationUtils
601:                        .locate(getBasePath(), getFileName());
602:            }
603:
604:            /**
605:             * Set the location of this configuration as a URL. For loading this can be
606:             * an arbitrary URL with a supported protocol. If the configuration is to
607:             * be saved, too, a URL with the &quot;file&quot; protocol should be
608:             * provided.
609:             *
610:             * @param url the location of this configuration as URL
611:             */
612:            public void setURL(URL url) {
613:                setBasePath(ConfigurationUtils.getBasePath(url));
614:                setFileName(ConfigurationUtils.getFileName(url));
615:                sourceURL = url;
616:            }
617:
618:            public void setAutoSave(boolean autoSave) {
619:                this .autoSave = autoSave;
620:            }
621:
622:            public boolean isAutoSave() {
623:                return autoSave;
624:            }
625:
626:            /**
627:             * Save the configuration if the automatic persistence is enabled
628:             * and if a file is specified.
629:             */
630:            protected void possiblySave() {
631:                if (autoSave && fileName != null) {
632:                    try {
633:                        save();
634:                    } catch (ConfigurationException e) {
635:                        throw new ConfigurationRuntimeException(
636:                                "Failed to auto-save", e);
637:                    }
638:                }
639:            }
640:
641:            /**
642:             * Adds a new property to this configuration. This implementation checks if
643:             * the auto save mode is enabled and saves the configuration if necessary.
644:             *
645:             * @param key the key of the new property
646:             * @param value the value
647:             */
648:            public void addProperty(String key, Object value) {
649:                super .addProperty(key, value);
650:                possiblySave();
651:            }
652:
653:            /**
654:             * Sets a new value for the specified property. This implementation checks
655:             * if the auto save mode is enabled and saves the configuration if
656:             * necessary.
657:             *
658:             * @param key the key of the affected property
659:             * @param value the value
660:             */
661:            public void setProperty(String key, Object value) {
662:                super .setProperty(key, value);
663:                possiblySave();
664:            }
665:
666:            public void clearProperty(String key) {
667:                super .clearProperty(key);
668:                possiblySave();
669:            }
670:
671:            public ReloadingStrategy getReloadingStrategy() {
672:                return strategy;
673:            }
674:
675:            public void setReloadingStrategy(ReloadingStrategy strategy) {
676:                this .strategy = strategy;
677:                strategy.setConfiguration(this );
678:                strategy.init();
679:            }
680:
681:            /**
682:             * Performs a reload operation if necessary. This method is called on each
683:             * access of this configuration. It asks the associated reloading strategy
684:             * whether a reload should be performed. If this is the case, the
685:             * configuration is cleared and loaded again from its source. If this
686:             * operation causes an exception, the registered error listeners will be
687:             * notified. The error event passed to the listeners is of type
688:             * <code>EVENT_RELOAD</code> and contains the exception that caused the
689:             * event.
690:             */
691:            public void reload() {
692:                synchronized (reloadLock) {
693:                    if (noReload == 0) {
694:                        try {
695:                            enterNoReload(); // avoid reentrant calls
696:
697:                            if (strategy.reloadingRequired()) {
698:                                if (getLogger().isInfoEnabled()) {
699:                                    getLogger().info(
700:                                            "Reloading configuration. URL is "
701:                                                    + getURL());
702:                                }
703:                                fireEvent(EVENT_RELOAD, null, getURL(), true);
704:                                setDetailEvents(false);
705:                                try {
706:                                    clear();
707:                                    load();
708:                                } finally {
709:                                    setDetailEvents(true);
710:                                }
711:                                fireEvent(EVENT_RELOAD, null, getURL(), false);
712:
713:                                // notify the strategy
714:                                strategy.reloadingPerformed();
715:                            }
716:                        } catch (Exception e) {
717:                            fireError(EVENT_RELOAD, null, null, e);
718:                            // todo rollback the changes if the file can't be reloaded
719:                        } finally {
720:                            exitNoReload();
721:                        }
722:                    }
723:                }
724:            }
725:
726:            /**
727:             * Enters the &quot;No reloading mode&quot;. As long as this mode is active
728:             * no reloading will be performed. This is necessary for some
729:             * implementations of <code>save()</code> in derived classes, which may
730:             * cause a reload while accessing the properties to save. This may cause the
731:             * whole configuration to be erased. To avoid this, this method can be
732:             * called first. After a call to this method there always must be a
733:             * corresponding call of <code>{@link #exitNoReload()}</code> later! (If
734:             * necessary, <code>finally</code> blocks must be used to ensure this.
735:             */
736:            protected void enterNoReload() {
737:                synchronized (reloadLock) {
738:                    noReload++;
739:                }
740:            }
741:
742:            /**
743:             * Leaves the &quot;No reloading mode&quot;.
744:             *
745:             * @see #enterNoReload()
746:             */
747:            protected void exitNoReload() {
748:                synchronized (reloadLock) {
749:                    if (noReload > 0) // paranoia check
750:                    {
751:                        noReload--;
752:                    }
753:                }
754:            }
755:
756:            /**
757:             * Sends an event to all registered listeners. This implementation ensures
758:             * that no reloads are performed while the listeners are invoked. So
759:             * infinite loops can be avoided that can be caused by event listeners
760:             * accessing the configuration's properties when they are invoked.
761:             *
762:             * @param type the event type
763:             * @param propName the name of the property
764:             * @param propValue the value of the property
765:             * @param before the before update flag
766:             */
767:            protected void fireEvent(int type, String propName,
768:                    Object propValue, boolean before) {
769:                enterNoReload();
770:                try {
771:                    super .fireEvent(type, propName, propValue, before);
772:                } finally {
773:                    exitNoReload();
774:                }
775:            }
776:
777:            public Object getProperty(String key) {
778:                reload();
779:                return super .getProperty(key);
780:            }
781:
782:            public boolean isEmpty() {
783:                reload();
784:                return super .isEmpty();
785:            }
786:
787:            public boolean containsKey(String key) {
788:                reload();
789:                return super .containsKey(key);
790:            }
791:
792:            public Iterator getKeys() {
793:                reload();
794:                return super .getKeys();
795:            }
796:
797:            /**
798:             * Create the path to the specified file.
799:             *
800:             * @param file the target file
801:             */
802:            private void createPath(File file) {
803:                if (file != null) {
804:                    // create the path to the file if the file doesn't exist
805:                    if (!file.exists()) {
806:                        File parent = file.getParentFile();
807:                        if (parent != null && !parent.exists()) {
808:                            parent.mkdirs();
809:                        }
810:                    }
811:                }
812:            }
813:
814:            public String getEncoding() {
815:                return encoding;
816:            }
817:
818:            public void setEncoding(String encoding) {
819:                this .encoding = encoding;
820:            }
821:
822:            /**
823:             * Creates a copy of this configuration. The new configuration object will
824:             * contain the same properties as the original, but it will lose any
825:             * connection to a source file (if one exists); this includes setting the
826:             * source URL, base path, and file name to <b>null</b>. This is done to
827:             * avoid race conditions if both the original and the copy are modified and
828:             * then saved.
829:             *
830:             * @return the copy
831:             * @since 1.3
832:             */
833:            public Object clone() {
834:                AbstractFileConfiguration copy = (AbstractFileConfiguration) super 
835:                        .clone();
836:                copy.setBasePath(null);
837:                copy.setFileName(null);
838:                copy.initReloadingStrategy();
839:                return copy;
840:            }
841:
842:            /**
843:             * Helper method for initializing the reloading strategy.
844:             */
845:            private void initReloadingStrategy() {
846:                setReloadingStrategy(new InvariantReloadingStrategy());
847:            }
848:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.