View Javadoc
1   /*
2    * This software was designed and created by Jason Carroll.
3    * Copyright (c) 2002, 2003, 2004 Jason Carroll.
4    * The author can be reached at jcarroll@cowsultants.com
5    * ITracker website: http://www.cowsultants.com
6    * ITracker forums: http://www.cowsultants.com/phpBB/index.php
7    *
8    * This program is free software; you can redistribute it and/or modify
9    * it only under the terms of the GNU General Public License as published by
10   * the Free Software Foundation; either version 2 of the License, or
11   * (at your option) any later version.
12   *
13   * This program is distributed in the hope that it will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   * GNU General Public License for more details.
17   */
18  
19  package org.itracker.core.resources;
20  import org.itracker.ITrackerDirtyResourceException;
21  import org.slf4j.Logger;
22  import org.slf4j.LoggerFactory;
23  import java.util.*;
24  
25  public class ITrackerResourceBundle extends ResourceBundle {
26  
27      private static final Logger log = LoggerFactory
28              .getLogger(ITrackerResourceBundle.class);
29      private final Properties data = new Properties();
30  
31      private ResourceBundle propertiesBundle;
32  
33  
34      static ResourceBundle loadBundle() {
35          return new ITrackerResourceBundle();
36      }
37  
38      static ResourceBundle loadBundle(Locale locale) {
39          return new ITrackerResourceBundle(locale);
40      }
41  
42  
43      static ResourceBundle loadBundle(Locale locale, Properties items) {
44          return new ITrackerResourceBundle(locale, items);
45      }
46  
47      private ITrackerResourceBundle() {
48          super.setParent(ResourceBundle.getBundle(
49                  ITrackerResources.RESOURCE_BUNDLE_NAME, new Locale(
50                  ITrackerResources.getDefaultLocale())));
51      }
52  
53      /**
54       * @param locale
55       */
56      private ITrackerResourceBundle(Locale locale) {
57          if (null == locale) {
58              locale = ITrackerResources.getLocale(ITrackerResources
59                      .getDefaultLocale());
60          }
61          this.propertiesBundle = ResourceBundle.getBundle(
62                  ITrackerResources.RESOURCE_BUNDLE_NAME, locale,
63                  Control.getNoFallbackControl(Control.FORMAT_DEFAULT));
64  
65          if (!locale.equals(ITrackerResources
66                  .getLocale(ITrackerResources.BASE_LOCALE))) {
67              if (locale.getCountry().length() > 0) {
68                  setParent(ITrackerResources.getBundle(new Locale(locale
69                          .getLanguage())));
70              } else if (locale.getLanguage().length() > 0) {
71                  setParent(ITrackerResources.getBundle(ITrackerResources
72                          .getLocale(ITrackerResources.BASE_LOCALE)));
73              }
74          }
75  
76      }
77  
78      public ITrackerResourceBundle(Locale locale, Properties items) {
79          this(locale);
80          if (null != items) {
81              this.data.putAll(items);
82          }
83      }
84  
85      public static ResourceBundle getBundle() {
86          return ITrackerResources.getBundle();
87      }
88  
89      public static ResourceBundle getBundle(Locale locale) {
90          return ITrackerResources.getBundle(locale);
91      }
92  
93      /**
94       * @deprecated used still for testing
95       */
96      public ITrackerResourceBundle(Locale locale, Object[][] data) {
97          this(locale);
98          setContents(data);
99      }
100 
101     /**
102      * @param content
103      */
104     @Deprecated
105     private void setContents(Object[][] content) {
106         if (content != null && content.length == 2
107                 && content[0].length == content[1].length) {
108             synchronized (data) {
109                 data.clear();
110                 for (int i = 0; i < content[0].length; i++) {
111                     data.put(content[0][i], content[1][i]);
112                 }
113             }
114         }
115     }
116 
117     @Override
118     public Locale getLocale() {
119         Locale l = super.getLocale();
120         if (null == l && null != propertiesBundle) {
121             l = propertiesBundle.getLocale();
122         }
123         return l;
124     }
125 
126     public boolean isDirty(String key) {
127         try {
128             handleGetObject(key);
129         } catch (ITrackerDirtyResourceException exception) {
130             return true;
131         }
132         return false;
133     }
134 
135 
136     public void updateValue(String key, String value) {
137         if (null == key) {
138             throw new IllegalArgumentException("key must not be null");
139         }
140         if (null == value) {
141             throw new IllegalArgumentException("value must not be null");
142         }
143         synchronized (data) {
144             data.put(key, value);
145         }
146     }
147 
148 
149     public void removeValue(String key, boolean markDirty) {
150         if (key != null) {
151             synchronized (data) {
152                 if (markDirty) {
153                     data.put(key, new DirtyKey() {
154                     });
155                 } else {
156                     data.remove(key);
157                 }
158             }
159         }
160     }
161 
162     /**
163      * Implementation of ResourceBundle.handleGetObject. Returns the request key
164      * from the internal data map.
165      */
166     public final Object handleGetObject(String key) {
167         Object value = data.get(key);
168         if (value instanceof DirtyKey) {
169             throw new ITrackerDirtyResourceException(
170                     "The requested key has been marked dirty.",
171                     "ITrackerResourceBundle_" + getLocale(), key);
172         }
173         if (null == value) {
174             try {
175                 value = propertiesBundle.getObject(key);
176             } catch (MissingResourceException e) {
177                 if (log.isDebugEnabled()) {
178                     log.debug("handleGetObject: " + key, e);
179                 }
180             }
181         }
182         return value;
183     }
184 
185     /**
186      * Implementation of ResourceBundle.getKeys. Since it returns an
187      * enumeration, It creates a new Set, and returns that collections
188      * enumerator.
189      */
190     public Enumeration<String> getKeys() {
191                 Set set = new TreeSet(data.keySet());
192         if (null != parent) {
193             Enumeration<String> keys = parent.getKeys();
194             String key;
195             while (keys.hasMoreElements()) {
196                 key = keys.nextElement();
197                 set.add(key);
198             }
199         }
200         if (null != propertiesBundle) {
201             Enumeration<String> keys = propertiesBundle.getKeys();
202             String key;
203             while (keys.hasMoreElements()) {
204                 key = keys.nextElement();
205                 set.add(key);
206             }
207         }
208         return Collections.enumeration(set);
209     }
210 
211     public interface DirtyKey {
212     }
213 }