KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > sync4j > syncclient > sps > palm > PalmDataStore


1 /**
2  * Copyright (C) 2003-2005 Funambol
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18
19 package sync4j.syncclient.sps.palm;
20
21 import java.io.IOException JavaDoc;
22 import java.util.Date JavaDoc;
23 import java.util.Hashtable JavaDoc;
24 import java.util.Vector JavaDoc;
25
26 import sync4j.syncclient.common.logging.Logger;
27
28 import sync4j.syncclient.sps.common.DataAccessException;
29 import sync4j.syncclient.sps.common.DataStore;
30 import sync4j.syncclient.sps.common.Record;
31 import sync4j.syncclient.sps.common.RecordFilter;
32 import sync4j.syncclient.sps.common.RecordMetadata;
33 import sync4j.syncclient.spds.SyncRecordFunction;
34
35 import palm.conduit.SyncException;
36 import palm.conduit.SyncManager;
37
38 /**
39  * This class create implementation of Palm DataStore
40  * and provide method to operate about record
41  *
42  * @author Fabio Maggi @ Funambol
43  * $Id: PalmDataStore.java,v 1.7 2005/01/19 11:18:37 fabius Exp $
44  */

45
46 public class PalmDataStore extends DataStore {
47
48     private Vector JavaDoc palmDB = null ;
49     private boolean dataStoreChanged = false ;
50
51     private Logger logger = new Logger();
52
53     //----------------------------------------------------------- Costructors
54

55     public PalmDataStore(String JavaDoc dataStoreName, RecordMetadata recordMetadata) {
56         super(dataStoreName, recordMetadata);
57     }
58
59     //----------------------------------------------------------- Public methods
60

61     /**
62      * create record
63      *
64      * @param key
65      * @return record
66      **/

67     public Record newRecord(String JavaDoc key) {
68
69         Record record = null;
70         record = new Record(this, key);
71         return record;
72
73     }
74
75     /**
76      * read record
77      * @param record
78      * @throws DataAccessException
79      **/

80     public Record readRecord(Record record)
81     throws DataAccessException {
82
83         try {
84
85             int l = palmDB.size();
86
87             for (int i=0; i < l; i++) {
88
89                 if(((Record)palmDB.elementAt(i)).getKey().equals(record.getKey())) {
90                     return (Record)palmDB.elementAt(i);
91                 }
92             }
93
94         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
95             throw new DataAccessException(e.getMessage());
96         }
97
98         return record;
99
100     }
101
102     /**
103      * store record
104      * @param record
105      * @return stored Record
106      * @throws DataAccessException
107      **/

108     public Record storeRecord(Record record)
109     throws DataAccessException {
110
111         boolean findRecord = false;
112
113         dataStoreChanged = true;
114
115         int i=0;
116
117         try {
118
119             int l = palmDB.size();
120
121             for (i=0; i < l; i++) {
122
123                 if(((Record)palmDB.elementAt(i)).getKey().equals(record.getKey())) {
124                     findRecord = true;
125                     break;
126                 }
127
128             }
129
130             if(findRecord) {
131                 palmDB.setElementAt((Object JavaDoc) record, i);
132             } else {
133
134                //
135
//enable this code to key generate by client
136
//String key = String.valueOf(getNextKey());
137
//record.setKey(key);
138
//
139

140                palmDB.addElement((Object JavaDoc) record);
141             }
142
143         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
144             throw new DataAccessException(e.getMessage());
145         }
146
147         return record;
148
149     }
150
151     /**
152      * delete record
153      * @param record
154      * @throws DataAccessException
155      **/

156     public void deleteRecord(Record record)
157     throws DataAccessException {
158         dataStoreChanged = true;
159
160         try {
161
162             int l = palmDB.size();
163
164             for (int i=0; i < l; i++) {
165
166                 if(((Record)palmDB.elementAt(i)).getKey().equals(record.getKey())) {
167                     palmDB.removeElementAt(i);
168                     break;
169                 }
170             }
171
172
173         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
174             throw new DataAccessException(e.getMessage());
175         }
176
177         return;
178
179     }
180
181     /**
182      * return alla records of device
183      *
184      * @return find records
185      * @throws DataAccessException
186      **/

187     public Vector JavaDoc initFindAllRecords() throws DataAccessException {
188
189         Vector JavaDoc records = new Vector JavaDoc();
190
191         String JavaDoc dbName = null;
192
193         int countHHRecords = 0;
194
195         int db = 0;
196
197         boolean findRecord = false;
198
199         Record record = null;
200
201         PalmRecord palmRecord = new PalmRecord();
202
203         dbName = this.getDataStoreName();
204
205         boolean createDB = false;
206
207         //
208
// Check if exist Palm DB
209
//
210
try {
211             db = SyncManager.openDB(dbName, 0, SyncManager.OPEN_READ |
212                                                SyncManager.OPEN_WRITE |
213                                                SyncManager.OPEN_EXCLUSIVE );
214             SyncManager.closeDB(db);
215         } catch (SyncException e) {
216             createDB=true;
217         }
218
219         //
220
// Create Palm DB (if not exist)
221
//
222
if (createDB) {
223
224             try {
225                 db = SyncManager.
226                         createDB(asciiStringToInt((String JavaDoc) this.
227                                         getDataStoreProperties().get("creatorId")), 0x0,
228                      (short)0, dbName, asciiStringToInt((String JavaDoc) this.
229                                 getDataStoreProperties().get("dataStoreType")));
230                 if (logger.isLoggable(Logger.DEBUG)) {
231                     logger.debug("Creating DataStore: " + dbName);
232                 }
233
234             } catch (SyncException e) {
235                 throw new DataAccessException("Error at init, creating DB " +
236                                               dbName +
237                                               ": " +
238                                               e.getMessage() );
239
240             } catch (NumberFormatException JavaDoc e) {
241                 throw new DataAccessException("Error at init, number conversion error " +
242                                               dbName +
243                                               ": " +
244                                               e.getMessage() );
245             } finally {
246                 try {
247                     SyncManager.closeDB(db);
248                 } catch (SyncException e) {
249                     throw new DataAccessException("Error at init, closing DB " +
250                                                   dbName +
251                                                   ": " +
252                                                   e.getMessage() );
253                 }
254             }
255
256         }
257
258
259         try {
260
261             //
262
// Open Palm DB
263
//
264
try {
265                 db = SyncManager.openDB(dbName, 0, SyncManager.OPEN_READ |
266                                                    SyncManager.OPEN_WRITE |
267                                                    SyncManager.OPEN_EXCLUSIVE );
268             } catch (palm.conduit.SyncException e) {
269                 throw new DataAccessException("Error at init, openening DB " +
270                                               dbName +
271                                               ": " +
272                                               e.getMessage() );
273             }
274
275             try {
276                 countHHRecords = SyncManager.getDBRecordCount(db);
277             } catch(IOException JavaDoc e) {
278                 throw new
279                     DataAccessException("Error at init, recordCount not received: " +
280                                         e.getMessage() );
281             }
282
283             for (int recordIndex=0; recordIndex < countHHRecords; recordIndex++) {
284
285                 palmRecord = new PalmRecord();
286
287                 palmRecord.setIndex(recordIndex);
288
289                 //
290
//in PalmRecord key set in dedicate field
291
//in Record key set at the first position of array
292
//
293
palmRecord.setRecordSize(this.getRecordMetadata().
294                                             getFieldMetadata().length - 1);
295
296                 try {
297                     SyncManager.readRecordByIndex(db, palmRecord);
298                 } catch(IOException JavaDoc e) {
299                     throw new DataAccessException("Error, record at position: " +
300                                                   recordIndex +
301                                                   " not loaded: " +
302                                                   e.getMessage() );
303                 }
304
305                 record = new Record(this, (String JavaDoc) palmRecord.getKey());
306
307                 int l = palmRecord.getSize();
308
309                 for (int i=0; i < l; i++) {
310                     record.setField(i+2, (String JavaDoc) palmRecord.getStoreField(i));
311                 }
312
313                 records.addElement(record);
314                 record = null ;
315                 palmRecord = null ;
316
317
318             }
319
320         } finally {
321              try {
322                 SyncManager.closeDB(db);
323              } catch (palm.conduit.SyncException e) {
324                 throw new DataAccessException("Error at init, closing DB " +
325                                               dbName +
326                                               ": " +
327                                               e.getMessage() );
328              }
329         }
330
331         return records;
332
333     }
334
335
336     /**
337      * return all records of device stored in memory
338      *
339      * @return find records
340      **/

341     public Vector JavaDoc findAllRecords() {
342
343         return palmDB;
344     }
345
346
347     /**
348      * return a Vector of Records
349      * found by state
350      *
351      * @param state state of record
352      * @param since last timestamp
353      * @return find records
354      * @throws DataAccessException
355      **/

356     public Vector JavaDoc findRecords(char state, Date JavaDoc since)
357     throws DataAccessException {
358
359         Vector JavaDoc findRecords = new Vector JavaDoc();
360
361         try {
362
363             int l = palmDB.size();
364
365             for(int i=0; i < l; i++) {
366
367                 if (String.valueOf(state).equals(SyncRecordFunction.
368                         getModificationType((Record) palmDB.elementAt(i)))) {
369                     findRecords.addElement(palmDB.elementAt(i));
370                 }
371
372             }
373
374         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
375             throw new DataAccessException(e.getMessage());
376         }
377
378         return findRecords;
379
380     }
381
382
383     /**
384      * return records of dataStore find by RecordFilter
385      *
386      * @param recordFilter filter
387      * @return find records
388      * @throws DataAccessException
389      **/

390     public Vector JavaDoc findRecords(RecordFilter recordFilter)
391     throws DataAccessException {
392
393         Vector JavaDoc allRecords = null;
394         Vector JavaDoc findRecords = new Vector JavaDoc();
395
396
397         Record record = null;
398
399         allRecords = this.findAllRecords();
400
401         try {
402
403             int l = allRecords.size();
404
405             for(int i=0; i < l; i++) {
406
407                 record = this.readRecord((Record) allRecords.elementAt(i));
408
409                 if(recordFilter.accept(record)) {
410                     findRecords.addElement(allRecords.elementAt(i));
411                 }
412             }
413
414         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
415             throw new DataAccessException(e.getMessage());
416         }
417
418         return findRecords;
419
420     }
421
422
423     /**
424      * return next key on device
425      * 1000 if no record exist
426      *
427      * @return key
428      **/

429     public long getNextKey() {
430
431         String JavaDoc function = null;
432         String JavaDoc nameFieldKey = null;
433
434         long recordKey = 0;
435         long key = 0;
436
437         //
438
//for future implementation about key-field position
439
//
440

441         int l = this.getRecordMetadata().getFieldMetadata().length;
442
443         for (int i=0; i < l; i++) {
444
445             function = (String JavaDoc) this.getRecordMetadata().
446                             getFieldMetadata()[i].getAttributes().get("function");
447
448             if (function.equals("key")) {
449                 nameFieldKey = this.getRecordMetadata().getFieldMetadata()[i].getName();
450             }
451
452         }
453
454
455         l = palmDB.size();
456
457         if (l != 0) {
458
459             for (int i=0; i < l; i++) {
460
461                 recordKey = Long.parseLong(((Record) palmDB.elementAt(i)).getKey());
462
463                 if (recordKey > key) {
464                     key = recordKey;
465                 }
466
467             }
468
469             key = key + 1;
470
471         } else {
472
473             //
474
//key about no record in table
475
//
476
key = 1000;
477         }
478
479         return key;
480
481     }
482
483
484     /**
485      * Method define start DB operathions
486      * @throws DataAccessException
487      */

488     public void startDBOperations()
489     throws DataAccessException {
490
491         palmDB = initFindAllRecords();
492
493     }
494
495
496     /**
497      * Method define end DB operathions
498      * @throws DataAccessException
499      */

500     public void commitDBOperations()
501     throws DataAccessException {
502
503         int db = 0;
504
505         String JavaDoc dbName = null;
506
507         Vector JavaDoc palmRecords = null;
508
509         PalmRecord palmRecord = null;
510
511         Record record = null;
512
513         //
514
// dataStoreChanged tells us when anything changed at server side. If no
515
// changes are detected from the server, we have to check if changes
516
// where made locally. To do so, we check the record status flag
517
//
518
if (!dataStoreChanged) {
519             char state;
520             int l = palmDB.size();
521             for (int i=0; i < l; ++i) {
522                 record = (Record) palmDB.elementAt(i);
523                 state = SyncRecordFunction.getModificationType(record).charAt(0);
524                 if (state != 'S') {
525                     dataStoreChanged = true;
526                     break;
527                 }
528             }
529             if (!dataStoreChanged) {
530                 // still not changed: nothing to do
531
return;
532             }
533         }
534
535         palmRecords = new Vector JavaDoc();
536
537         int l = palmDB.size();
538
539         for (int i=0; i < l; i++) {
540
541             record = (Record) palmDB.elementAt(i);
542
543             if (!"D".equals(SyncRecordFunction.getModificationType(record))) {
544                 SyncRecordFunction.setModificationType(record, "S");
545
546                 palmRecord = new PalmRecord();
547
548                 palmRecord.setKey(record.getKey());
549
550                 for (int j=2; j <= record.getLength(); j++) {
551                     palmRecord.addStoreField(record.getString(j));
552                 }
553
554                 palmRecords.addElement(palmRecord);
555             }
556
557         }
558
559         dbName = this.getDataStoreName();
560
561         try {
562             //
563
// Open Palm DB
564
//
565
try {
566                 db = SyncManager.openDB(dbName, 0, SyncManager.OPEN_READ |
567                                                    SyncManager.OPEN_WRITE |
568                                                    SyncManager.OPEN_EXCLUSIVE );
569             } catch (palm.conduit.SyncException e) {
570                 throw new DataAccessException("Error at commit, opening DB " +
571                                               dbName +
572                                               ": " +
573                                               e.getMessage() );
574             }
575
576             try {
577                 SyncManager.purgeAllRecs(db);
578             } catch(SyncException e) {
579                 throw new
580                     DataAccessException("Error at commit, all records not purged: " +
581                                         e.getMessage() );
582             }
583
584             l = palmRecords.size();
585
586             for(int i = 0; i < l; i++){
587                 palmRecord = (PalmRecord) palmRecords.elementAt(i);
588                 palmRecord.setId(0);
589                 palmRecord.setIndex(0);
590
591                 try {
592                     SyncManager.writeRec(db, palmRecord);
593                 } catch(IOException JavaDoc e) {
594                     throw new
595                         DataAccessException("Error at commit, record not written: " +
596                                             e.getMessage() );
597                 }
598             }
599
600             try {
601                 //
602
//deletes all hh records marked as deleted
603
//
604
SyncManager.purgeDeletedRecs(db);
605             } catch(SyncException e) {
606                 throw new
607                     DataAccessException("Error at commit, deleted records not purged: " +
608                     e.getMessage() );
609             }
610
611             try {
612                 //
613
//reset all the sync flags on the hh
614
//
615
SyncManager.resetSyncFlags(db);
616             } catch(SyncException e) {
617                 throw new
618                     DataAccessException("Error at commit, flags not reset: " +
619                     e.getMessage() );
620             }
621
622         } finally {
623             try {
624                 palmRecords = null;
625                 SyncManager.closeDB(db);
626             } catch (palm.conduit.SyncException e) {
627                 throw new
628                     DataAccessException("Error at commit, closing " +
629                                         dbName +
630                                         ": " +
631                                         e.getMessage() );
632             }
633         }
634
635         return;
636
637     }
638
639
640     //----------------------------------------------------------- Private methods
641

642     /**
643      * Convert ascii string to int value
644      *
645      * @param asciiValue value to convert
646      * @return converted value
647      * @throws NumberFormatException
648      *
649      */

650     private int asciiStringToInt (String JavaDoc asciiValue)
651         throws NumberFormatException JavaDoc {
652
653         int intValue = 0;
654
655         String JavaDoc hexValue = null;
656
657         hexValue = "";
658
659         int l = asciiValue.length();
660
661         for (int i=0; i < l; i++) {
662             hexValue += Integer.toHexString((new Character JavaDoc(asciiValue.charAt(i))).hashCode());
663         }
664
665         intValue = Integer.parseInt(hexValue, 16);
666
667         return intValue;
668
669     }
670
671 }
Popular Tags