##### Coverage Report - org.apache.commons.configuration.reloading.FileChangedReloadingStrategy

Classes in this File | Line Coverage | Branch Coverage | Complexity
FileChangedReloadingStrategy |
94% | 31/33
100% | 7/7
| 1.9;1,9

1 |  |
     /*
2 |  |
      * Licensed to the Apache Software Foundation (ASF) under one or more
3 |  |
      * contributor license agreements.  See the NOTICE file distributed with
4 |  |
      * this work for additional information regarding copyright ownership.
5 |  |
      * The ASF licenses this file to You under the Apache License, Version 2.0
6 |  |
      * (the "License"); you may not use this file except in compliance with
7 |  |
      * the License.  You may obtain a copy of the License at
8 |  |
      *
9 |  |
      *     http://www.apache.org/licenses/LICENSE-2.0
10 |  |
      *
11 |  |
      * Unless required by applicable law or agreed to in writing, software
12 |  |
      * distributed under the License is distributed on an "AS IS" BASIS,
13 |  |
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 |  |
      * See the License for the specific language governing permissions and
15 |  |
      * limitations under the License.
16 |  |
      */
17 |  |
18 |  |
     package org.apache.commons.configuration.reloading;
19 |  |
20 |  |
     import java.io.File;
21 |  |
     import java.net.MalformedURLException;
22 |  |
     import java.net.URL;
23 |  |
24 |  |
     import org.apache.commons.configuration.ConfigurationUtils;
25 |  |
     import org.apache.commons.configuration.FileConfiguration;
26 |  |
27 |  |
     /**
28 |  |
      * <p>A reloading strategy that will reload the configuration every time its
29 |  |
      * underlying file is changed.</p>
30 |  |
      * <p>This reloading strategy does not actively monitor a configuration file,
31 |  |
      * but is triggered by its associated configuration whenever properties are
32 |  |
      * accessed. It then checks the configuration file's last modification date
33 |  |
      * and causes a reload if this has changed.</p>
34 |  |
      * <p>To avoid permanent disc access on successive property lookups a refresh
35 |  |
      * delay can be specified. This has the effect that the configuration file's
36 |  |
      * last modification date is only checked once in this delay period. The default
37 |  |
      * value for this refresh delay is 5 seconds.</p>
38 |  |
      * <p>This strategy only works with FileConfiguration instances.</p>
39 |  |
      *
40 |  |
      * @author Emmanuel Bourg
41 |  |
      * @version $Revision: 439648 $, $Date: 2006-09-02 22:42:10 +0200 (Sa, 02 Sep 2006) $
42 |  |
      * @since 1.1
43 |  |
      */
44 | 24 |
     public class FileChangedReloadingStrategy implements ReloadingStrategy
