KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > sync4j > server > store > EnginePersistentStore


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.server.store;
20
21 import java.util.ArrayList JavaDoc;
22
23 import java.sql.*;
24
25 import sync4j.server.engine.Sync4jSource;
26
27 import sync4j.framework.tools.DBTools;
28 import sync4j.framework.tools.Base64;
29 import sync4j.framework.engine.dm.DeviceDMState;
30 import sync4j.framework.server.store.*;
31 import sync4j.framework.server.Sync4jDevice;
32 import sync4j.framework.security.Sync4jPrincipal;
33
34 /**
35  * This is the store for information regarding the Sync4j engine such as users,
36  * principals, ecc. Currently it persistes the following classes:
37  *
38  * <ul>
39  * <li>sync4j.framework.security.Sync4jPrincipal</li>
40  * </ul>
41  *
42  *
43  * @author Stefano Fornari @ Funambol
44  *
45  * @version $Id: EnginePersistentStore.java,v 1.1 2005/05/16 17:32:57 nichele Exp $
46  *
47  */

48 public class EnginePersistentStore
49 extends BasePersistentStore
50 implements PersistentStore, java.io.Serializable JavaDoc {
51
52     // --------------------------------------------------------------- Constants
53

54     private static final String JavaDoc OPT_INSERT = "INSERT";
55
56     public static final byte SQL_INSERT_PRINCIPAL = 0;
57     public static final byte SQL_GET_PRINCIPAL = 1;
58     public static final byte SQL_SELECT_PRINCIPAL = 2;
59     public static final byte SQL_UPDATE_PRINCIPAL = 3;
60     public static final byte SQL_SELECT_ALL_PRINCIPALS = 4;
61     public static final byte SQL_INSERT_SOURCE = 5;
62     public static final byte SQL_GET_SOURCE = 6;
63     public static final byte SQL_UPDATE_SOURCE = 7;
64     public static final byte SQL_SELECT_ALL_SOURCES = 8;
65     public static final byte SQL_SELECT_ALL_DEVICES = 9;
66     public static final byte SQL_GET_DEVICE = 10;
67     public static final byte SQL_INSERT_DEVICE = 11;
68     public static final byte SQL_UPDATE_DEVICE = 12;
69     public static final byte SQL_DELETE_DEVICE = 13;
70     public static final byte SQL_DELETE_DEVICE_PRINCIPAL = 14;
71     public static final byte SQL_DELETE_PRINCIPAL = 15;
72     public static final byte SQL_DELETE_CLIENT_MAPPING = 16;
73     public static final byte SQL_DELETE_LAST_SYNC = 17;
74     public static final byte SQL_GET_COUNTER = 18;
75     public static final byte SQL_UPDATE_COUNTER = 19;
76     public static final byte SQL_DELETE_SOURCE = 20;
77     public static final byte SQL_INSERT_SYNCSOURCE = 21;
78     public static final byte SQL_UPDATE_SYNCSOURCE = 22;
79     public static final byte SQL_DELETE_SOURCE_CLIENT_MAPPING = 23;
80     public static final byte SQL_DELETE_SOURCE_LAST_SYNC = 24;
81     public static final byte SQL_COUNT_DEVICES = 25;
82     public static final byte SQL_COUNT_PRINCIPALS = 26;
83     public static final byte SQL_GET_DEVICE_DM_STATE = 27;
84     public static final byte SQL_UPDATE_DEVICE_DM_STATE = 28;
85     public static final byte SQL_INSERT_DEVICE_DM_STATE = 29;
86     public static final byte SQL_DELETE_DEVICE_DM_STATE = 30;
87     public static final byte SQL_SELECT_ALL_DM_STATE = 31;
88
89     public static final String JavaDoc NS_PRINCIPAL = "principal";
90     public static final String JavaDoc NS_DEVICE = "device" ;
91     public static final String JavaDoc NS_DM_STATE = "dmstate" ;
92
93     // -------------------------------------------------------------- Properties
94

95     private String JavaDoc[] sql = null;
96
97     public void setSql(String JavaDoc[] sql) {
98         this.sql = sql;
99     }
100
101     public String JavaDoc[] getSql() {
102         return this.sql;
103     }
104
105     // ------------------------------------------------------------ Private data
106
private static final String JavaDoc SEARCH_COUNT_DEVICES = "SCD";
107     private static final String JavaDoc SEARCH_COUNT_PRINCIPALS = "SCP";
108
109     // ------------------------------------------------------------ Constructors
110

111     // ---------------------------------------------------------- Public methods
112

113     public boolean delete(Object JavaDoc o)
114     throws PersistentStoreException {
115         if (o instanceof Sync4jDevice) {
116             deleteDevice((Sync4jDevice) o);
117             return true;
118         } else if (o instanceof Sync4jPrincipal) {
119             deletePrincipal((Sync4jPrincipal) o);
120             return true;
121         } else if (o instanceof Sync4jSource) {
122             deleteSource((Sync4jSource) o);
123             return true;
124         } else if (o instanceof DeviceDMState) {
125             deleteDeviceDMState((DeviceDMState) o);
126             return true;
127         }
128
129         return false;
130     }
131
132     public boolean store(String JavaDoc id, Object JavaDoc o, String JavaDoc operation) throws PersistentStoreException {
133         if (o instanceof Sync4jSource) {
134             if (operation.equals(OPT_INSERT)) {
135                 insertSyncSource(id, (Sync4jSource)o);
136             } else {
137                 updateSyncSource(id, (Sync4jSource)o);
138             }
139             return true;
140         }
141
142         return false;
143     }
144
145     public boolean store(Object JavaDoc o)
146     throws PersistentStoreException {
147         if (o instanceof Sync4jPrincipal) {
148             storePrincipal((Sync4jPrincipal)o);
149             return true;
150         } else if (o instanceof Sync4jSource) {
151             storeSource((Sync4jSource)o);
152             return true;
153         } else if (o instanceof Sync4jDevice) {
154             storeDevice((Sync4jDevice)o);
155             return true;
156         } else if (o instanceof DeviceDMState) {
157             storeDeviceDMState((DeviceDMState)o);
158             return true;
159         }
160
161         return false;
162     }
163
164     public boolean read(Object JavaDoc o)
165     throws PersistentStoreException {
166         if (o instanceof Sync4jPrincipal) {
167             readPrincipal((Sync4jPrincipal) o);
168             return true;
169         } else if (o instanceof Sync4jSource) {
170             readSource((Sync4jSource) o);
171             return true;
172         } else if (o instanceof Sync4jDevice) {
173             readDevice((Sync4jDevice) o);
174             return true;
175         } else if (o instanceof DeviceDMState) {
176             readDeviceDMState((DeviceDMState)o);
177             return true;
178         }
179
180         return false;
181     }
182
183     public Object JavaDoc[] read(Class JavaDoc objClass) throws PersistentStoreException {
184         if (objClass.equals(Sync4jSource.class)) {
185             return readAllSources();
186         }
187
188         return null;
189     }
190
191     /**
192      * Read all informations
193      * @param object whichever object Sync
194      * @param clause condition where for select
195      *
196      * @return Object[] array of object
197      */

198     public Object JavaDoc[] read(Object JavaDoc o, Clause clause) throws PersistentStoreException {
199         if (o instanceof Sync4jPrincipal) {
200             return readAllPrincipals(clause);
201         } else if (o instanceof Sync4jDevice) {
202             return readAllDevices(clause);
203         } else if (o instanceof String JavaDoc) {
204             if (o.equals(SEARCH_COUNT_DEVICES)) {
205                 return readCountDevices(clause);
206             } else if (o.equals(SEARCH_COUNT_PRINCIPALS)) {
207                 return readCountPrincipals(clause);
208             }
209         } else if (o instanceof Sync4jSource) {
210             return readSource((Sync4jSource)o, clause);
211         } else if (o instanceof DeviceDMState) {
212             return readDeviceDMState(clause);
213         }
214
215         return null;
216     }
217
218     // --------------------------------------------------------- Private methods
219

220
221     // -------------------------------------------------------------------------
222
// Sync4jPricipal
223
// -------------------------------------------------------------------------
224

225     private void storePrincipal(Sync4jPrincipal p)
226     throws PersistentStoreException {
227         Connection conn = null;
228         PreparedStatement stmt = null;
229         ResultSet rs = null;
230         int n = 0;
231
232         try {
233             conn = dataSource.getConnection();
234
235             if (p.getId() != null && !p.getId().equals("")) {
236
237                 stmt = conn.prepareStatement(sql[SQL_UPDATE_PRINCIPAL]);
238
239                 stmt.setString(1, p.getUsername());
240                 stmt.setString(2, p.getDeviceId());
241                 stmt.setString(3, p.getId() );
242
243                 n = stmt.executeUpdate();
244
245                 stmt.close();
246             } else {
247                 //check if the principal already exist: verify username-deviceid
248

249                 stmt = conn.prepareStatement(sql[SQL_SELECT_PRINCIPAL]);
250
251                 stmt.setString(1, p.getUsername());
252                 stmt.setString(2, p.getDeviceId());
253
254                 rs = stmt.executeQuery();
255
256                 if (rs.next() == false) {
257
258                     n = 0;
259
260                 } else {
261
262                     n = 1;
263
264                     p.setId (rs.getString(1));
265                     p.setUsername (rs.getString(2));
266                     p.setDeviceId (rs.getString(3));
267                     p.setEmail (rs.getString(4));
268                     p.setFirstName(rs.getString(5));
269                     p.setLastName (rs.getString(6));
270                 }
271
272                 stmt.close();
273                 rs.close();
274             }
275
276             if (n == 0) {
277                 //
278
// The first time!!!
279
//
280

281                 int principalId = this.readCounter(NS_PRINCIPAL);
282                 p.setId("" + principalId);
283
284                 stmt = conn.prepareStatement(sql[SQL_INSERT_PRINCIPAL]);
285
286                 stmt.setString(1, p.getId() );
287                 stmt.setString(2, p.getUsername());
288                 stmt.setString(3, p.getDeviceId());
289
290                 stmt.executeUpdate();
291             }
292         } catch (SQLException e) {
293             throw new PersistentStoreException("Error storing principal " + p, e);
294         } finally {
295             DBTools.close(conn, stmt, rs);
296         }
297     }
298
299     /**
300      * Read the principal from the data store. If <i>getId()</i> returns null,
301      * it tries to read the principal from username/device, otherwise throws id
302      * is used for the lookup.
303      *
304      * @throws PersistentException in case of error reading the data store
305      */

306     private void readPrincipal(Sync4jPrincipal p)
307     throws PersistentStoreException {
308         Connection conn = null;
309         PreparedStatement stmt = null;
310         ResultSet rs = null;
311
312         try {
313             conn = dataSource.getConnection();
314
315             if (p.getId() == null) {
316
317                 stmt = conn.prepareStatement(sql[SQL_SELECT_PRINCIPAL]);
318
319                 stmt.setString(1, p.getUsername());
320                 stmt.setString(2, p.getDeviceId());
321             } else {
322
323                 stmt = conn.prepareStatement(sql[SQL_GET_PRINCIPAL]);
324
325                 stmt.setString(1, p.getId());
326             }
327
328             rs = stmt.executeQuery();
329
330             if (rs.next() == false) {
331                 throw new NotFoundException("Principal not found for "
332                 + p.toString()
333                 );
334             }
335
336             p.setId (rs.getString(1));
337             p.setUsername (rs.getString(2));
338             p.setDeviceId (rs.getString(3));
339             p.setEmail (rs.getString(4));
340             p.setFirstName(rs.getString(5));
341             p.setLastName (rs.getString(6));
342         } catch (SQLException e) {
343             throw new PersistentStoreException("Error reading principal " + p, e);
344         } finally {
345             DBTools.close(conn, stmt, rs);
346         }
347     }
348
349     /**
350      * Read all principals
351      *
352      * @return an array with the principals (empty if no objects are found)
353      *
354      * @throws PersistentException in case of error reading the data store
355      */

356     private Object JavaDoc[] readAllPrincipals(Clause clause)
357     throws PersistentStoreException {
358         Connection conn = null;
359         PreparedStatement stmt = null;
360         ResultSet rs = null;
361
362         ArrayList JavaDoc ret = new ArrayList JavaDoc();
363
364         try {
365             conn = dataSource.getConnection();
366
367             PreparedWhere where = clause.getPreparedWhere();
368
369             String JavaDoc query = sql[SQL_SELECT_ALL_PRINCIPALS];
370             if (where.sql.length() > 0){
371                 query += " where " + where.sql;
372             }
373
374             stmt = conn.prepareStatement(query);
375
376             for (int i=0; i<where.parameters.length; ++i) {
377                 stmt.setObject(i+1, where.parameters[i]);
378             }
379
380             rs = stmt.executeQuery();
381
382             while (rs.next()) {
383                 ret.add(
384                     new Sync4jPrincipal(
385                         rs.getString(1),
386                         rs.getString(2),
387                         rs.getString(3)
388                     )
389                 );
390             }
391
392             return ret.toArray(new Sync4jPrincipal[ret.size()]);
393         } catch (SQLException e) {
394             throw new PersistentStoreException("Error reading principals", e);
395         } finally {
396             DBTools.close(conn, stmt, rs);
397         }
398     }
399
400
401     /**
402      * Delete the principal from the data store.
403      *
404      * @param p the principal
405      *
406      * @throws PersistentException in case of error reading the data store
407      */

408     private void deletePrincipal(Sync4jPrincipal p)
409     throws PersistentStoreException {
410         Connection conn = null;
411         PreparedStatement stmt = null;
412
413         try {
414             conn = dataSource.getConnection();
415
416             stmt = conn.prepareStatement(sql[SQL_DELETE_CLIENT_MAPPING]);
417
418             stmt.setString(1, p.getId());
419
420             stmt.executeUpdate();
421
422             stmt.close();
423             stmt = conn.prepareStatement(sql[SQL_DELETE_LAST_SYNC]);
424
425             stmt.setString(1, p.getId());
426
427             stmt.executeUpdate();
428
429             stmt.close();
430             stmt = conn.prepareStatement(sql[SQL_DELETE_PRINCIPAL]);
431
432             stmt.setString(1, p.getId());
433
434             stmt.executeUpdate();
435
436
437         } catch (SQLException e) {
438             throw new PersistentStoreException("Error deleting the principal " + p, e);
439         } finally {
440             DBTools.close(conn, stmt, null);
441         }
442     }
443
444     /**
445      * Select the number of principals that satisfy the conditions specified in input
446      *
447      * @return int number of principals
448      */

449     public Object JavaDoc[] readCountPrincipals(Clause clause) throws PersistentStoreException {
450         Connection conn = null;
451         PreparedStatement stmt = null;
452         ResultSet rs = null;
453         int n = 0;
454
455         try {
456             conn = dataSource.getConnection();
457
458             PreparedWhere where = clause.getPreparedWhere();
459
460             String JavaDoc query = sql[SQL_COUNT_PRINCIPALS];
461
462             if (where.sql.length()>0) {
463                 query += " where " + where.sql;
464             }
465
466             stmt = conn.prepareStatement(query);
467
468             for (int i=0; i<where.parameters.length; ++i) {
469                 stmt.setObject(i+1, where.parameters[i]);
470             }
471
472             rs = stmt.executeQuery();
473             while (rs.next()) {
474                 n = rs.getInt(1);
475             }
476
477             String JavaDoc[] s = new String JavaDoc[1];
478             s[0] = "" + n;
479             return s;
480
481         } catch (SQLException e) {
482             throw new PersistentStoreException("Error reading count principals ", e);
483         } finally {
484             DBTools.close(conn, stmt, rs);
485         }
486     }
487
488     // -------------------------------------------------------------------------
489
// Sync4jDevice
490
// -------------------------------------------------------------------------
491

492     private Object JavaDoc[] readAllDevices(Clause clause)
493     throws PersistentStoreException {
494         Connection conn = null;
495         PreparedStatement stmt = null;
496         ResultSet rs = null;
497
498         ArrayList JavaDoc ret = new ArrayList JavaDoc();
499
500         try {
501             conn = dataSource.getConnection();
502
503             PreparedWhere where = clause.getPreparedWhere();
504
505             String JavaDoc query = sql[SQL_SELECT_ALL_DEVICES];
506             if (where.sql.length() > 0) {
507                 query += " where " + where.sql;
508             }
509
510             stmt = conn.prepareStatement(query);
511
512             for (int i=0; i<where.parameters.length; ++i) {
513                 stmt.setObject(i+1, where.parameters[i]);
514             }
515
516             rs = stmt.executeQuery();
517
518             while (rs.next()) {
519                 ret.add(
520                     new Sync4jDevice(
521                         rs.getString(1),
522                         rs.getString(2),
523                         rs.getString(3)
524                     )
525                 );
526             }
527
528             return ret.toArray(new Sync4jDevice[ret.size()]);
529         } catch (SQLException e) {
530             throw new PersistentStoreException("Error reading devices", e);
531         } finally {
532             DBTools.close(conn, stmt, rs);
533         }
534     }
535
536     /**
537      * Read the device from the data store.
538      *
539      * @param d the device
540      *
541      * @throws PersistentException in case of error reading the data store
542      */

543     private void readDevice(Sync4jDevice d)
544     throws PersistentStoreException {
545         Connection conn = null;
546         PreparedStatement stmt = null;
547         ResultSet rs = null;
548
549         String JavaDoc value;
550         try {
551             conn = dataSource.getConnection();
552
553             stmt = conn.prepareStatement(sql[SQL_GET_DEVICE]);
554             stmt.setString(1, d.getDeviceId());
555
556             rs = stmt.executeQuery();
557
558             if (rs.next() == false) {
559                 throw new NotFoundException("Device not found for "
560                 + d.getDeviceId()
561                 );
562             }
563
564             d.setDescription(rs.getString(1));
565             d.setType (rs.getString(2));
566             d.setDigest (rs.getString(3));
567             value = rs.getString(4);
568             if (value == null) {
569                 d.setClientNonce(null);
570             } else if (value.equals("")) {
571                 d.setClientNonce(new byte[0]);
572             } else {
573                 d.setClientNonce(Base64.decode(value.getBytes()));
574             }
575
576             value = rs.getString(5);
577             if (value == null) {
578                 d.setServerNonce(null);
579             } else if (value.equals("")) {
580                 d.setServerNonce(new byte[0]);
581             } else {
582                 d.setServerNonce(Base64.decode(value.getBytes()));
583             }
584
585             d.setServerPassword(rs.getString(6));
586
587         } catch (SQLException e) {
588             throw new PersistentStoreException("Error reading the device " + d, e);
589         } finally {
590             DBTools.close(conn, stmt, rs);
591         }
592     }
593
594     /**
595      * Insert or Update the device from the data store.
596      *
597      * @param d the device
598      *
599      * @throws PersistentException in case of error reading the data store
600      */

601     private void storeDevice(Sync4jDevice d)
602     throws PersistentStoreException {
603         Connection conn = null;
604         PreparedStatement stmt = null;
605         int n = 0;
606
607         try {
608             conn = dataSource.getConnection();
609
610             if (d.getDeviceId() != null && !d.getDeviceId().equals("")) {
611                 stmt = conn.prepareStatement(sql[SQL_UPDATE_DEVICE]);
612
613                 stmt.setString(1, d.getDescription());
614                 stmt.setString(2, d.getType());
615                 stmt.setString(3, d.getDigest());
616                 byte[] nonce = d.getClientNonce();
617                 stmt.setString(4, ((nonce != null) ? new String JavaDoc(Base64.encode(nonce)) : null));
618                 nonce = d.getServerNonce();
619                 stmt.setString(5, ((nonce != null) ? new String JavaDoc(Base64.encode(nonce)) : null));
620                 stmt.setString(6, d.getServerPassword());
621
622                 stmt.setString(7, d.getDeviceId());
623
624
625                 n = stmt.executeUpdate();
626
627                 stmt.close();
628             }
629
630             if (n == 0) {
631                 //
632
// The first time!!!
633
//
634
if (d.getDeviceId() == null || d.getDeviceId().equals("")) {
635                     int deviceId = this.readCounter(NS_DEVICE);
636                     d.setDeviceId("" + deviceId);
637                 }
638
639                 stmt = conn.prepareStatement(sql[SQL_INSERT_DEVICE]);
640
641                 stmt.setString(1, d.getDeviceId());
642                 stmt.setString(2, d.getDescription());
643                 stmt.setString(3, d.getType());
644                 stmt.setString(4, d.getDigest());
645                 byte[] nonce = d.getClientNonce();
646                 stmt.setString(5, ((nonce != null) ? new String JavaDoc(Base64.encode(nonce)) : null));
647                 nonce = d.getServerNonce();
648                 stmt.setString(6, ((nonce != null) ? new String JavaDoc(Base64.encode(nonce)) : null));
649                 stmt.setString(7, d.getServerPassword());
650
651
652                 stmt.executeUpdate();
653             }
654         } catch (SQLException e) {
655             throw new PersistentStoreException("Error storing the device " + d, e);
656         } finally {
657             DBTools.close(conn, stmt, null);
658         }
659     }
660
661     /**
662      * Delete the device from the data store.
663      *
664      * @param d the device
665      *
666      * @throws PersistentException in case of error reading the data store
667      */

668     private void deleteDevice(Sync4jDevice d)
669     throws PersistentStoreException {
670         Connection conn = null;
671         PreparedStatement stmt = null;
672
673         try {
674             conn = dataSource.getConnection();
675
676             //select and delete all principal for this device
677
WhereClause c = new WhereClause("device", new String JavaDoc[] {d.getDeviceId()}, WhereClause.OPT_EQ, true);
678             Sync4jPrincipal[] sp = (Sync4jPrincipal[])readAllPrincipals(c);
679
680             for (int i=0; (sp != null) && i<sp.length; i++) {
681                 Sync4jPrincipal syncPrincipal = sp[i];
682                 this.deletePrincipal(syncPrincipal);
683             }
684
685             stmt = conn.prepareStatement(sql[SQL_DELETE_DEVICE]);
686
687             stmt.setString(1, d.getDeviceId());
688
689             stmt.executeUpdate();
690
691
692         } catch (SQLException e) {
693             throw new PersistentStoreException("Error deleting the device " + d, e);
694         } finally {
695             DBTools.close(conn, stmt, null);
696         }
697     }
698
699     /**
700      * Select the number of devices that satisfy the conditions specified in input
701      *
702      * @return int number of devices
703      */

704     public Object JavaDoc[] readCountDevices(Clause clause) throws PersistentStoreException {
705         Connection conn = null;
706         PreparedStatement stmt = null;
707         ResultSet rs = null;
708         int n = 0;
709
710         try {
711             conn = dataSource.getConnection();
712
713             PreparedWhere where = clause.getPreparedWhere();
714
715             String JavaDoc query = sql[SQL_COUNT_DEVICES];
716             if (where.sql.length()>0) {
717                 query += " where " + where.sql;
718             }
719
720             stmt = conn.prepareStatement(query);
721
722             for (int i=0; i<where.parameters.length; ++i) {
723                 stmt.setObject(i+1, where.parameters[i]);
724             }
725
726             rs = stmt.executeQuery();
727             while (rs.next()) {
728                 n = rs.getInt(1);
729             }
730
731             String JavaDoc[] s = new String JavaDoc[1];
732             s[0] = "" + n;
733             return s;
734
735         } catch (SQLException e) {
736             throw new PersistentStoreException("Error reading count devices ", e);
737         } finally {
738             DBTools.close(conn, stmt, rs);
739         }
740     }
741
742     // -------------------------------------------------------------------------
743

744     // -------------------------------------------------------------------------
745
// Sync4jSource
746
// -------------------------------------------------------------------------
747

748     /**
749      * Read all sources
750      *
751      * @return an array with the sources (empty if no objects are found)
752      *
753      * @throws PersistentException in case of error reading the data store
754      */

755     private Object JavaDoc[] readAllSources()
756     throws PersistentStoreException {
757         Connection conn = null;
758         PreparedStatement stmt = null;
759         ResultSet rs = null;
760
761         ArrayList JavaDoc ret = new ArrayList JavaDoc();
762
763         try {
764             conn = dataSource.getConnection();
765
766             stmt = conn.prepareStatement(sql[SQL_SELECT_ALL_SOURCES]);
767
768             rs = stmt.executeQuery();
769
770             while (rs.next()) {
771                 ret.add(
772                     new Sync4jSource(
773                         rs.getString(1),
774                         rs.getString(2)
775                     )
776                 );
777             }
778
779             return ret.toArray(new Sync4jSource[ret.size()]);
780         } catch (SQLException e) {
781             throw new PersistentStoreException("Error reading sources", e);
782         } finally {
783             DBTools.close(conn, stmt, rs);
784         }
785     }
786
787     private void storeSource(Sync4jSource s)
788     throws PersistentStoreException {
789         Connection conn = null;
790         PreparedStatement stmt = null;
791
792         try {
793             conn = dataSource.getConnection();
794
795             stmt = conn.prepareStatement(sql[SQL_UPDATE_SOURCE]);
796
797             stmt.setString(1, s.getConfig());
798             stmt.setString(2, s.getUri() );
799
800             int n = stmt.executeUpdate();
801
802             if (n == 0) {
803                 //
804
// The first time!!!
805
//
806
stmt.close();
807
808                 stmt = conn.prepareStatement(sql[SQL_INSERT_SOURCE]);
809
810                 stmt.setString(1, s.getUri() );
811                 stmt.setString(2, s.getConfig());
812
813                 stmt.executeUpdate();
814             }
815         } catch (SQLException e) {
816             throw new PersistentStoreException("Error storing the source " + s, e);
817         } finally {
818             DBTools.close(conn, stmt, null);
819         }
820     }
821
822     /**
823      * Read the source from the data store.
824      *
825      * @param s the source
826      *
827      * @throws PersistentException in case of error reading the data store
828      */

829     private void readSource(Sync4jSource s)
830     throws PersistentStoreException {
831         Connection conn = null;
832         PreparedStatement stmt = null;
833         ResultSet rs = null;
834
835         try {
836             conn = dataSource.getConnection();
837
838             stmt = conn.prepareStatement(sql[SQL_GET_SOURCE]);
839             stmt.setString(1, s.getUri());
840
841             rs = stmt.executeQuery();
842
843             if (rs.next() == false) {
844                 throw new NotFoundException("Source not found for "
845                 + s.getUri()
846                 );
847             }
848
849             s.setUri (rs.getString(1));
850             s.setConfig(rs.getString(2));
851         } catch (SQLException e) {
852             throw new PersistentStoreException("Error reading the source " + s, e);
853         } finally {
854             DBTools.close(conn, stmt, rs);
855         }
856     }
857
858     private Object JavaDoc[] readSource(Sync4jSource s,Clause clause)
859     throws PersistentStoreException {
860         Connection conn = null;
861         PreparedStatement stmt = null;
862         ResultSet rs = null;
863
864         ArrayList JavaDoc ret = new ArrayList JavaDoc();
865
866         try {
867             conn = dataSource.getConnection();
868
869             PreparedWhere where = clause.getPreparedWhere();
870
871             String JavaDoc query = sql[SQL_SELECT_ALL_SOURCES];
872             if (where.sql.length() > 0) {
873                 query += " where " + where.sql;
874             }
875
876             stmt = conn.prepareStatement(query);
877
878             for (int i=0; i<where.parameters.length; ++i) {
879                 stmt.setObject(i+1, where.parameters[i]);
880             }
881
882             rs = stmt.executeQuery();
883
884             while (rs.next()) {
885                 ret.add(
886                     new Sync4jSource(
887                         rs.getString(1),
888                         rs.getString(2)
889                     )
890                 );
891             }
892
893             return ret.toArray(new Sync4jSource[ret.size()]);
894         } catch (SQLException e) {
895             throw new PersistentStoreException("Error reading sources", e);
896         } finally {
897             DBTools.close(conn, stmt, rs);
898         }
899     }
900
901     private void deleteSource(Sync4jSource s)
902     throws PersistentStoreException {
903         Connection conn = null;
904         PreparedStatement stmt = null;
905
906         try {
907             conn = dataSource.getConnection();
908
909             stmt = conn.prepareStatement(sql[SQL_DELETE_SOURCE_CLIENT_MAPPING]);
910
911             stmt.setString(1, s.getUri());
912
913             stmt.executeUpdate();
914
915             stmt.close();
916             stmt = conn.prepareStatement(sql[SQL_DELETE_SOURCE_LAST_SYNC]);
917
918             stmt.setString(1, s.getUri());
919
920             stmt.executeUpdate();
921
922             stmt.close();
923
924             stmt = conn.prepareStatement(sql[SQL_DELETE_SOURCE]);
925
926             stmt.setString(1, s.getUri());
927
928             stmt.executeUpdate();
929
930             stmt.close();
931
932         } catch (SQLException e) {
933             throw new PersistentStoreException("Error deleting the source " + s, e);
934         } finally {
935             DBTools.close(conn, stmt, null);
936         }
937     }
938
939     /**
940      * Insert a new SyncSource
941      */

942     private void insertSyncSource(String JavaDoc sourcetypeid, Sync4jSource ss)
943     throws PersistentStoreException {
944         Connection conn = null;
945         PreparedStatement stmt = null;
946
947         try {
948             conn = dataSource.getConnection();
949
950             stmt = conn.prepareStatement(sql[SQL_INSERT_SYNCSOURCE]);
951
952             stmt.setString(1, ss.getUri());
953             stmt.setString(2, ss.getConfig());
954             stmt.setString(3, ss.getSourceName());
955             stmt.setString(4, sourcetypeid);
956
957             stmt.executeUpdate();
958             stmt.close();
959
960         } catch (SQLException e) {
961             throw new PersistentStoreException("Error storing the syncsource " + ss, e);
962         } finally {
963             DBTools.close(conn, stmt, null);
964         }
965     }
966
967     /**
968      * Update an existing SyncSource
969      */

970     private void updateSyncSource(String JavaDoc sourcetypeid, Sync4jSource ss)
971     throws PersistentStoreException {
972         Connection conn = null;
973         PreparedStatement stmt = null;
974
975         try {
976             conn = dataSource.getConnection();
977
978             stmt = conn.prepareStatement(sql[SQL_UPDATE_SYNCSOURCE]);
979
980             stmt.setString(1, ss.getConfig());
981             stmt.setString(2, ss.getSourceName());
982             stmt.setString(3, ss.getSourceTypeId());
983             stmt.setString(4, ss.getUri() );
984
985             stmt.executeUpdate();
986             stmt.close();
987
988         } catch (SQLException e) {
989             throw new PersistentStoreException("Error updating the syncsource " + ss, e);
990         } finally {
991             DBTools.close(conn, stmt, null);
992         }
993     }
994
995     // -------------------------------------------------------------------------
996
// DeviceDMState
997
// -------------------------------------------------------------------------
998

999     /**
1000     * Read a device DM state from the data store.
1001     *
1002     * @param d the device DM state
1003     *
1004     * @throws PersistentException in case of error reading the data store
1005     * @throws NotFoundException if no device DM state is found with the given
1006     * device id
1007     */

1008    private void readDeviceDMState(DeviceDMState d)
1009    throws PersistentStoreException {
1010        Connection conn = null;
1011        PreparedStatement stmt = null;
1012        ResultSet rs = null;
1013
1014        String JavaDoc value;
1015        try {
1016            conn = dataSource.getConnection();
1017
1018            stmt = conn.prepareStatement(sql[SQL_GET_DEVICE_DM_STATE]);
1019            stmt.setString(1, d.deviceId);
1020
1021            rs = stmt.executeQuery();
1022
1023            if (rs.next() == false) {
1024                throw new NotFoundException("Device not found for "
1025                + d.deviceId
1026                );
1027            }
1028
1029            d.mssid = rs.getString(1) ;
1030            value = rs.getString(2) ;
1031            d.state = (value == null)
1032                        ? 0
1033                        : (byte)value.charAt(0);
1034            d.start = rs.getTimestamp(3) ;
1035            d.end = rs.getTimestamp(4) ;
1036            d.operation = rs.getString(5) ;
1037            d.info = rs.getString(6) ;
1038
1039        } catch (SQLException e) {
1040            throw new PersistentStoreException("Error reading the device " + d, e);
1041        } finally {
1042            DBTools.close(conn, stmt, rs);
1043        }
1044    }
1045
1046    /**
1047     * Insert or update the given device DM state into the data store.
1048     *
1049     * @param d the device DM state
1050     *
1051     * @throws PersistentException in case of data store error
1052     */

1053    private void storeDeviceDMState(DeviceDMState d)
1054    throws PersistentStoreException {
1055        Connection conn = null;
1056        PreparedStatement stmt = null;
1057        int n = 0;
1058
1059        try {
1060            conn = dataSource.getConnection();
1061
1062            if (d.id != null) {
1063                stmt = conn.prepareStatement(sql[SQL_UPDATE_DEVICE_DM_STATE]);
1064
1065                stmt.setString (1, d.deviceId);
1066                stmt.setString (2, d.mssid);
1067                stmt.setString (3, String.valueOf((char)d.state));
1068                stmt.setTimestamp(4, (d.start == null)
1069                                   ? null
1070                                   : new Timestamp(d.start.getTime()));
1071                stmt.setTimestamp(5, (d.end == null)
1072                                   ? null
1073                                   : new Timestamp(d.end.getTime()));
1074                stmt.setString (6, d.operation);
1075                stmt.setString (7, d.info);
1076                stmt.setString (8, d.id);
1077
1078                n = stmt.executeUpdate();
1079
1080                stmt.close(); stmt = null;
1081            }
1082
1083            if (n == 0) {
1084                //
1085
// The first time!!!
1086
//
1087

1088                if (d.id == null) {
1089                    d.id = String.valueOf(readCounter(NS_DM_STATE));
1090                }
1091
1092                stmt = conn.prepareStatement(sql[SQL_INSERT_DEVICE_DM_STATE]);
1093
1094                stmt.setString (1, d.id);
1095                stmt.setString (2, d.deviceId);
1096                stmt.setString (3, d.mssid);
1097                stmt.setString (4, String.valueOf((char)d.state));
1098                stmt.setTimestamp(5, (d.start == null)
1099                                   ? null
1100                                   : new Timestamp(d.start.getTime()));
1101                stmt.setTimestamp(6, (d.end == null)
1102                                   ? null
1103                                   : new Timestamp(d.end.getTime()));
1104                stmt.setString (7, d.operation);
1105                stmt.setString (8, d.info);
1106
1107                stmt.executeUpdate();
1108            }
1109        } catch (SQLException e) {
1110            throw new PersistentStoreException("Error storing the device DM state " + d, e);
1111        } finally {
1112            DBTools.close(conn, stmt, null);
1113        }
1114    }
1115
1116    /**
1117     * Read the DM states identified by the given clause
1118     *
1119     * @param clause the selecting clause
1120     *
1121     * @return an array with the principals (empty if no objects are found)
1122     *
1123     * @throws PersistentException in case of error reading the data store
1124     */

1125    private Object JavaDoc[] readDeviceDMState(Clause clause)
1126    throws PersistentStoreException {
1127        Connection conn = null;
1128        PreparedStatement stmt = null;
1129        ResultSet rs = null;
1130
1131        ArrayList JavaDoc ret = new ArrayList JavaDoc();
1132
1133        try {
1134            conn = dataSource.getConnection();
1135
1136            PreparedWhere where = clause.getPreparedWhere();
1137
1138            String JavaDoc query = sql[SQL_SELECT_ALL_DM_STATE];
1139            if (where.sql.length() > 0){
1140                query += " where " + where.sql;
1141            }
1142
1143            stmt = conn.prepareStatement(query);
1144
1145            for (int i=0; i<where.parameters.length; ++i) {
1146                stmt.setObject(i+1, where.parameters[i]);
1147            }
1148
1149            rs = stmt.executeQuery();
1150
1151            String JavaDoc value = null;
1152            DeviceDMState dms = null;
1153            while (rs.next()) {
1154                dms = new DeviceDMState();
1155
1156                dms.id = rs.getString (1);
1157                dms.deviceId = rs.getString (2);
1158                dms.mssid = rs.getString (3);
1159                value = rs.getString (4);
1160                dms.state = (value != null)
1161                              ? (byte)value.charAt(0)
1162                              : DeviceDMState.STATE_UNKNOWN
1163                              ;
1164                dms.start = rs.getTimestamp(5);
1165                dms.end = rs.getTimestamp(6);
1166                dms.operation = rs.getString (7);
1167                dms.info = rs.getString (8);
1168
1169                ret.add(dms);
1170            }
1171
1172            return ret.toArray(new DeviceDMState[ret.size()]);
1173        } catch (SQLException e) {
1174            throw new PersistentStoreException("Error reading device managment state", e);
1175        } finally {
1176            DBTools.close(conn, stmt, rs);
1177        }
1178    }
1179
1180    /**
1181     * Delete the given device DM state from the data store.
1182     *
1183     * @param d the device DM state
1184     *
1185     * @throws PersistentException in case of error reading the data store
1186     */

1187    private void deleteDeviceDMState(DeviceDMState d)
1188    throws PersistentStoreException {
1189        Connection conn = null;
1190        PreparedStatement stmt = null;
1191
1192        try {
1193            conn = dataSource.getConnection();
1194
1195            stmt = conn.prepareStatement(sql[SQL_DELETE_DEVICE_DM_STATE]);
1196
1197            stmt.setString(1, d.id);
1198
1199            stmt.executeUpdate();
1200        } catch (SQLException e) {
1201            throw new PersistentStoreException("Error deleting the device " + d, e);
1202        } finally {
1203            DBTools.close(conn, stmt, null);
1204        }
1205    }
1206
1207    /**
1208     * Read the counter of the specific id in order to use it like primary key
1209     * in case of inserting a new record into data store.
1210     *
1211     * @param idSpace the idSpace
1212     *
1213     * @throws PersistentException in case of error reading the data store
1214     */

1215    public int readCounter(String JavaDoc idSpace)
1216    throws PersistentStoreException {
1217        return readCounter(idSpace, 1);
1218    }
1219
1220    /**
1221     * Read the counter of the specific id in order to use it like primary key
1222     * in case of inserting a new record into data store and increment it of the
1223     * given increment
1224     *
1225     * @param idSpace the idSpace
1226     * @param increment the increment
1227     *
1228     * @throws PersistentException in case of error reading the data store
1229     */

1230    public int readCounter(String JavaDoc idSpace, int increment) throws PersistentStoreException {
1231        Connection conn = null;
1232        PreparedStatement stmt = null;
1233        ResultSet rs = null;
1234        int counter = 0;
1235
1236        try {
1237            conn = dataSource.getConnection();
1238
1239            java.sql.DatabaseMetaData JavaDoc dmd = conn.getMetaData();
1240
1241            if (dmd.supportsSelectForUpdate()) {
1242                stmt = conn.prepareStatement(sql[SQL_GET_COUNTER]);
1243            } else {
1244                stmt = conn.prepareStatement("select counter from sync4j_id where idspace=?");
1245            }
1246
1247            stmt.setString(1, idSpace);
1248
1249            rs = stmt.executeQuery();
1250
1251            if (rs.next() == false) {
1252                throw new NotFoundException("Counter not found for "
1253                                            + idSpace
1254                    );
1255            }
1256
1257            counter = rs.getInt(1);
1258
1259            stmt.close();
1260
1261            stmt = conn.prepareStatement(sql[SQL_UPDATE_COUNTER]);
1262            stmt.setInt(1, counter + increment);
1263            stmt.setString(2, idSpace);
1264
1265            stmt.executeUpdate();
1266
1267        } catch (SQLException e) {
1268            e.printStackTrace();
1269            throw new PersistentStoreException("Error reading the counter " + counter, e);
1270        } finally {
1271            DBTools.close(conn, stmt, rs);
1272        }
1273        return counter;
1274    }
1275
1276
1277
1278}
Popular Tags