KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > sync4j > exchange > engine > source > ExchangeNoteSyncSource


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.exchange.engine.source;
20
21 import java.io.Serializable JavaDoc;
22 import java.security.Principal JavaDoc;
23 import java.sql.Timestamp JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Date JavaDoc;
26 import java.util.logging.Logger JavaDoc;
27 import java.util.logging.Level JavaDoc;
28
29 import sync4j.framework.logging.Sync4jLogger;
30 import sync4j.framework.engine.SyncItemImpl;
31 import sync4j.framework.engine.SyncItem;
32 import sync4j.framework.engine.SyncItemKey;
33 import sync4j.framework.engine.SyncProperty;
34 import sync4j.framework.engine.SyncItemState;
35 import sync4j.framework.engine.source.SyncSource;
36 import sync4j.framework.engine.source.SyncSourceException;
37 import sync4j.framework.engine.source.AbstractSyncSource;
38 import sync4j.framework.security.Sync4jPrincipal;
39 import sync4j.framework.server.store.NotFoundException;
40 import sync4j.framework.tools.Base64;
41
42 import sync4j.exchange.items.note.model.Note;
43 import sync4j.exchange.items.note.manager.NoteManager;
44 import sync4j.exchange.items.note.NoteParseException;
45 import sync4j.exchange.DataAccessException;
46
47 /**
48  * This class define <i>SyncSource</i>
49  * between SyncServer and Exchange Server notes items
50  *
51  * version $Id: ExchangeNoteSyncSource.java,v 1.11 2005/07/05 08:01:43 nichele Exp $
52  */

