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

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

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

Line 
1/**
2 * Copyright (C) 2003-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.*;
19
20import com.funambol.framework.core.*;
21import com.funambol.framework.engine.pipeline.*;
22import com.funambol.framework.logging.FunambolLogger;
23import com.funambol.framework.logging.FunambolLoggerFactory;
24import com.funambol.framework.protocol.ProtocolUtil;
25
26/**
27 * This class changes the input message client deviceId with a fixed deviceId.
28 * This is done in order to allow any phone to sync without the need of adding
29 * a new device/user/principal in the SyncAdmin. This is for the sake of easy
30 * of use for beginners. To disable this behaviuor, just remove the synclet
31 * from the pipeline.
32 * The original device id will is replaced in the outgoing message so that the
33 * phone device will not notice the change.
34 *
35 * <p>The change is done only if the sync sources to sync are in the given
36 * <code>syncSourcesToProcess</code> list and the client device id is not in the
37 * <code>devicesNotToProcess</code> list.
38 *
39 * This synclet uses the following context properties:
40 * <ul>
41 *  <li>funambol.foundation.changedevice.DEVICEID_ORIG - to store the original device id</li>
42 * </ul>
43 *
44 * Note that because the Alert commands containing the syncsource to sync are
45 * given only in the first message, we have to remember if we are changing the
46 * deviceid or not for all the messages in the session. For this, we just check
47 * if clientDeviceId is already set. If not, we check for the alert; if yes, it
48 * means that we have already determined that the device id needs to be replaced,
49 * therefore we replace it without further checks.
50 *
51 * <p>If the DEVICEID_ORIG in the processingContext is null, no change is performed.
52 *
53 * @version $Id: ChangeDeviceIdSynclet.java,v 1.3 2007-01-11 19:20:19 nichele Exp $
54 */
55public class ChangeDeviceIdSynclet
56implements InputMessageProcessor, OutputMessageProcessor {
57
58    // --------------------------------------------------------------- Constants
59    private static final String PROPERTY_ORIG_ID =
60        "funambol.foundation.changedevice.DEVICEID_ORIG";
61
62    private static final String CLIENT_DEVICEID = "syncml-phone";
63
64    private static final String SYNCLET_NAME = ChangeDeviceIdSynclet.class.getName();
65
66    // ------------------------------------------------------------ Private data
67    private static final FunambolLogger log =
68            FunambolLoggerFactory.getLogger("engine.pipeline");
69
70    /**
71     * Contain the original client device Id
72     */
73    private String clientDeviceId = null;
74
75    /**
76     * Contains the uri of the sync sources to process.
77     * If in the message to process, there are a syncsource specified in the list,
78     * then the message is processed
79     */
80    private ArrayList syncSourcesToProcess = null;
81
82    /**
83     * Contains the list of the known devices of which the ID doesn't have
84     * to be changed.
85     */
86    private ArrayList devicesNotToProcess    = null;
87
88    // ---------------------------------------------------------- Public methods
89
90    /**
91     * Process input message and set MessageProcessingContext property.
92     *
93     * @param processingContext the message processing context
94     * @param message the message to be processed
95     * @throws Sync4jException
96     */
97    public void preProcessMessage(MessageProcessingContext processingContext,
98                                  SyncML message) throws Sync4jException {
99
100        if (log.isTraceEnabled()) {
101            log.trace(SYNCLET_NAME + ".preProcessMessage(...)");
102        }
103
104        boolean processMessage = true;
105
106        if (clientDeviceId == null) {
107            processMessage = checkSourceUriToSync(message);
108        }
109
110        if (log.isTraceEnabled()) {
111            log.trace(SYNCLET_NAME + " - device id replacement " + (processMessage ? "" : "not ") + "required");
112        }
113
114        if (processMessage) {
115            if (clientDeviceId == null) {
116                clientDeviceId = message.getSyncHdr().getSource().getLocURI();
117            }
118
119            if (log.isTraceEnabled()) {
120                log.trace(SYNCLET_NAME + " - original clientDeviceId '" + clientDeviceId + "'");
121            }
122
123            if (!devicesNotToProcess.contains(clientDeviceId)) {
124                Source source = message.getSyncHdr().getSource();
125                source.setLocURI(CLIENT_DEVICEID);
126                processingContext.setRequestProperty(PROPERTY_ORIG_ID, clientDeviceId);
127            }
128        }
129    }
130
131
132    /**
133     * Process and manipulate the output message.
134     *
135     * @param processingContext the message processing context
136     * @param message the message to be processed
137     * @throws Sync4jException
138     */
139    public void postProcessMessage(MessageProcessingContext processingContext,
140                                   SyncML message) throws Sync4jException {
141        if (log.isTraceEnabled()) {
142            log.trace(SYNCLET_NAME + ".postProcessMessage(...)");
143        }
144
145        if (clientDeviceId == null) {
146            clientDeviceId = (String)processingContext.getRequestProperty(PROPERTY_ORIG_ID);
147        }
148
149        //
150        // If still null, no processing is required
151        //
152         if (clientDeviceId == null) {
153            if (log.isTraceEnabled()) {
154                log.trace(SYNCLET_NAME + " - processing not required");
155            }
156        } else {
157            if (log.isTraceEnabled()) {
158                log.trace(SYNCLET_NAME + " - setting device id to '" + clientDeviceId + "'");
159            }
160
161            Target target = message.getSyncHdr().getTarget();
162            target.setLocURI(clientDeviceId);
163
164            //
165            // We have also to change the SourceRef in the SyncHdr's status
166            //
167            SyncBody body = message.getSyncBody();
168            AbstractCommand[] allServerCommands =
169                 (AbstractCommand[])body.getCommands().toArray(new AbstractCommand[0]);
170
171            ArrayList listStatus =
172                ProtocolUtil.filterCommands(allServerCommands,
173                                            Status.class);
174
175            if (listStatus != null && listStatus.size() != 0) {
176
177                Status status = (Status) listStatus.get(0);
178                List sourceRefList = status.getSourceRef();
179                if (sourceRefList != null && sourceRefList.size() != 0) {
180                    SourceRef sourceRef =
181                            (SourceRef)sourceRefList.get(0);
182                    sourceRef.setValue(clientDeviceId);
183                }
184            }
185        }
186
187    }
188
189    /**
190     * Set the syncSourcesToProcess
191     * @param list the syncSourcesToProcess
192     */
193    public void setSyncSourcesToProcess(ArrayList list) {
194        this.syncSourcesToProcess = list;
195    }
196
197    /**
198     * Set the devicesNotToProcess
199     *
200     * @param list the devicesNotToProcess
201     */
202    public void setDevicesNotToProcess(ArrayList list) {
203        this.devicesNotToProcess = list;
204    }
205
206    // --------------------------------------------------------- Private Methods
207
208    /**
209     * Checks if the sync sources that are in the syncml message are present
210     * in the list <code>syncSourcesToProcess</code>
211     *
212     * @param message the message to process
213     * @return boolean
214     */
215    private boolean checkSourceUriToSync(SyncML message) {
216
217        if (syncSourcesToProcess == null) {
218            return false;
219        }
220
221        SyncBody syncBody = message.getSyncBody();
222
223        AbstractCommand[] allClientCommands =
224            (AbstractCommand[])syncBody.getCommands().toArray(
225            new AbstractCommand[0]);
226
227        ArrayList alertList = ProtocolUtil.filterCommands(allClientCommands,
228            Alert.class);
229
230        Iterator itAlertList = alertList.iterator();
231
232        Alert alert = null;
233        ArrayList items = null;
234        Iterator itItem = null;
235        Item item = null;
236        Target target = null;
237        String sourceUri = null;
238
239        while (itAlertList.hasNext()) {
240            alert = (Alert)itAlertList.next();
241            items = alert.getItems();
242            itItem = items.iterator();
243            while (itItem.hasNext()) {
244
245                item = (Item)itItem.next();
246                target = item.getTarget();
247                if (target != null) {
248                    sourceUri = target.getLocURI();
249
250                    if (syncSourcesToProcess.indexOf(sourceUri) != -1) {
251                        // the source uri is present in the list of the
252                        // sync source to process
253                        return true;
254                    }
255                }
256            }
257        }
258        return false;
259    }
260
261}
Note: See TracBrowser for help on using the repository browser.