View Javadoc
1   /*
2    * Copyright (c) 2009 QOS.ch All rights reserved.
3    * 
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   * 
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   * 
14   * THE SOFTWARE IS PROVIDED "AS  IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  package ch.qos.cal10n.util;
23  
24  import java.io.File;
25  import java.io.IOException;
26  import java.io.Reader;
27  import java.util.Enumeration;
28  import java.util.Hashtable;
29  import java.util.Map;
30  import java.util.ResourceBundle;
31  import java.util.concurrent.ConcurrentHashMap;
32  
33  /**
34   * 
35   * @author Ceki Gülcü
36   *
37   */
38  public class CAL10NBundle extends ResourceBundle {
39  
40    static long CHECK_DELAY = 10 * 60 * 1000; // 10 minutes delay
41  
42    Map<String, String> map = new ConcurrentHashMap<String, String>();
43    File hostFile;
44    volatile long nextCheck;
45    long lastModified;
46    CAL10NBundle parent;
47    
48    public CAL10NBundle(Reader r, File file)
49        throws IOException {
50      read(r);
51      this.hostFile = file;
52      nextCheck = System.currentTimeMillis() + CHECK_DELAY;
53    }
54  
55    void read(Reader r) throws IOException {
56      Parser p = new Parser(r, map);
57      p.parseAndPopulate();
58    }
59  
60  
61    public void setParent(CAL10NBundle parent) {
62      this.parent = (parent);
63    }
64  
65    public boolean hasChanged() {
66      // if the host file is unknown, no point in a check
67      if (hostFile == null) {
68        return false;
69      }
70  
71      long now = System.currentTimeMillis();
72      if (now < nextCheck) {
73        return false;
74      } else {
75        nextCheck = now + CHECK_DELAY;
76        if (lastModified != hostFile.lastModified()) {
77          lastModified = hostFile.lastModified();
78          return true;
79        } else {
80          return false;
81        }
82      }
83    }
84  
85    /**
86     * WARNING: Used for testing purposes. Do not invoke directly in user code.
87     */
88    public void resetCheckTimes() {
89      nextCheck = 0;
90      lastModified = 0;
91    } 
92  
93    @Override
94    public Enumeration<String> getKeys() {
95      Hashtable<String, String> ht = new Hashtable<String, String>(map);
96      if(parent != null) {
97        ht.putAll(parent.map);
98      }
99      return ht.keys();
100   }
101 
102   @Override
103   protected Object handleGetObject(String key) {
104     if (key == null) {
105       throw new NullPointerException();
106     }
107     Object o = map.get(key);
108     if(o == null && parent != null) {
109       o = parent.handleGetObject(key);
110     }
111     return o;
112   }
113 }