View Javadoc

1   /*
2    * Created by IntelliJ IDEA.
3    * User: Mike
4    * Date: Jun 1, 2004
5    * Time: 3:08:51 PM
6    */
7   package com.atlassian.core.propertyset;
8   
9   import com.opensymphony.module.propertyset.PropertySet;
10  import com.opensymphony.module.propertyset.PropertyException;
11  import com.opensymphony.module.propertyset.PropertySetSchema;
12  import com.opensymphony.module.propertyset.PropertySetManager;
13  import com.opensymphony.module.propertyset.memory.SerializablePropertySet;
14  import com.opensymphony.util.DataUtil;
15  
16  import java.io.Serializable;
17  import java.util.*;
18  
19  import org.w3c.dom.Document;
20  
21  /**
22   * A PropertySet which decorates another PropertySet and caches the results.
23   * <p/>
24   * <p/>
25   * This class performs similar objective as the
26   * com.opensymphony.module.propertyset.cached.CachingPropertySet class but does more
27   * caching.
28   * <p/>
29   * (originally from JiraCachingPropertySet in JIRA)
30   */
31  public class CachingPropertySet implements PropertySet, Serializable
32  {
33      private PropertySet decoratedPS;
34      private SerializablePropertySet cachePS;
35      private Map existantKeyCache;
36  
37      /**
38       * Args required are:
39       * <ul>
40       * <li>PropertySet - the PropertySet being decorated
41       * <li>serializableName - the name of the serializable PropertySet to use for the 'property cache' (optional - defaults to 'serializable')
42       * <li>bulkload - a Boolean determining whether or not to bulk load all of the properties into the cache upon startup
43       * </ul>
44       * @param config
45       * @param args
46       */
47      public void init(Map config, Map args)
48      {
49          decoratedPS = (PropertySet) args.get("PropertySet");
50  
51          String serializableName = (String) config.get("serializableName");
52  
53          if (serializableName == null)
54          {
55              serializableName = "serializable";
56          }
57  
58          cachePS = (SerializablePropertySet) PropertySetManager.getInstance(serializableName, null);
59          existantKeyCache = new HashMap();
60  
61          Boolean bulkload = (Boolean) args.get("bulkload");
62  
63          if ((bulkload != null) && bulkload.booleanValue())
64          {
65              PropertySetManager.clone(decoratedPS, cachePS);
66          }
67      }
68  
69      public void setAsActualType(String key, Object value) throws PropertyException
70      {
71          if (value instanceof Boolean)
72          {
73              setBoolean(key, DataUtil.getBoolean((Boolean) value));
74          }
75          else if (value instanceof Integer)
76          {
77              setInt(key, DataUtil.getInt((Integer) value));
78          }
79          else if (value instanceof Long)
80          {
81              setLong(key, DataUtil.getLong((Long) value));
82          }
83          else if (value instanceof Double)
84          {
85              setDouble(key, DataUtil.getDouble((Double) value));
86          }
87          else if (value instanceof String)
88          {
89              setString(key, (String) value);
90          }
91          else if (value instanceof Date)
92          {
93              setDate(key, (Date) value);
94          }
95          else if (value instanceof Document)
96          {
97              setXML(key, (Document) value);
98          }
99          else if (value instanceof byte[])
100         {
101             setData(key, (byte[]) value);
102         }
103         else if (value instanceof Properties)
104         {
105             setProperties(key, (Properties) value);
106         }
107         else
108         {
109             setObject(key, value);
110         }
111     }
112 
113     public Object getAsActualType(String key) throws PropertyException
114     {
115         int type = getType(key);
116         Object value = null;
117 
118         switch (type)
119         {
120             case BOOLEAN:
121                 value = new Boolean(getBoolean(key));
122                 break;
123 
124             case INT:
125                 value = new Integer(getInt(key));
126                 break;
127 
128             case LONG:
129                 value = new Long(getLong(key));
130                 break;
131 
132             case DOUBLE:
133                 value = new Double(getDouble(key));
134                 break;
135 
136             case STRING:
137                 value = getString(key);
138                 break;
139 
140             case DATE:
141                 value = getDate(key);
142                 break;
143 
144             case XML:
145                 value = getXML(key);
146                 break;
147 
148             case DATA:
149                 value = getData(key);
150                 break;
151 
152             case PROPERTIES:
153                 value = getProperties(key);
154                 break;
155 
156             case OBJECT:
157                 value = getObject(key);
158                 break;
159         }
160 
161         return value;
162     }
163 
164     public void setBoolean(String key, boolean value) throws PropertyException
165     {
166         decoratedPS.setBoolean(key, value);
167         cachePS.setBoolean(key, value);
168 
169         // Clear cache
170         existantKeyCache.remove(key);
171     }
172 
173     public boolean getBoolean(String key) throws PropertyException
174     {
175         if (!cachePS.exists(key))
176         {
177             cachePS.setBoolean(key, decoratedPS.getBoolean(key));
178         }
179 
180         return cachePS.getBoolean(key);
181     }
182 
183     public void setData(String key, byte[] value) throws PropertyException
184     {
185         decoratedPS.setData(key, value);
186         cachePS.setData(key, value);
187 
188         // Clear cache
189         existantKeyCache.remove(key);
190     }
191 
192     public byte[] getData(String key) throws PropertyException
193     {
194         if (!cachePS.exists(key))
195         {
196             cachePS.setData(key, decoratedPS.getData(key));
197         }
198 
199         return cachePS.getData(key);
200     }
201 
202     public void setDate(String key, Date value) throws PropertyException
203     {
204         decoratedPS.setDate(key, value);
205         cachePS.setDate(key, value);
206 
207         // Clear cache
208         existantKeyCache.remove(key);
209     }
210 
211     public Date getDate(String key) throws PropertyException
212     {
213         if (!cachePS.exists(key))
214         {
215             cachePS.setDate(key, decoratedPS.getDate(key));
216         }
217 
218         return cachePS.getDate(key);
219     }
220 
221     public void setDouble(String key, double value) throws PropertyException
222     {
223         decoratedPS.setDouble(key, value);
224         cachePS.setDouble(key, value);
225 
226         // Clear cache
227         existantKeyCache.remove(key);
228     }
229 
230     public double getDouble(String key) throws PropertyException
231     {
232         if (!cachePS.exists(key))
233         {
234             cachePS.setDouble(key, decoratedPS.getDouble(key));
235         }
236 
237         return cachePS.getDouble(key);
238     }
239 
240     public void setInt(String key, int value) throws PropertyException
241     {
242         decoratedPS.setInt(key, value);
243         cachePS.setInt(key, value);
244 
245         // Clear cache
246         existantKeyCache.remove(key);
247     }
248 
249     public int getInt(String key) throws PropertyException
250     {
251         if (!cachePS.exists(key))
252         {
253             cachePS.setInt(key, decoratedPS.getInt(key));
254         }
255 
256         return cachePS.getInt(key);
257     }
258 
259     public Collection getKeys() throws PropertyException
260     {
261         return decoratedPS.getKeys();
262     }
263 
264     public Collection getKeys(int type) throws PropertyException
265     {
266         return decoratedPS.getKeys(type);
267     }
268 
269     public Collection getKeys(String prefix) throws PropertyException
270     {
271         return decoratedPS.getKeys(prefix);
272     }
273 
274     public Collection getKeys(String prefix, int type) throws PropertyException
275     {
276         return decoratedPS.getKeys(prefix, type);
277     }
278 
279     public void setLong(String key, long value) throws PropertyException
280     {
281         decoratedPS.setLong(key, value);
282         cachePS.setLong(key, value);
283 
284         // Clear cache
285         existantKeyCache.remove(key);
286     }
287 
288     public long getLong(String key) throws PropertyException
289     {
290         if (!cachePS.exists(key))
291         {
292             cachePS.setLong(key, decoratedPS.getLong(key));
293         }
294 
295         return cachePS.getLong(key);
296     }
297 
298     public void setObject(String key, Object value) throws PropertyException
299     {
300         decoratedPS.setObject(key, value);
301         cachePS.setObject(key, value);
302 
303         // Clear cache
304         existantKeyCache.remove(key);
305     }
306 
307     public Object getObject(String key) throws PropertyException
308     {
309         if (!cachePS.exists(key))
310         {
311             cachePS.setObject(key, decoratedPS.getObject(key));
312         }
313 
314         return cachePS.getObject(key);
315     }
316 
317     public void setProperties(String key, Properties value) throws PropertyException
318     {
319         decoratedPS.setProperties(key, value);
320         cachePS.setProperties(key, value);
321 
322         // Clear cache
323         existantKeyCache.remove(key);
324     }
325 
326     public Properties getProperties(String key) throws PropertyException
327     {
328         if (!cachePS.exists(key))
329         {
330             cachePS.setProperties(key, decoratedPS.getProperties(key));
331         }
332 
333         return cachePS.getProperties(key);
334     }
335 
336     public void setSchema(PropertySetSchema schema) throws PropertyException
337     {
338         decoratedPS.setSchema(schema);
339     }
340 
341     public PropertySetSchema getSchema() throws PropertyException
342     {
343         return decoratedPS.getSchema();
344     }
345 
346     public boolean isSettable(String property)
347     {
348         return decoratedPS.isSettable(property);
349     }
350 
351     public void setString(String key, String value) throws PropertyException
352     {
353         decoratedPS.setString(key, value);
354         cachePS.setString(key, value);
355 
356         // Clear cache
357         existantKeyCache.remove(key);
358     }
359 
360     public String getString(String key) throws PropertyException
361     {
362         if (!cachePS.exists(key))
363         {
364             cachePS.setString(key, decoratedPS.getString(key));
365         }
366 
367         return cachePS.getString(key);
368     }
369 
370     public void setText(String key, String value) throws PropertyException
371     {
372         decoratedPS.setText(key, value);
373         cachePS.setText(key, value);
374 
375         // Clear cache
376         existantKeyCache.remove(key);
377     }
378 
379     public String getText(String key) throws PropertyException
380     {
381         if (!cachePS.exists(key))
382         {
383             cachePS.setText(key, decoratedPS.getText(key));
384         }
385 
386         return cachePS.getText(key);
387     }
388 
389     public int getType(String key) throws PropertyException
390     {
391         return decoratedPS.getType(key);
392     }
393 
394     public void setXML(String key, Document value) throws PropertyException
395     {
396         decoratedPS.setXML(key, value);
397         cachePS.setXML(key, value);
398 
399         // Clear cache
400         existantKeyCache.remove(key);
401     }
402 
403     public Document getXML(String key) throws PropertyException
404     {
405         if (!cachePS.exists(key))
406         {
407             cachePS.setXML(key, decoratedPS.getXML(key));
408         }
409 
410         return cachePS.getXML(key);
411     }
412 
413     public boolean exists(String key) throws PropertyException
414     {
415         // Check if we have the result for the exists() call cached. If not check the
416         // decoratedPS
417         if (existantKeyCache.containsKey(key))
418         {
419             return Boolean.TRUE.equals(existantKeyCache.get(key));
420         }
421 
422         boolean keyExists = decoratedPS.exists(key);
423 
424         // Cache the result
425         existantKeyCache.put(key, new Boolean(keyExists));
426         return keyExists;
427     }
428 
429     public void remove(String key) throws PropertyException
430     {
431         existantKeyCache.remove(key);
432         cachePS.remove(key);
433         decoratedPS.remove(key);
434     }
435 
436     public boolean supportsType(int type)
437     {
438         return decoratedPS.supportsType(type);
439     }
440 
441     public boolean supportsTypes()
442     {
443         return decoratedPS.supportsTypes();
444     }
445 }