53 public class ExchangeNoteSyncSource
54 extends ExchangeSyncSource
55 implements SyncSource, Serializable JavaDoc {
56
57     // --------------------------------------------------------------- Constants
58

59     private static final String JavaDoc EXCHANGE_HREF_EXTENSION = ".eml";
60
61     // --------------------------------------------------------------- Private data
62

63     private NoteManager nm = null;
64
65     // --------------------------------------------------------------- Constructors
66

67     public ExchangeNoteSyncSource() {
68     }
69
70     // --------------------------------------------------------------- Public Methods
71

72    /**
73     * @see SyncSource
74     */

75     public SyncItem setSyncItem(Principal JavaDoc principal, SyncItem syncItem)
76     throws SyncSourceException {
77
78        Note note = null ;
79        Note newNote = null ;
80
81        String JavaDoc itemKey = null ;
82        String JavaDoc href = null ;
83
84        String JavaDoc username = null ;
85        String JavaDoc credentials = null ;
86
87        boolean isAddNote = false ;
88
89        try {
90
91             username = ((Sync4jPrincipal)principal).getUsername() ;
92             credentials = ((Sync4jPrincipal)principal).getEncodedCredentials() ;
93
94             itemKey = syncItem.getKey().getKeyAsString();
95
96             //
97
// search href [eg. 1234.eml] in exchange items
98
//
99
href = getHref(itemKey);
100
101             if (href == null) {
102                //
103
// if href not found, new item is created
104
// default href = this.CurrentTimesMillis()
105
//
106
href = String.valueOf(System.currentTimeMillis()) +
107                       EXCHANGE_HREF_EXTENSION;
108                isAddNote = true;
109             }
110
111             note = getNoteFromSyncItem(syncItem);
112
113             note.setHref(href);
114
115             this.nm = getNoteManager();
116
117             newNote = this.nm.setNote (note ,
118                                        username ,
119                                        credentials ,
120                                        exchangeFolder );
121
122             if (isAddNote) {
123                 toChangedItems(newNote.getId(), ITEM_ADD);
124             } else {
125                 toChangedItems(newNote.getId(), ITEM_UPDATE);
126             }
127
128             syncItem = getSyncItem(newNote);
129
130             if (log.isLoggable(Level.SEVERE)) {
131                 log.severe("Exchange SyncSource " +
132                            sourceURI +
133                            " - set syncItem" +
134                            syncItem.getKey().getKeyAsString());
135             }
136
137             return syncItem;
138
139
140         } catch (Exception JavaDoc e) {
141
142             if (newNote != null) {
143                 if (isAddNote) {
144                     toChangedItems(newNote.getId(), ITEM_ADD_ERROR);
145                 } else {
146                     toChangedItems(newNote.getId(), ITEM_UPDATE_ERROR);
147                 }
148             }
149
150             throw new SyncSourceException( "Error setting the item " +
151                                           syncItem + " " + e.getMessage(), e);
152         }
153     }
154
155     /**
156      * @see SyncSource
157      */

158     public SyncItem[] setSyncItems(Principal JavaDoc principal, SyncItem[] syncItems)
159     throws SyncSourceException {
160
161         ArrayList JavaDoc syncItemsInError = new ArrayList JavaDoc();
162         ArrayList JavaDoc ret = new ArrayList JavaDoc();
163
164         for (int i=0, l = syncItems.length; i < l; ++i) {
165             try {
166                 ret.add(setSyncItem(principal, syncItems[i]));
167             } catch (SyncSourceException e) {
168                 syncItemsInError.add(syncItems[i]);
169             }
170         } // next i
171

172         if (syncItemsInError.size() > 0) {
173             throw new SyncSourceException("Error setting the following items: " +
174                                           syncItemsInError.toString()
175                                          );
176         }
177
178         if (log.isLoggable(Level.SEVERE)) {
179             log.severe("Exchange SyncSource " +
180                        sourceURI +
181                        " - set syncItems");
182         }
183
184         return (SyncItem[])ret.toArray(new SyncItem[] {});
185
186     }
187
188     /**
189      * @see SyncSource
190      */

191     public SyncItem getSyncItemFromId(Principal JavaDoc principal,
192                                       SyncItemKey syncItemKey)
193     throws SyncSourceException{
194
195         SyncItem[] syncItems =
196             getSyncItemsFromIds(principal, new SyncItemKey[] {syncItemKey});
197
198         if ((syncItems == null) || (syncItems.length == 0)) {
199             return null;
200         }
201
202         return syncItems[0];
203
204     }
205
206     /**
207      * @see SyncSource
208      */

209     public SyncItem[] getSyncItemsFromIds(Principal JavaDoc principal,
210                                           SyncItemKey[] syncItemKeys)
211     throws SyncSourceException {
212
213         ArrayList JavaDoc syncItems = null ;
214         Note note = null ;
215
216         String JavaDoc username = null ;
217         String JavaDoc credentials = null ;
218
219         String JavaDoc id = null ;
220
221         username = ((Sync4jPrincipal) principal).getUsername() ;
222         credentials = ((Sync4jPrincipal) principal).getEncodedCredentials() ;
223
224         syncItems = new ArrayList JavaDoc();
225
226         int l = syncItemKeys.length;
227
228         for (int i = 0; ((syncItemKeys != null) && (i < l)); ++i) {
229
230             id = syncItemKeys[i].getKeyAsString();
231
232             try {
233                 this.nm = getNoteManager();
234                 note = this.nm.getNoteById(username ,
235                                            credentials ,
236                                            id ,
237                                            this.exchangeFolder );
238             } catch (DataAccessException e) {
239                 Throwable JavaDoc previous = e.getCause();
240
241                 if (previous instanceof NotFoundException) {
242
243                     Logger JavaDoc log = Sync4jLogger.getLogger("source");
244                     if (log.isLoggable(Level.SEVERE)) {
245                         log.severe("Note not found while reading Exchange database: " + e.getMessage());
246                     }
247                     Logger.getLogger(LOG_NAME).throwing(getClass().getName(), "readExchangeDatabase", e);
248                 } else{
249                     throw new SyncSourceException("Error reading items", e);
250                 }
251             }
252
253             if (note != null) {
254                 note.setState (SyncItemState.NEW ) ;
255                 syncItems.add (getSyncItem(note) ) ;
256             }
257         }
258
259         if (log.isLoggable(Level.SEVERE)) {
260             log.severe("Exchange SyncSource " +
261                        sourceURI +
262                        " - getting syncItems" );
263         }
264
265         return (SyncItem[]) syncItems.toArray(new SyncItem[syncItems.size()]);
266
267     }
268
269     /**
270      * @see SyncSource
271      */

272     public SyncItemKey[] getNewSyncItemKeys(Principal JavaDoc principal,
273                                             Timestamp JavaDoc since )
274     throws SyncSourceException {
275         return null;
276     }
277
278     /**
279      * @see SyncSource
280      */

281     public SyncItem[] getNewSyncItems(Principal JavaDoc principal,
282                                       Timestamp JavaDoc since )
283     throws SyncSourceException {
284
285         String JavaDoc ids[] = null;
286
287         ids = this.getNewItemIds();
288
289         if (log.isLoggable(Level.SEVERE)) {
290             log.severe("Exchange SyncSource " +
291                        sourceURI +
292                        " - getting new syncItems" );
293         }
294
295         if(ids == null || !(ids.length > 0)) {
296             return new SyncItem[0];
297         }
298
299
300         return filterSyncItems(principal, ids, SyncItemState.NEW);
301
302     }
303
304     /**
305      * @see SyncSource
306      */

307     public SyncItemKey[] getDeletedSyncItemKeys(Principal JavaDoc principal,
308                                                 Timestamp JavaDoc since )
309     throws SyncSourceException {
310         return null;
311     }
312
313     /**
314      * @see SyncSource
315      */

316     public SyncItem[] getDeletedSyncItems(Principal JavaDoc principal,
317                                           Timestamp JavaDoc since )
318     throws SyncSourceException {
319
320         String JavaDoc [] ids = null ;
321         SyncItem[] syncItems = null ;
322
323         ids = this.getDeleteItemIds();
324
325         int l = ids.length;
326
327         syncItems = new SyncItem[l];
328
329         for (int i = 0; i < l; i++) {
330
331             syncItems[i] = new SyncItemImpl(this, ids[i], SyncItemState.DELETED);
332         }
333
334         if (log.isLoggable(Level.SEVERE)) {
335             log.severe("Exchange SyncSource " +
336                        sourceURI +
337                        " - getting deleted syncItems" );
338         }
339
340         return syncItems;
341     }
342
343     /**
344      * @see SyncSource
345      */

346     public SyncItem[] getUpdatedSyncItems(Principal JavaDoc principal, Timestamp JavaDoc since)
347     throws SyncSourceException {
348
349         String JavaDoc ids[] = null;
350
351         ids = this.getUpdateItemIds();
352
353         if (log.isLoggable(Level.SEVERE)) {
354             log.severe("Exchange SyncSource " +
355                        sourceURI +
356                        " - getting updated syncItems" );
357         }
358
359         if(ids == null || !(ids.length > 0)) {
360             return new SyncItem[0];
361         }
362
363         return filterSyncItems(principal, ids, SyncItemState.UPDATED);
364     }
365
366
367     public SyncItemKey[] getUpdatedSyncItemKeys(Principal JavaDoc principal,
368                                                 Timestamp JavaDoc since)
369     throws SyncSourceException {
370         return null;
371     }
372
373     /**
374      * @see SyncSource
375      */

376     public void removeSyncItem(Principal JavaDoc principal, SyncItem syncItem)
377     throws SyncSourceException {
378
379         Note note = null ;
380
381         String JavaDoc username = null ;
382         String JavaDoc credentials = null ;
383
384         String JavaDoc id = null ;
385         String JavaDoc href = null ;
386
387         id = syncItem.getKey().getKeyAsString();
388
389         username = ((Sync4jPrincipal) principal).getUsername() ;
390         credentials = ((Sync4jPrincipal) principal).getEncodedCredentials() ;
391
392         href = getHref(id);
393
394         try {
395             if (href != null) {
396                 note = new Note(id) ;
397                 note.setHref(href) ;
398                 this.nm = getNoteManager() ;
399                 this.nm.removeNote(note ,
400                                    username ,
401                                    credentials ,
402                                    exchangeFolder ) ;
403                 toChangedItems(note.getId(), ITEM_REMOVE) ;
404             } else {
405                 toChangedItems(note.getId(), ITEM_REMOVE_ERROR) ;
406             }
407         } catch (DataAccessException e) {
408            toChangedItems(note.getId(), ITEM_REMOVE_ERROR) ;
409            throw new SyncSourceException("Error reading items", e);
410         }
411     }
412
413     /**
414      * @see SyncSource
415      */

416     public void removeSyncItems(Principal JavaDoc principal, SyncItem[] syncItems)
417     throws SyncSourceException {
418
419         ArrayList JavaDoc syncItemsInError = new ArrayList JavaDoc();
420
421         for (int i=0, l = syncItems.length ; i < l; ++i) {
422             try {
423                 removeSyncItem(principal, syncItems[i]);
424             } catch (SyncSourceException e) {
425                 syncItemsInError.add(syncItems[i]);
426             }
427         } // next i
428

429         if (syncItemsInError.size() > 0) {
430             throw new SyncSourceException( "Error deleting the following items: "
431                                          + syncItemsInError.toString()
432                                          );
433         }
434
435         if (log.isLoggable(Level.SEVERE)) {
436             log.severe("Exchange SyncSource " +
437                        sourceURI +
438                        " - removing syncItems" );
439         }
440
441
442     }
443
444     /**
445      * @see SyncSource
446      */

447     public SyncItem[] getAllSyncItems(Principal JavaDoc principal)
448     throws SyncSourceException {
449
450         if (log.isLoggable(Level.SEVERE)) {
451             log.severe("Exchange SyncSource " +
452                        sourceURI +
453                        " - getting all syncItems" );
454         }
455
456         return filterSyncItems(principal, SyncItemState.NEW);
457
458     }
459
460
461     /**
462      * The same as <i>getSyncItemFromId()</i>
463      * @see SyncSource
464      */

465     public SyncItem getSyncItemFromTwin(Principal JavaDoc principal, SyncItem syncItem)
466             throws SyncSourceException {
467
468         String JavaDoc username = ((Sync4jPrincipal) principal).getUsername();
469         String JavaDoc credentials = ((Sync4jPrincipal) principal).
470                              getEncodedCredentials();
471         SyncItem syncTwin = null;
472         try {
473             this.nm = getNoteManager();
474             Note note = getNoteFromSyncItem(syncItem);
475             Note twin = nm.getNoteTwin(note,
476                                        username,
477                                        credentials,
478                                        exchangeFolder);
479
480             if (twin != null) {
481                 syncTwin = getSyncItem(twin);
482             }
483
484         } catch (Exception JavaDoc ex) {
485             throw new SyncSourceException("Error getting twin", ex);
486         }
487
488         return syncTwin;
489
490     }
491
492     /**
493      * The same as <i>getSyncItemFromIds()</i>
494      *
495      * @see SyncSource
496      */

497     public SyncItem[] getSyncItemsFromTwins(Principal JavaDoc principal,
498                                             SyncItem[] syncItems)
499     throws SyncSourceException {
500
501         ArrayList JavaDoc items = new ArrayList JavaDoc();
502         for (int i = 0, l = syncItems.length; i < l; ++i){
503             items.add(getSyncItemFromId(principal, syncItems[i].getKey()));
504         }
505
506         return (SyncItem[])items.toArray(new SyncItem[items.size()]);
507
508     }
509
510
511     // --------------------------------------------------------- Private methods
512

513
514     /**
515      * Filters the SyncItems in the synchronization database (after a refresh)
516      * based on the given principal, ids, state
517      *
518      * @param principal principal
519      * @param ids an array containing note id
520      * @param state note state
521      *
522      * @throws SyncSourceException in case of IO errors
523      *
524      * @return an array of SyncItem objects whose state is equal to the given
525      * state.
526      */

527     private SyncItem[] filterSyncItems(Principal JavaDoc principal ,
528                                        String JavaDoc[] ids ,
529                                        char state)
530     throws SyncSourceException {
531
532         Note[] notes = null ;
533
534         String JavaDoc username = null ;
535         String JavaDoc credentials = null ;
536
537         username = ((Sync4jPrincipal) principal).getUsername() ;
538         credentials = ((Sync4jPrincipal) principal).getEncodedCredentials() ;
539
540         try {
541
542             this.nm = getNoteManager();
543
544             notes = this.nm.getNotes (username ,
545                                           credentials ,
546                                           ids ,
547                                           this.exchangeFolder ) ;
548
549
550         } catch (DataAccessException e) {
551             throw new SyncSourceException("Error reading notes: " +
552                                          e.getMessage(), e);
553         }
554
555         return getSyncItems(notes, state);
556
557     }
558
559
560     /**
561      * Filters the SyncItems in the synchronization database (after a refresh)
562      * based on the given principal, state
563      *
564      * @param principal principal
565      * @param state note state
566      *
567      * @throws SyncSourceException in case of IO errors
568      *
569      * @return an array of SyncItem objects whose state is equal to the given
570      * state.
571      */

572     private SyncItem[] filterSyncItems(Principal JavaDoc principal ,
573                                        char state)
574     throws SyncSourceException {
575
576         Note[] notes = null ;
577
578         String JavaDoc username = null ;
579         String JavaDoc credentials = null ;
580
581         username = ((Sync4jPrincipal) principal).getUsername() ;
582         credentials = ((Sync4jPrincipal) principal).getEncodedCredentials() ;
583
584         try {
585
586             this.nm = getNoteManager();
587
588             notes = this.nm.getAllNotes (username ,
589                                           credentials ,
590                                           this.exchangeFolder) ;
591
592         } catch (DataAccessException e) {
593             throw new SyncSourceException("Error reading notes: " +
594                                          e.getMessage(), e);
595         }
596
597         return getSyncItems(notes, state);
598
599     }
600
601     /**
602      * Create SyncItem array from Note array
603      *
604      * @param notess
605      * @param state
606      * @return SyncItem array
607      * @trows SyncSourceException
608      */

609     private SyncItem[] getSyncItems(Note[] notes,
610                                     char state)
611     throws SyncSourceException {
612
613         SyncItem[] syncItems = null;
614
615         int l = notes.length;
616
617         syncItems = new SyncItem [l];
618
619         for (int i=0; i < l; i++) {
620             notes [i].setState(state) ;
621             syncItems[i] = getSyncItem(notes[i]) ;
622         }
623
624
625         return syncItems;
626
627     }
628
629     /**
630      * Create SyncItem from Note
631      *
632      * @param note
633      * @return SyncItem
634      * @trows SyncSourceException
635      */

636     private SyncItem getSyncItem(Note note)
637     throws SyncSourceException {
638
639         SyncItem syncItem = null;
640
641         syncItem = new SyncItemImpl(this ,
642                                     note.getId() ,
643                                     note.getState());
644
645         try {
646
647             if (this.isEncode()) {
648                 syncItem.setProperty(
649                     new SyncProperty(SyncItem.PROPERTY_BINARY_CONTENT,
650                                      Base64.encode(note.toXML().getBytes())
651                 ));
652
653                 syncItem.setProperty(
654                     new SyncProperty(SyncItem.PROPERTY_FORMAT,"b64")
655                 );
656
657             } else {
658                 syncItem.setProperty(
659                     new SyncProperty(SyncItem.PROPERTY_BINARY_CONTENT,
660                                      note.toXML().getBytes())
661                 );
662             }
663
664         } catch (NoteParseException e) {
665             throw new SyncSourceException( "Error setting the item "
666                                           + syncItem
667                                           , e
668                                           );
669         }
670
671         return syncItem;
672
673     }
674
675     /**
676      *
677      * Create ContactManager istance
678      * (if not already exist)
679      *
680      * @trows DataAccessException
681      */

682     private NoteManager getNoteManager()
683     throws DataAccessException {
684
685         if (this.nm == null) {
686             this.nm = new NoteManager(this.getHost() ,
687                                       this.getPort());
688         }
689
690         return this.nm;
691
692     }
693
694     /**
695      * Creates a new Note from the given syncItem
696      * @param syncItem SyncItem
697      * @return Note
698      */

699     private Note getNoteFromSyncItem(SyncItem syncItem) throws Exception JavaDoc {
700
701         byte[] itemContent =
702                 (byte[]) syncItem.getPropertyValue(
703                         SyncItem.PROPERTY_BINARY_CONTENT);
704
705         if (itemContent == null) {
706             itemContent = new byte[0];
707         }
708
709         String JavaDoc content = new String JavaDoc(itemContent);
710
711         if (this.isEncode() && content != null && content.length() > 0) {
712             content = new String JavaDoc(Base64.decode(content));
713         }
714
715         Date JavaDoc t =
716                 new Date JavaDoc(((Timestamp JavaDoc) syncItem.getPropertyValue(
717                         SyncItem.PROPERTY_TIMESTAMP)).getTime());
718
719         Note note = new Note(syncItem.getKey().getKeyAsString(),
720                              content,
721                              t);
722
723         return note;
724     }
725
726 }
727
Popular Tags