View Javadoc

1   package com.explosion.utilities.preferences.impl.sun;
2   
3   /*
4    * =============================================================================
5    * 
6    * Copyright 2004 Stephen Cowx
7    * 
8    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
9    * use this file except in compliance with the License. You may obtain a copy of
10   * the License at
11   * 
12   * http://www.apache.org/licenses/LICENSE-2.0
13   * 
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17   * License for the specific language governing permissions and limitations under
18   * the License.
19   * 
20   * =============================================================================
21   */
22  
23  import java.awt.Color;
24  import java.awt.Font;
25  import java.io.File;
26  import java.util.ArrayList;
27  import java.util.List;
28  import java.util.prefs.BackingStoreException;
29  import java.util.prefs.Preferences;
30  
31  import com.explosion.utilities.GeneralConstants;
32  import com.explosion.utilities.preferences.EncryptionException;
33  import com.explosion.utilities.preferences.Preference;
34  import com.explosion.utilities.preferences.groups.PreferencePersistenceException;
35  import com.explosion.utilities.preferences.persist.PreferencePersister;
36  
37  /***
38   * @author: Stephen Cowx
39   *
40   * A persister to allow preferences to be persisted using the Java Preferences API
41   * 
42   */
43  
44  public class SunPreferencePersister implements PreferencePersister
45  {
46      private Preferences parentNode;
47  
48      /***
49       * Hidden constructor, want to use the factory method
50       */
51      private SunPreferencePersister()    {        
52      }
53      
54      /***
55       * Constructs an instance of a SunPreferencePersistor
56       * @param referenceToStore
57       * @return
58       */
59      public static PreferencePersister createPreferencePersistor(Object referenceToStore)
60      {
61          SunPreferencePersister persister = new SunPreferencePersister();
62          persister.parentNode = (Preferences) referenceToStore;
63          return persister;
64      }
65      
66      /***
67       * Returns a reference to the backing store as understood by the PreferencePersister
68       * @return
69       */
70      public Object getReferenceToStore()
71      {
72          return parentNode;
73      }
74      
75      /***
76       * Sets the reference to the backing store as understood by the PreferencePersister
77       * Effectively moving it from one store to another or moving it from one location in the same store to another
78       * @return
79       */
80      public void setReferenceToStore(Object referenceToStore)
81      {
82          this.parentNode = (Preferences) referenceToStore;
83      }
84      
85      /***
86       * This method saves the property to persistent storage, if the value is
87       * null, it should delete the entire key/value pair persisted if it exists
88       * or not save it if it does.
89       * 
90       * @throws Exception
91       */
92      public void save(Preference preference) throws PreferencePersistenceException
93      {
94          if (preference.isDefaulted())
95          {
96              /* If it is defaulted and this node exists then delete it */
97              if (parentNode.get(preference.getUniqueIdentifier(), null) != null)
98                  parentNode.remove(preference.getUniqueIdentifier());
99  
100             return;
101         }
102 
103         if (preference.getType() == Preference.PROPERTY_TYPE_COLLECTION)
104             persistCollection(preference);
105         else
106             persistPreference(preference.getType(), preference.getUniqueIdentifier(), preference.getValue(), parentNode);
107         
108         try {
109 			parentNode.flush();
110 		} catch (BackingStoreException e) {
111 			throw new PreferencePersistenceException("Exception caught while flushing Preferences node.", e);
112 		}
113     }
114 
115     /***
116      * @throws Exception
117      */
118     private void persistPreference(int type, String uniqueId, Object theValue, Preferences node) throws PreferencePersistenceException
119     {
120         try
121         {
122             switch (type)
123             {
124                 case (Preference.PROPERTY_TYPE_TEXT):
125                     node.put(uniqueId, (String) theValue);
126                     break;
127                 case (Preference.PROPERTY_TYPE_FILE):
128                     node.put(uniqueId, ((File) theValue).getAbsolutePath());
129                     break;
130                 case (Preference.PROPERTY_TYPE_DIRECTORY):
131                     node.put(uniqueId, ((File) theValue).getAbsolutePath());
132                     break;
133                 case (Preference.PROPERTY_TYPE_COLOR):
134                     node.putInt(uniqueId, ((Color) theValue).getRGB());
135                     break;
136                 case (Preference.PROPERTY_TYPE_INT):
137                     node.putInt(uniqueId, ((Integer) theValue).intValue());
138                     break;
139                 case (Preference.PROPERTY_TYPE_FLOAT):
140                     node.putFloat(uniqueId, ((Float) theValue).floatValue());
141                     break;
142                 case (Preference.PROPERTY_TYPE_STRING_CHOICE):
143                     node.put(uniqueId, ((String) theValue));
144                     break;
145                 case (Preference.PROPERTY_TYPE_INT_CHOICE):
146                     node.putInt(uniqueId, ((Integer) theValue).intValue());
147                     break;
148                 case (Preference.PROPERTY_TYPE_BOOLEAN):
149                     node.putBoolean(uniqueId, ((Boolean) theValue).booleanValue());
150                     break;
151                 case (Preference.PROPERTY_TYPE_FONT):
152                     String fontString = ((Font) theValue).getStyle() + "," + ((Font) theValue).getSize() + "," + ((Font) theValue).getName();
153                     node.put(uniqueId, fontString);
154                     break;
155                 case (Preference.PROPERTY_TYPE_ENCRYPTED):
156                     /* encrypt it before you write it */
157                     node.put(uniqueId, Preference.encrypt((String) theValue));
158                     break;
159                 case (Preference.PROPERTY_TYPE_COLLECTION):
160                     throw new IllegalArgumentException("Unexpected type : COLLECTION.");
161             }
162         }
163         catch (EncryptionException e)
164         {
165             throw new PreferencePersistenceException("Exception caught while persisting preference", e);
166         }
167     }
168 
169     /***
170      * Creates a new node for this collection and adds the children into it
171      * 
172      * @param preferences
173      */
174     private void persistCollection(Preference preference) throws PreferencePersistenceException
175     {
176         try
177         {
178             Preferences collectionNode = parentNode.node(preference.getUniqueIdentifier());
179             collectionNode.clear();
180             
181             List items = preference.getValues();
182             collectionNode.putInt(ITEM_COUNT, items.size());
183             for (int i = 0; i < items.size(); i++)
184             {
185                 persistPreference(preference.getCollectionType(), ITEM_NAME + i, items.get(i), collectionNode);
186             }
187         }
188         catch (BackingStoreException e)
189         {
190             throw new PreferencePersistenceException("Exception caught while saving preference " + preference.getLongName(), e);
191         }
192     }
193 
194     /***
195      * This method loads the property from persistent storage if it is there, if
196      * it is not it should not populate the value.
197      * 
198      * @throws Exception
199      */
200     public void load(Preference preference) throws PreferencePersistenceException
201     {
202         try
203         {
204             if (preference.getType() != Preference.PROPERTY_TYPE_COLLECTION)
205             {
206                 if (parentNode.get(preference.getUniqueIdentifier(), null) == null)
207                    return;
208                 
209                 Object object = getTypedValue(preference.getType(), parentNode, preference.getUniqueIdentifier(), preference.getDefaultValue());
210                 preference.setValue(object);
211 
212                 /* Do some cleaning for files etc */
213                 switch (preference.getType())
214                 {
215                 case (Preference.PROPERTY_TYPE_FILE):
216                     if (((File) preference.getValue()).getName().indexOf(GeneralConstants.DEFAULT_FILE) >= 0)
217                         preference.setValue(preference.createDefaultFile());
218                     break;
219                 case (Preference.PROPERTY_TYPE_DIRECTORY):
220                     if (((File) preference.getValue()).getName().equals(GeneralConstants.DEFAULT_FILE))
221                         preference.setValue(preference.createDefaultFile());
222                     break;
223                 }
224             }
225             else
226             {
227                loadCollection(preference);
228             }
229         }
230         catch (PreferencePersistenceException e)
231         {
232             throw e;
233         }
234         catch (Exception e)
235         {
236             throw new PreferencePersistenceException("Error caught while persisting data", e);
237         }
238     }
239 
240     /***
241      * Obtains and creates the object from the persistent store based on it's
242      * type
243      * 
244      * @param type
245      * @param node
246      * @param uniqueIdentifier
247      * @param defaultValue
248      * @return @throws Exception
249      */
250     private Object getTypedValue(int type, Preferences node, String uniqueIdentifier, Object defaultValue) throws PreferencePersistenceException
251     {
252         try
253         {
254             switch (type)
255             {
256                 case (Preference.PROPERTY_TYPE_TEXT):
257                     return node.get(uniqueIdentifier, (String) defaultValue);
258                 case (Preference.PROPERTY_TYPE_FILE):
259                     return new File(node.get(uniqueIdentifier, ((File) defaultValue).toString()));
260                 case (Preference.PROPERTY_TYPE_DIRECTORY):
261                     return new File(node.get(uniqueIdentifier, ((File) defaultValue).toString()));
262                 case (Preference.PROPERTY_TYPE_COLOR):
263                     return new Color(node.getInt(uniqueIdentifier, ((Color) defaultValue).getRGB()));
264                 case (Preference.PROPERTY_TYPE_INT):
265                     return new Integer(node.getInt(uniqueIdentifier, ((Integer) defaultValue).intValue()));
266                 case (Preference.PROPERTY_TYPE_FLOAT):
267                     return new Float(node.getFloat(uniqueIdentifier, ((Float) defaultValue).floatValue()));
268                 case (Preference.PROPERTY_TYPE_STRING_CHOICE):
269                     return getTypedValue(Preference.PROPERTY_TYPE_TEXT, node, uniqueIdentifier, defaultValue);
270                 case (Preference.PROPERTY_TYPE_INT_CHOICE):
271                     return getTypedValue(Preference.PROPERTY_TYPE_INT, node, uniqueIdentifier, defaultValue);
272                 case (Preference.PROPERTY_TYPE_BOOLEAN):
273                     return new Boolean(node.getBoolean(uniqueIdentifier, ((Boolean) defaultValue).booleanValue()));
274                 case (Preference.PROPERTY_TYPE_FONT):
275                     String defaultFontString = ((Font) defaultValue).getStyle() + "," + ((Font) defaultValue).getSize() + "," + ((Font) defaultValue).getName();
276                     return Preference.deriveFont(node.get(uniqueIdentifier, defaultFontString));
277                 case (Preference.PROPERTY_TYPE_ENCRYPTED):
278                     /* decrypt it as you read it */
279                     return Preference.decrypt(node.get(uniqueIdentifier, (String) defaultValue));
280                 default:
281                     return null;
282             }
283         }
284         catch (PreferencePersistenceException e)
285         {
286             throw e;
287         }
288         catch (EncryptionException e)
289         {
290             throw new PreferencePersistenceException("Error caught while persisting data", e);
291         }
292     }
293     
294    /***
295      * loads this collection into the values List
296      * 
297      * @param preferences
298      */
299     private void loadCollection(Preference preference) throws Exception
300     {
301         Preferences collectionNode = parentNode.node(preference.getUniqueIdentifier());
302         int numberOfItems = collectionNode.getInt(ITEM_COUNT, -1);
303         if (numberOfItems == -1)
304           return;
305           
306         List items = new ArrayList();
307         
308         for (int i = 0; i < numberOfItems; i++)
309         {
310             items.add(getTypedValue(preference.getCollectionType(), collectionNode, ITEM_NAME + i, preference.getDefaultValue()));
311         }
312         
313         preference.setValues(items, preference.getCollectionType());
314     }
315    
316 }