source: contrib/psync/src/main/java/br/com/prognus/psync/synclet/SourceUriPrefixSynclet.java @ 1009

Revision 1009, 18.2 KB checked in by wmerlotto, 15 years ago (diff)

Ticket #554 - Commit da versão inicial do psync.

Line 
1/**
2 * Copyright (C) 2006-2007 Funambol
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the Honest Public License.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 * Honest Public License for more details.
11 *
12 * You should have received a copy of the Honest Public License
13 * along with this program; if not, write to Funambol,
14 * 643 Bair Island Road, Suite 305 - Redwood City, CA 94063, USA
15 */
16package br.com.prognus.psync.synclet;
17
18import java.util.ArrayList;
19import java.util.HashMap;
20import java.util.Iterator;
21import java.util.List;
22
23import com.funambol.framework.core.AbstractCommand;
24import com.funambol.framework.core.Alert;
25import com.funambol.framework.core.Status;
26import com.funambol.framework.core.Results;
27import com.funambol.framework.core.Sync;
28import com.funambol.framework.core.Map;
29import com.funambol.framework.core.Item;
30import com.funambol.framework.core.DataStore;
31import com.funambol.framework.core.Source;
32import com.funambol.framework.core.Sync4jException;
33import com.funambol.framework.core.SyncBody;
34import com.funambol.framework.core.SyncML;
35import com.funambol.framework.core.Target;
36import com.funambol.framework.core.TargetRef;
37import com.funambol.framework.core.SourceRef;
38import com.funambol.framework.engine.pipeline.InputMessageProcessor;
39import com.funambol.framework.engine.pipeline.OutputMessageProcessor;
40import com.funambol.framework.engine.pipeline.MessageProcessingContext;
41import com.funambol.framework.logging.FunambolLogger;
42import com.funambol.framework.logging.FunambolLoggerFactory;
43import com.funambol.framework.protocol.ProtocolUtil;
44import com.funambol.framework.core.DevInfItem;
45
46/**
47 * This class strips the source URIs with a './' if needed.
48 *
49 * This is done in order to allow any client to sync with the source URIs
50 * defined, because some devices have a prefix of './'.
51 *
52 * @version $Id: SourceUriPrefixSynclet.java,v 1.4 2007-02-15 10:23:46 luigiafassina Exp $
53 */
54public class SourceUriPrefixSynclet
55implements InputMessageProcessor, OutputMessageProcessor {
56
57    // --------------------------------------------------------------- Constants
58    private static final String SYNCLET_NAME =
59        SourceUriPrefixSynclet.class.getName();
60
61    private static final String PROPERTY_SOURCENAME_CHANGED =
62        "funambol.foundation.sourceuriprefix.SOURCENAME_CHANGED";
63    // ------------------------------------------------------------ Private data
64    private static final FunambolLogger log =
65            FunambolLoggerFactory.getLogger("engine.pipeline");
66
67    // ---------------------------------------------------------- Public methods
68
69    /**
70     * Process input message and set MessageProcessingContext property.
71     *
72     * @param processingContext the message processing context
73     * @param message the message to be processed
74     * @throws Sync4jException
75     */
76    public void preProcessMessage(MessageProcessingContext processingContext,
77                                  SyncML message                            )
78    throws Sync4jException {
79
80        if (log.isTraceEnabled()) {
81            log.trace(SYNCLET_NAME + ".preProcessMessage(...)");
82        }
83
84        HashMap sourceReplacedMap =
85            (HashMap)processingContext.getSessionProperty(
86                                                   PROPERTY_SOURCENAME_CHANGED);
87
88        if (sourceReplacedMap == null) {
89            sourceReplacedMap = new HashMap();
90            processingContext.setSessionProperty(PROPERTY_SOURCENAME_CHANGED,
91                                                 sourceReplacedMap          );
92        }
93
94        //
95        // Store and change the source uri into commands
96        //
97        manageInputAlert (message, sourceReplacedMap);
98        manageInputStatus(message, sourceReplacedMap);
99        manageInputSync  (message, sourceReplacedMap);
100        manageInputMap   (message, sourceReplacedMap);
101
102    }
103
104    /**
105     * Process and manipulate the output message.
106     *
107     * @param processingContext the message processing context
108     * @param message the message to be processed
109     * @throws Sync4jException
110     */
111    public void postProcessMessage(MessageProcessingContext processingContext,
112                                   SyncML message) throws Sync4jException {
113        if (log.isTraceEnabled()) {
114            log.trace(SYNCLET_NAME + ".postProcessMessage(...)");
115        }
116
117        HashMap sourceReplacedMap =
118            (HashMap)processingContext.getSessionProperty(
119                                                   PROPERTY_SOURCENAME_CHANGED);
120        if (!sourceReplacedMap.isEmpty()) {
121            //
122            // Replace original source uri into commands
123            //
124            manageOutputStatus (message, sourceReplacedMap);
125            manageOutputResults(message, sourceReplacedMap);
126            manageOutputAlert  (message, sourceReplacedMap);
127            manageOutputSync   (message, sourceReplacedMap);
128       }
129    }
130
131    // --------------------------------------------------------- Private Methods
132
133    /**
134     * Store and change Target URI into Alert commands
135     *
136     * @param message the client message
137     * @param sourceReplacedMap the HashMap in which store uri to replace
138     */
139    private void manageInputAlert(SyncML message, HashMap sourceReplacedMap) {
140        if (log.isTraceEnabled()) {
141            log.trace("Strip TargetURI into input Alert commands");
142        }
143        SyncBody syncBody = message.getSyncBody();
144
145        AbstractCommand[] allClientCommands =
146            (AbstractCommand[])syncBody.getCommands().toArray(
147            new AbstractCommand[0]);
148
149        ArrayList alertList =
150            ProtocolUtil.filterCommands(allClientCommands, Alert.class);
151
152        Iterator itAlertList = alertList.iterator();
153
154        Alert alert = null;
155        ArrayList items = null;
156        Iterator itItem = null;
157        Item item = null;
158        Target target = null;
159        String targetUri = null;
160
161        while (itAlertList.hasNext()) {
162            alert = (Alert)itAlertList.next();
163            items = alert.getItems();
164            itItem = items.iterator();
165            while (itItem.hasNext()) {
166
167                item = (Item)itItem.next();
168                target = item.getTarget();
169                if (target != null) {
170                    targetUri = target.getLocURI();
171                    if (log.isTraceEnabled()) {
172                        log.trace("original targetUri: " + targetUri);
173                    }
174
175                    if (targetUri.startsWith("./")) {
176                        String targetNew = targetUri.substring(2);
177                        if (log.isTraceEnabled()) {
178                            log.trace("new targetUri: " + targetNew);
179                        }
180                        target.setLocURI(targetNew);
181
182                        sourceReplacedMap.put(targetNew, targetUri);
183                    }
184                }
185            }
186        }
187    }
188
189    /**
190     * Store and change SourceRef into Status commmads
191     *
192     * @param message the client message
193     * @param sourceReplacedMap the HashMap in which store uri to replace
194     */
195    private void manageInputStatus(SyncML message, HashMap sourceReplacedMap) {
196        if (log.isTraceEnabled()) {
197            log.trace("Strip SourceRef into input Status commands");
198        }
199        SyncBody syncBody = message.getSyncBody();
200
201        AbstractCommand[] allClientCommands =
202            (AbstractCommand[])syncBody.getCommands().toArray(
203            new AbstractCommand[0]);
204
205        ArrayList statusList =
206            ProtocolUtil.filterCommands(allClientCommands, Status.class);
207
208        Iterator itStatusList = statusList.iterator();
209
210        Status status = null;
211        while (itStatusList.hasNext()) {
212            status = (Status)itStatusList.next();
213            SourceRef[] srefs =
214                (SourceRef[])status.getSourceRef().toArray(new SourceRef[0]);
215            int s = srefs.length;
216            for(int i=0;i<s;i++) {
217                SourceRef sr = (SourceRef)srefs[i];
218                String sourceRef = sr.getValue();
219                if (log.isTraceEnabled()) {
220                    log.trace("original sourceRef: " + sourceRef);
221                }
222
223                if (sourceRef.startsWith("./")) {
224                    String sourceRefNew = sourceRef.substring(2);
225                    if (log.isTraceEnabled()) {
226                        log.trace("new sourceRef: " + sourceRefNew);
227                    }
228                    sr.setValue(sourceRefNew);
229
230                    sourceReplacedMap.put(sourceRefNew, sourceRef);
231                }
232            }
233        }
234    }
235
236    /**
237     * Store and change Target into Sync commands
238     *
239     * @param message the client message
240     * @param sourceReplacedMap the HashMap in which store uri to replace
241     */
242    private void manageInputSync(SyncML message, HashMap sourceReplacedMap) {
243        if (log.isTraceEnabled()) {
244            log.trace("Strip TargetURI into input Sync commands");
245        }
246        SyncBody syncBody = message.getSyncBody();
247
248        AbstractCommand[] allClientCommands =
249            (AbstractCommand[])syncBody.getCommands().toArray(
250            new AbstractCommand[0]);
251
252        ArrayList syncList =
253            ProtocolUtil.filterCommands(allClientCommands, Sync.class);
254
255        Iterator itList = syncList.iterator();
256
257        Sync sync = null;
258        String targetUri = null;
259
260        while (itList.hasNext()) {
261            sync = (Sync)itList.next();
262            targetUri = sync.getTarget().getLocURI();
263            if (log.isTraceEnabled()) {
264                log.trace("original targetUri: " + targetUri);
265            }
266
267            if (targetUri.startsWith("./")) {
268                String targetNew = targetUri.substring(2);
269                if (log.isTraceEnabled()) {
270                    log.trace("new targetUri: " + targetNew);
271                }
272                sync.getTarget().setLocURI(targetNew);
273
274                sourceReplacedMap.put(targetNew, targetUri);
275            }
276        }
277    }
278
279    /**
280     * Store and change Target into Map commands
281     *
282     * @param message the client message
283     * @param sourceReplacedMap the HashMap in which store uri to replace
284     */
285    private void manageInputMap(SyncML message, HashMap sourceReplacedMap) {
286        if (log.isTraceEnabled()) {
287            log.trace("Strip TargetURI into input Map commands");
288        }
289        SyncBody syncBody = message.getSyncBody();
290
291        AbstractCommand[] allClientCommands =
292            (AbstractCommand[])syncBody.getCommands().toArray(
293            new AbstractCommand[0]);
294
295        ArrayList mapList =
296            ProtocolUtil.filterCommands(allClientCommands, Map.class);
297
298        Iterator itList = mapList.iterator();
299
300        Map map = null;
301        String targetUri = null;
302
303        while (itList.hasNext()) {
304            map = (Map)itList.next();
305            targetUri = map.getTarget().getLocURI();
306            if (log.isTraceEnabled()) {
307                log.trace("original targetUri: " + targetUri);
308            }
309
310            if (targetUri.startsWith("./")) {
311                String targetNew = targetUri.substring(2);
312
313                if (log.isTraceEnabled()) {
314                    log.trace("new targetUri: " + targetNew);
315                }
316                map.getTarget().setLocURI(targetNew);
317
318                sourceReplacedMap.put(targetNew, targetUri);
319            }
320        }
321    }
322
323    /**
324     * Replace TargetRef into Status commands
325     *
326     * @param message the client message
327     * @param sourceReplacedMap the HashMap with the uri to replace
328     */
329    private void manageOutputStatus(SyncML message, HashMap sourceReplacedMap) {
330        if (log.isTraceEnabled()) {
331            log.trace("Replace TargetRef into output Status commands");
332        }
333        SyncBody syncBody = message.getSyncBody();
334
335        AbstractCommand[] allServerCommands =
336            (AbstractCommand[])syncBody.getCommands().toArray(
337            new AbstractCommand[0]);
338
339        ArrayList statusList =
340            ProtocolUtil.filterCommands(allServerCommands, Status.class);
341
342        Iterator itStatusList = statusList.iterator();
343
344        Status status = null;
345        while (itStatusList.hasNext()) {
346            status = (Status)itStatusList.next();
347
348            if (status.getTargetRef() == null) {
349                continue;
350            }
351            TargetRef[] trefs =
352                (TargetRef[])status.getTargetRef().toArray(new TargetRef[0]);
353            int s = trefs.length;
354            for(int i=0;i<s;i++) {
355                TargetRef tr = (TargetRef)trefs[i];
356                if (sourceReplacedMap.containsKey(tr.getValue())) {
357                    tr.setValue((String)sourceReplacedMap.get(tr.getValue()));
358                }
359            }
360        }
361    }
362
363    /**
364     * Replace Source into Alert commands
365     *
366     * @param message the client message
367     * @param sourceReplacedMap the HashMap with the uri to replace
368     */
369    private void manageOutputAlert(SyncML message, HashMap sourceReplacedMap) {
370        if (log.isTraceEnabled()) {
371            log.trace("Replace Source into output Alert commands");
372        }
373        SyncBody syncBody = message.getSyncBody();
374
375        AbstractCommand[] allServerCommands =
376            (AbstractCommand[])syncBody.getCommands().toArray(
377            new AbstractCommand[0]);
378
379        ArrayList alertList =
380            ProtocolUtil.filterCommands(allServerCommands, Alert.class);
381
382        Iterator itAlertList = alertList.iterator();
383
384        Alert alert = null;
385        ArrayList items = null;
386        Iterator itItem = null;
387        Item item = null;
388        Source source = null;
389        String sourceUri = null;
390
391        while (itAlertList.hasNext()) {
392            alert = (Alert)itAlertList.next();
393            items = alert.getItems();
394            itItem = items.iterator();
395            while (itItem.hasNext()) {
396
397                item = (Item)itItem.next();
398                source = item.getSource();
399                if (source != null) {
400                    sourceUri = source.getLocURI();
401
402                    if (sourceReplacedMap.containsKey(sourceUri)) {
403                        //
404                        // Here we have to create a new Source object because
405                        // the Alert can contain the same Source used in the
406                        // engine/sessionHandler to handle the Database.
407                        // If here we change the source object of the alert we
408                        // change also the source of the database because it's
409                        // the same object!!.
410                        //
411                        //
412                        Source newSource = new Source(
413                            (String)sourceReplacedMap.get(sourceUri),
414                            source.getLocName()
415                        );
416                        item.setSource(newSource);
417                    }
418                }
419            }
420        }
421    }
422
423    /**
424     * Replace SourceRef into Results command
425     *
426     * @param message the client message
427     * @param sourceReplacedMap the HashMap with the uri to replace
428     */
429    private void manageOutputResults(SyncML message, HashMap sourceReplacedMap) {
430        if (log.isTraceEnabled()) {
431            log.trace("Replace SourceRef into output Result commands");
432        }
433        SyncBody syncBody = message.getSyncBody();
434
435        AbstractCommand[] allServerCommands =
436            (AbstractCommand[])syncBody.getCommands().toArray(
437            new AbstractCommand[0]);
438
439        List list =
440            ProtocolUtil.filterCommands(allServerCommands, Results.class);
441
442        if (list.isEmpty()) {
443            return;
444        }
445
446        Results results = (Results)list.get(0);
447
448        Item[] items = (Item[])results.getItems().toArray(new Item[0]);
449
450        if (items != null && items.length > 0) {
451            if (items[0] instanceof DevInfItem) {
452                DevInfItem item = (DevInfItem) items[0];
453                ArrayList dss = item.getDevInfData().getDevInf().getDataStores();
454                int s = dss.size();
455                for (int i = 0; i < s; i++) {
456                    DataStore ds = (DataStore) dss.get(i);
457                    String sourceRef = ds.getSourceRef().getValue();
458                    if (sourceReplacedMap.containsKey(sourceRef)) {
459                        ds.getSourceRef().setValue((String) sourceReplacedMap.
460                                get(sourceRef));
461                    }
462                }
463            }
464        }
465    }
466
467
468    /**
469     * Replace Source into Sync commands
470     *
471     * @param message the client message
472     * @param sourceReplacedMap the HashMap with the uri to replace
473     */
474    private void manageOutputSync(SyncML message, HashMap sourceReplacedMap) {
475        if (log.isTraceEnabled()) {
476            log.trace("Replace Source into output Sync commands");
477        }
478        SyncBody syncBody = message.getSyncBody();
479
480        AbstractCommand[] allServerCommands =
481            (AbstractCommand[])syncBody.getCommands().toArray(
482            new AbstractCommand[0]);
483
484        ArrayList syncList =
485            ProtocolUtil.filterCommands(allServerCommands, Sync.class);
486
487        Iterator itSyncList = syncList.iterator();
488
489        Sync sync        = null;
490        Source source    = null;
491        String sourceUri = null;
492
493        while (itSyncList.hasNext()) {
494            sync = (Sync) itSyncList.next();
495
496            source = sync.getSource();
497
498            if (source != null) {
499                sourceUri = source.getLocURI();
500
501                if (sourceReplacedMap.containsKey(sourceUri)) {
502                    //
503                    // Here we have to create a new Source object because
504                    // the Sync can contain the same Source used in the
505                    // engine/sessionHandler to handle the Database.
506                    // If here we change the source object of the sync commands we
507                    // change also the source of the database because it's
508                    // the same object!!.
509                    //
510                    //
511                    Source newSource = new Source(
512                            (String) sourceReplacedMap.get(sourceUri),
513                            source.getLocName()
514                                       );
515                    sync.setSource(newSource);
516                }
517            }
518        }
519    }
520
521}
Note: See TracBrowser for help on using the repository browser.