45 |  |
     {
46 |  |
         /** Constant for the jar URL protocol.*/
47 |  |
         private static final String JAR_PROTOCOL = "jar";
48 |  |
49 |  |
         /** Constant for the default refresh delay.*/
50 |  |
         private static final int DEFAULT_REFRESH_DELAY = 5000;
51 |  |
52 |  |
         /** Stores a reference to the configuration to be monitored.*/
53 |  |
         protected FileConfiguration configuration;
54 |  |
55 |  |
         /** The last time the configuration file was modified. */
56 |  |
         protected long lastModified;
57 |  |
58 |  |
         /** The last time the file was checked for changes. */
59 |  |
         protected long lastChecked;
60 |  |
61 |  |
         /** The minimum delay in milliseconds between checks. */
62 | 24 |
         protected long refreshDelay = DEFAULT_REFRESH_DELAY;
63 |  |
64 |  |
         public void setConfiguration(FileConfiguration configuration)
65 |  |
         {
66 | 23 |
             this.configuration = configuration;
67 | 23 |
         }
68 |  |
69 |  |
         public void init()
70 |  |
         {
71 | 26 |
             updateLastModified();
72 | 26 |
         }
73 |  |
74 |  |
         public boolean reloadingRequired()
75 |  |
         {
76 | 450 |
             boolean reloading = false;
77 |  |
78 | 450 |
             long now = System.currentTimeMillis();
79 |  |
80 | 450 |
             if (now > lastChecked + refreshDelay)
81 |  |
             {
82 | 8 |
                 lastChecked = now;
83 | 8 |
                 if (hasChanged())
84 |  |
                 {
85 | 2 |
                     reloading = true;
86 |  |
                 }
87 |  |
             }
88 |  |
89 | 450 |
             return reloading;
90 |  |
         }
91 |  |
92 |  |
         public void reloadingPerformed()
93 |  |
         {
94 | 46 |
             updateLastModified();
95 | 46 |
         }
96 |  |
97 |  |
         /**
98 |  |
          * Return the minimal time in milliseconds between two reloadings.
99 |  |
          *
100 |  |
          * @return the refresh delay (in milliseconds)
101 |  |
          */
102 |  |
         public long getRefreshDelay()
103 |  |
         {
104 | 2 |
             return refreshDelay;
105 |  |
         }
106 |  |
107 |  |
         /**
108 |  |
          * Set the minimal time between two reloadings.
109 |  |
          *
110 |  |
          * @param refreshDelay refresh delay in milliseconds
111 |  |
          */
112 |  |
         public void setRefreshDelay(long refreshDelay)
113 |  |
         {
114 | 7 |
             this.refreshDelay = refreshDelay;
115 | 7 |
         }
116 |  |
117 |  |
         /**
118 |  |
          * Update the last modified time.
119 |  |
          */
120 |  |
         protected void updateLastModified()
121 |  |
         {
122 | 72 |
             File file = getFile();
123 | 72 |
             if (file != null)
124 |  |
             {
125 | 72 |
                 lastModified = file.lastModified();
126 |  |
             }
127 | 72 |
         }
128 |  |
129 |  |
         /**
130 |  |
          * Check if the configuration has changed since the last time it was loaded.
131 |  |
          *
132 |  |
          * @return a flag whether the configuration has changed
133 |  |
          */
134 |  |
         protected boolean hasChanged()
135 |  |
         {
136 | 8 |
             File file = getFile();
137 | 8 |
             if (file == null || !file.exists())
138 |  |
             {
139 | 1 |
                 return false;
140 |  |
             }
141 |  |
142 | 7 |
             return file.lastModified() > lastModified;
143 |  |
         }
144 |  |
145 |  |
         /**
146 |  |
          * Returns the file that is monitored by this strategy. Note that the return
147 |  |
          * value can be <b>null </b> under some circumstances.
148 |  |
          *
149 |  |
          * @return the monitored file
150 |  |
          */
151 |  |
         protected File getFile()
152 |  |
         {
153 | 83 |
             return (configuration.getURL() != null) ? fileFromURL(configuration
154 |  |
                     .getURL()) : configuration.getFile();
155 |  |
         }
156 |  |
157 |  |
         /**
158 |  |
          * Helper method for transforming a URL into a file object. This method
159 |  |
          * handles file: and jar: URLs.
160 |  |
          *
161 |  |
          * @param url the URL to be converted
162 |  |
          * @return the resulting file or <b>null </b>
163 |  |
          */
164 |  |
         private File fileFromURL(URL url)
165 |  |
         {
166 | 81 |
             if (JAR_PROTOCOL.equals(url.getProtocol()))
167 |  |
             {
168 | 2 |
                 String path = url.getPath();
169 |  |
                 try
170 |  |
                 {
171 | 2 |
                     return ConfigurationUtils.fileFromURL(new URL(path.substring(0,
172 |  |
                             path.indexOf('!'))));
173 |  |
                 }
174 | 0 |
                 catch (MalformedURLException mex)
175 |  |
                 {
176 | 0 |
                     return null;
177 |  |
                 }
178 |  |
             }
179 |  |
             else
180 |  |
             {
181 | 79 |
                 return ConfigurationUtils.fileFromURL(url);
182 |  |
             }
183 |  |
         }
184 |  |
     }