KickJava   Java API By Example, From Geeks To Geeks.

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


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.task.model.Task;
43 import sync4j.exchange.items.task.manager.TaskManager;
44 import sync4j.exchange.items.task.TaskParseException;
45 import sync4j.exchange.DataAccessException;
46
47 /**
48  * This class define <i>SyncSource</i>
49  * between SyncServer and Exchange Server tasks items
50  *
51  * @author Fabio Maggi @ Funambol
52  *
53  * version $Id: ExchangeTaskSyncSource.java,v 1.11 2005/06/25 13:43:44 nichele Exp $
54  */

55 public class ExchangeTaskSyncSource
56 extends ExchangeSyncSource
57 implements SyncSource, Serializable JavaDoc {
58
59     // --------------------------------------------------------------- Constants
60

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

65     private TaskManager tm = null;
66
67     // ------------------------------------------------------------ Constructors
68

69     public ExchangeTaskSyncSource() {
70     }
71
72     // ---------------------------------------------------------- Public Methods
73

74    /**
75     * @see SyncSource
76     */

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

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

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

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

208     public SyncItem[] getSyncItemsFromIds(Principal JavaDoc principal,
209                                           SyncItemKey[] syncItemKeys)
210     throws SyncSourceException {
211
212         ArrayList JavaDoc syncItems = null ;
213         Task task = null ;
214
215         String JavaDoc username = null ;
216         String JavaDoc credentials = null ;
217
218         String JavaDoc id = null ;
219
220         username = ((Sync4jPrincipal) principal).getUsername() ;
221         credentials = ((Sync4jPrincipal) principal).getEncodedCredentials() ;
222
223         syncItems = new ArrayList JavaDoc();
224
225         int l = syncItemKeys.length;
226
227         for (int i = 0; ((syncItemKeys != null) && (i < l)); ++i) {
228
229             id = syncItemKeys[i].getKeyAsString();
230
231             try {
232                 this.tm = getTaskManager();
233                 task = this.tm.getTaskById(username ,
234                                                credentials ,
235                                                id ,
236                                                this.exchangeFolder);
237             } catch (DataAccessException e) {
238                 Throwable JavaDoc previous = e.getCause();
239
240                 if (previous instanceof NotFoundException) {
241
242                     Logger JavaDoc log = Sync4jLogger.getLogger("source");
243                     if (log.isLoggable(Level.SEVERE)) {
244                         log.severe("Task not found while reading Exchange database: " + e.getMessage());
245                     }
246                     Logger.getLogger(LOG_NAME).throwing(getClass().getName(), "readExchangeDatabase", e);
247                 } else{
248                     throw new SyncSourceException("Error reading items", e);
249                 }
250             }
251
252             if (task != null) {
253                 task.setState (SyncItemState.NEW );
254                 syncItems.add (getSyncItem (task) );
255             }
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         return filterSyncItems(principal, ids, SyncItemState.NEW);
300
301     }
302
303     /**
304      * @see SyncSource
305      */

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

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

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

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

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

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

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

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

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

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

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

566     private SyncItem[] filterSyncItems(Principal JavaDoc principal ,
567                                        char state)
568     throws SyncSourceException {
569
570         Task[] tasks = null ;
571
572         String JavaDoc username = null ;
573         String JavaDoc credentials = null ;
574
575         username = ((Sync4jPrincipal) principal).getUsername() ;
576         credentials = ((Sync4jPrincipal) principal).getEncodedCredentials() ;
577
578         try {
579
580             this.tm = getTaskManager();
581
582             tasks = this.tm.getAllTasks (username ,
583                                           credentials ,
584                                           this.exchangeFolder ) ;
585
586
587         } catch (DataAccessException e) {
588             throw new SyncSourceException("Error reading tasks: " +
589                                          e.getMessage(), e);
590         }
591
592         return getSyncItems(tasks, state);
593
594     }
595
596     /**
597      * Create SyncItem from Task
598      *
599      * @param note
600      * @return SyncItem
601      * @trows SyncSourceException
602      */

603     private SyncItem getSyncItem(Task task)
604     throws SyncSourceException {
605
606         SyncItem syncItem = null;
607
608         syncItem = new SyncItemImpl(this ,
609                                     task.getId() ,
610                                     task.getState());
611
612         try {
613
614             if (this.isEncode()) {
615                 syncItem.setProperty(
616                     new SyncProperty(SyncItem.PROPERTY_BINARY_CONTENT,
617                                      Base64.encode(task.toXml().getBytes())
618                 ));
619
620                 syncItem.setProperty(
621                     new SyncProperty(SyncItem.PROPERTY_FORMAT,"b64")
622                                 );
623
624             } else {
625                 syncItem.setProperty(
626                     new SyncProperty(SyncItem.PROPERTY_BINARY_CONTENT,
627                                      task.toXml().getBytes())
628                 );
629             }
630
631         } catch (TaskParseException e) {
632             throw new SyncSourceException( "Error setting the item "
633                                           + syncItem
634                                           , e
635                                           );
636         }
637
638         return syncItem;
639
640     }
641
642     /**
643      * Create SyncItem array from Task array
644      *
645      * @param task
646      * @param state
647      * @return SyncItem array
648      * @trows SyncSourceException
649      */

650     private SyncItem[] getSyncItems(Task[] tasks,
651                                     char state)
652     throws SyncSourceException {
653
654         SyncItem[] syncItems = null;
655
656         int l = tasks.length;
657
658         syncItems = new SyncItem [l];
659
660         for (int i=0; i < l; i++) {
661             tasks [i].setState(state) ;
662             syncItems[i] = getSyncItem(tasks[i]) ;
663         }
664
665         return syncItems;
666
667     }
668
669     /**
670      *
671      * Create TaskManager istance
672      * (if not already exist)
673      *
674      * @trows DataAccessException
675      */

676     private TaskManager getTaskManager()
677     throws DataAccessException {
678
679         if (this.tm == null) {
680             this.tm = new TaskManager(this.getHost() ,
681                                       this.getPort());
682         }
683
684         return this.tm;
685
686     }
687
688     /**
689      * Creates a new Task from the given syncItem
690      * @param syncItem SyncItem
691      * @return Task
692      */

693     private Task getTaskFromSyncItem(SyncItem syncItem)
694             throws Exception JavaDoc {
695
696         String JavaDoc content = null;
697         Task task = null;
698
699         String JavaDoc itemKey = syncItem.getKey().getKeyAsString();
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         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         task = new Task(itemKey, content, t);
720
721         return task;
722     }
723
724 }
725
Popular Tags