source: trunk/LogicMail/src/org/logicprobe/LogicMail/util/PersistentObjectDataStore.java @ 800

Revision 800, 9.8 KB checked in by octorian, 17 months ago (diff)

Added own-classpath wrapper around persisted configuration data

  • Property svn:mime-type set to text/plain
Line 
1/*-
2 * Copyright (c) 2008, Derek Konigsberg
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the project nor the names of its
15 *    contributors may be used to endorse or promote products derived
16 *    from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29 * OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32package org.logicprobe.LogicMail.util;
33
34import java.util.Enumeration;
35import java.util.Vector;
36
37import net.rim.device.api.system.PersistentObject;
38import net.rim.device.api.system.PersistentStore;
39import net.rim.device.api.util.LongHashtable;
40import net.rim.device.api.util.ToLongHashtable;
41
42public class PersistentObjectDataStore implements DataStore {
43    /** Unique id for the root persistent object */
44    private long storeUid;
45    /** Root persistent object store */
46    private PersistentObject store;
47    /** Name to UID mappings */
48    private ToLongHashtable nameMap;
49    /** UID to Object mappings */
50    private LongHashtable objectMap;
51   
52    /**
53     * Creates a new instance of RmsDataStore.
54     * @param storeUid Unique ID of the store to use.
55     */
56    public PersistentObjectDataStore(long storeUid) {
57        this.storeUid = storeUid;
58        this.store = PersistentStore.getPersistentObject(storeUid);
59        this.nameMap = new ToLongHashtable();
60        this.objectMap = new LongHashtable();
61    }
62
63    public Serializable getNamedObject(String name) {
64        // Get the ID that matches the name
65        long id = nameMap.get(name);
66        if(id != -1) {
67            // Now get the object that matches the ID
68            return (Serializable)objectMap.get(id);
69        }
70        else {
71            return null;
72        }
73    }
74
75    public String[] getNamedObjects() {
76        String[] result = new String[nameMap.size()];
77        Enumeration e = nameMap.keys();
78        int i = 0;
79        while(e.hasMoreElements()) {
80            result[i++] = (String)e.nextElement();
81        }
82        return result;
83    }
84   
85    public Serializable getObject(long id) {
86        return (Serializable)objectMap.get(id);
87    }
88
89    public void putNamedObject(String name, Serializable object) {
90        // If this replaces an existing named object, we need to make sure to
91        // remove the old object from the object map.
92        long oldObjectId = nameMap.get(name);
93        if(oldObjectId != -1) {
94            objectMap.remove(oldObjectId);
95        }
96       
97        nameMap.put(name, object.getUniqueId());
98        putObject(object);
99    }
100
101    public void putObject(Serializable object) {
102        objectMap.put(object.getUniqueId(), object);
103    }
104
105    public void removeNamedObject(String name) {
106        Serializable object = getNamedObject(name);
107        if(object != null) {
108            objectMap.remove(object.getUniqueId());
109        }
110        nameMap.remove(name);
111    }
112
113    public void removeObject(Serializable object) {
114        objectMap.remove(object.getUniqueId());
115    }
116   
117    public void removeObject(long id) {
118        objectMap.remove(id);
119    }
120   
121    public void save() {
122        Vector objectData = new Vector();
123
124        byte[] byteArray;
125        Enumeration e = objectMap.elements();
126        while (e.hasMoreElements()) {
127            try {
128                byteArray = SerializationUtils.serializeClass((Serializable)e.nextElement());
129                objectData.addElement(byteArray);
130            } catch (Exception exp) { }
131        }
132
133        PersistentObjectDataStoreContainer container = new PersistentObjectDataStoreContainer();
134        container.setElement(PersistentObjectDataStoreContainer.FIELD_NAME_MAP, nameMap);
135        container.setElement(PersistentObjectDataStoreContainer.FIELD_OBJECT_DATA, objectData);
136
137        synchronized(store) {
138            store.setContents(container);
139            store.commit();
140        }
141    }
142
143    public void load() {
144        ToLongHashtable newNameMap = null;
145        Vector newObjects = null;
146        synchronized(store) {
147            Object storeData = store.getContents();
148            if(storeData instanceof PersistentObjectDataStoreContainer) {
149                PersistentObjectDataStoreContainer container = (PersistentObjectDataStoreContainer)storeData;
150                Object nameMapValue = container.getElement(PersistentObjectDataStoreContainer.FIELD_NAME_MAP);
151                Object objectDataValue = container.getElement(PersistentObjectDataStoreContainer.FIELD_OBJECT_DATA);
152                if(nameMapValue instanceof ToLongHashtable && objectDataValue instanceof Vector) {
153                    newNameMap = (ToLongHashtable)nameMapValue;
154                    newObjects = (Vector)objectDataValue;
155                }
156            }
157            else if(storeData instanceof Object[]) {
158                Object[] storeArray = (Object[])storeData;
159                if(storeArray != null && storeArray.length == 2
160                        && storeArray[0] instanceof ToLongHashtable
161                        && storeArray[1] instanceof Vector) {
162                    newNameMap = (ToLongHashtable)storeArray[0];
163                    newObjects = (Vector)storeArray[1];
164                }
165            }
166        }
167        if(newNameMap != null && newObjects != null) {
168            nameMap = newNameMap;
169            Object deserializedObject;
170            int size = newObjects.size();
171            for(int i=0; i<size; i++) {
172                try {
173                    deserializedObject = SerializationUtils.deserializeClass((byte[])newObjects.elementAt(i));
174                    if(deserializedObject != null) {
175                        objectMap.put(
176                                ((Serializable)deserializedObject).getUniqueId(),
177                                deserializedObject);
178                    }
179                } catch (Exception exp) { }
180            }
181        }
182    }
183
184    public void delete() {
185        PersistentStore.destroyPersistentObject(storeUid);
186    }
187
188    public int getSyncObjectUID() {
189        return (int)storeUid;
190    }
191   
192    public DataStoreSyncObject getSyncObject() {
193        DataStoreSyncObject syncObject = new DataStoreSyncObject((int)storeUid);
194       
195        Object storeData = store.getContents();
196        if(storeData instanceof PersistentObjectDataStoreContainer) {
197            PersistentObjectDataStoreContainer container = (PersistentObjectDataStoreContainer)storeData;
198            Object nameMapValue = container.getElement(PersistentObjectDataStoreContainer.FIELD_NAME_MAP);
199            Object objectDataValue = container.getElement(PersistentObjectDataStoreContainer.FIELD_OBJECT_DATA);
200            if(nameMapValue instanceof ToLongHashtable && objectDataValue instanceof Vector) {
201                syncObject.setNameMap((ToLongHashtable)nameMapValue);
202                syncObject.setObjectData((Vector)objectDataValue);
203            }
204            else {
205                syncObject.setNameMap(new ToLongHashtable());
206                syncObject.setObjectData(new Vector());
207            }
208        }
209        else if(storeData instanceof Object[]) {
210            Object[] storeArray = (Object[])storeData;
211            if(storeArray != null && storeArray.length == 2
212                    && storeArray[0] instanceof ToLongHashtable
213                    && storeArray[1] instanceof Vector) {
214                syncObject.setNameMap((ToLongHashtable)storeArray[0]);
215                syncObject.setObjectData((Vector)storeArray[1]);
216            }
217            else {
218                syncObject.setNameMap(new ToLongHashtable());
219                syncObject.setObjectData(new Vector());
220            }
221        }
222        else {
223            syncObject.setNameMap(new ToLongHashtable());
224            syncObject.setObjectData(new Vector());
225        }
226        return syncObject;
227    }
228
229    public boolean setSyncObject(DataStoreSyncObject syncObject) {
230        // Extra sanity checking to avoid populating from invalid data
231        if(syncObject == null
232                || syncObject.getUID() != (int)storeUid
233                || syncObject.getNameMap() == null
234                || syncObject.getObjectData() == null) {
235            return false;
236        }
237       
238        PersistentObjectDataStoreContainer container = new PersistentObjectDataStoreContainer();
239        container.setElement(PersistentObjectDataStoreContainer.FIELD_NAME_MAP, syncObject.getNameMap());
240        container.setElement(PersistentObjectDataStoreContainer.FIELD_OBJECT_DATA, syncObject.getObjectData());
241       
242        store.setContents(container);
243        store.commit();
244        return true;
245    }
246}
Note: See TracBrowser for help on using the repository browser.