KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > sync4j > framework > protocol > SyncModifications


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.framework.protocol;
20
21 import java.util.List JavaDoc;
22 import java.util.ArrayList JavaDoc;
23
24 import sync4j.framework.core.*;
25 import sync4j.framework.database.Database;
26
27 import sync4j.framework.protocol.ProtocolUtil;
28 import sync4j.framework.protocol.v11.SyncModificationsRequirements;
29
30 /**
31  * Represents a Client Modification package of the SyncML protocol.
32  *
33  * The class is designed to be used in two times. First a <i>ClientModification</i>
34  * is created and checked for validity and compliancy with the protocol. Than
35  * <i>getResponse()</i> can be used to get a response message for the given
36  * request. During the request validation process some information about the
37  * request message are cached into instance variables and used in <i>getResponse()</i>.<br>
38  *
39  * @author Stefano Fornari @ Funambol
40  *
41  * @version $Id: SyncModifications.java,v 1.3 2005/03/02 20:57:38 harrie Exp $
42  */

43 public class SyncModifications extends SyncPackage implements Flags {
44     
45     // ------------------------------------------------------------ Constructors
46

47     /** Constructors. It creates a new instance from the message header and body
48      * plus the databases to synchronize.
49      * It also checks if the requirements specified by the SyncML protocol are
50      * met; if not a Sync4jException is thrown.
51      * @param syncHeader the header of the syncronization packet
52      * @param syncBody the body of the syncronization packet
53      * @param syncDb the array of databases to be synchronized
54      * @throws Sync4jException in case SyncML requiremets are not respected
55      */

56     public SyncModifications(final SyncHdr syncHeader, final SyncBody syncBody, Database[] syncDb) throws Sync4jException {
57         super(syncHeader, syncBody);
58         checkRequirements();
59         databases = syncDb;
60     }
61     
62     public SyncModifications(final SyncHdr syncHeader, final SyncBody syncBody) throws Sync4jException {
63         super(syncHeader, syncBody);
64     }
65     
66     // -------------------------------------------------------------- Properties
67

68     /**
69      * Has the server sent its capabilities and is expecting a response?
70      * If yes, <i>serverCapabilitiesCmdId</i> is set to the id of the Put command
71      * sent by the server. If not, <i>serverCapabilitiesCmdId</i> is empty.
72      */

73     private CmdID serverCapabilitiesCmdId = null;
74     
75     /**
76      * Returns the serverCapabilitiesCmdId property.
77      *
78      * @return the serverCapabilitiesCmdId property.
79      */

80     public CmdID getServerCapabilitiesCmdId() {
81         return this.serverCapabilitiesCmdId;
82     }
83     
84     /**
85      * Sets the serverCapabilitiesCmdId property.
86      *
87      * @param serverCapabilitiesCmdId new value
88      */

89     public void setServerCapabilitiesCmdId(CmdID serverCapabilitiesCmdId) {
90         this.serverCapabilitiesCmdId = serverCapabilitiesCmdId;
91     }
92     
93     /**
94      * Has the server requested client capabilities?
95      * If yes, <i>clientCapabilitiesCmdId</i> is set to the id of the Get command
96      * sent by the server. If not, <i>clientCapabilitiesCmdId</i> is empty.
97      */

98     private CmdID clientCapabilitiesCmdId = null;
99     
100     /**
101      * Returns the clientCapabilitiesCmdId property.
102      *
103      * @return the clientCapabilitiesCmdId property.
104      */

105     public CmdID getClientCapabilitiesCmdId() {
106         return this.clientCapabilitiesCmdId;
107     }
108     
109     /**
110      * Sets the serverCapabilitiesCmdId property.
111      * @param clientCapabilitiesCmdId new value
112      */

113     public void setClientCapabilitiesCmdId(CmdID clientCapabilitiesCmdId) {
114         this.clientCapabilitiesCmdId = clientCapabilitiesCmdId;
115     }
116     
117     /**
118      * The results command in response to the request of client capabilities
119      */

120     private Results clientCapabilitiesResults = null;
121     
122     /**
123      * Returns the clientCapabilitiesResults property.
124      *
125      * @return the clientCapabilitiesResults property.
126      */

127     public Results getClientCapabilitiesResults() {
128         return this.clientCapabilitiesResults;
129     }
130     
131     /**
132      * The status command in response to the sending of server capabilities
133      */

134     private Status serverCapabilitiesStatus = null;
135     
136     /**
137      * Returns the serverCapabilitiesStatus property.
138      *
139      * @return the serverCapabilitiesStatus property.
140      */

141     public Status getServerCapabilitiesStatus() {
142         return this.serverCapabilitiesStatus;
143     }
144     
145     /**
146      * The client Sync command identifier. It is used when a response is required.
147      */

148     private CmdID clientSyncCmdId = null;
149     
150     /**
151      * Returns the clientSyncCmdId property.
152      *
153      * @return the clientSyncCmdId property.
154      */

155     public CmdID getClientSyncCmdId() {
156         return this.clientSyncCmdId;
157     }
158     
159     /**
160      * Sets the clientSyncCmdId property.
161      *
162      * @param clientSyncCmdId new value
163      */

164     public void setClientSyncCmdId(CmdID clientSyncCmdId) {
165         this.clientSyncCmdId = clientSyncCmdId;
166     }
167     
168     /**
169      * The modification commands the server wants to sent to the client.
170      */

171     private AbstractCommand[] serverModifications = null;
172     
173     /**
174      * Returns the serverModifications property.
175      *
176      * @return the serverModifications property.
177      */

178     public AbstractCommand[] getServerModifications() {
179         return this.serverModifications;
180     }
181     
182     /**
183      * Sets the serverModifications property.
184      *
185      * @param serverModifications new value
186      */

187     public void setServerModifications(AbstractCommand[] serverModifications) {
188         this.serverModifications = serverModifications;
189     }
190     
191     /**
192      * The status to be returned for the client sync command.
193      */

194     private Status[] clientModificationsStatus = null;
195     
196     /**
197      * Returns the clientModificationsStatus property.
198      *
199      * @return the clientModificationsStatus property.
200      */

201     public Status[] getClientModificationsStatus() {
202         return this.clientModificationsStatus;
203     }
204     
205     /**
206      * Sets the clientModificationsStatus property.
207      *
208      * @param clientModificationsStatus new value
209      */

210     public void setClientModificationsStatus(Status[] clientModificationsStatus) {
211         this.clientModificationsStatus = clientModificationsStatus;
212     }
213     
214     /**
215      * Caches the commands sent by the client. It is set during the
216      * checking of the requirements.
217      */

218     private AbstractCommand[] clientCommands = null;
219
220     /**
221      * Returns the clientCommands property.
222      *
223      * @return the clientCommands property.
224      */

225     public AbstractCommand[] getClientCommands() {
226         return clientCommands;
227     }
228         
229     /**
230      * Caches the SyncCommand sent by the client. It is set during the checking
231      * of requirements.
232      */

233     private Sync[] clientSyncCommands = null;
234     
235     /**
236      * Returns the clientSyncCommands property.
237      *
238      * @return the clientSyncCommands property.
239      */

240     public Sync[] getClientSyncCommands() {
241         return this.clientSyncCommands;
242     }
243    
244     /**
245      * Databases that the server wants to synchronize.
246      */

247     private Database[] databases = null;
248
249     /**
250      * Sets the databases property.
251      *
252      * @param databases new value
253      */

254     public void setDatabases(Database[] databases) {
255         this.databases = databases;
256     }
257
258     /**
259      * Returns the databases property.
260      *
261      * @return the databases property.
262      */

263     public Database[] getDatabases() {
264         return this.databases;
265     }
266     
267     /**
268      * The alert commands the server wants to sent to the client.
269      */

270     private Alert[] modificationsAlert = null;
271     
272     /**
273      * Returns the alertModifications property.
274      *
275      * @return the alertModifications property.
276      */

277     public Alert[] getModificationsAlert() {
278         return this.modificationsAlert;
279     }
280     
281     /**
282      * Sets the alertModifications property.
283      *
284      * @param alertModifications new value
285      */

286     public void setModificationsAlert(Alert[] modificationsAlert) {
287         this.modificationsAlert = modificationsAlert;
288     }
289
290     // ---------------------------------------------------------- Public methods
291

292     /** Checks that all requirements regarding the header of the initialization
293      * packet are respected.
294      * @throws ProtocolException if header requirements are not respected
295      */

296     public void checkHeaderRequirements() throws ProtocolException {
297         SyncModificationsRequirements.checkDTDVersion (syncHeader.getVerDTD() );
298         SyncModificationsRequirements.checkProtocolVersion(syncHeader.getVerProto() );
299         SyncModificationsRequirements.checkSessionId (syncHeader.getSessionID());
300         SyncModificationsRequirements.checkMessageId (syncHeader.getMsgID() );
301         SyncModificationsRequirements.checkTarget (syncHeader.getTarget() );
302         SyncModificationsRequirements.checkSource (syncHeader.getSource() );
303     }
304     
305     /** Checks that all requirements regarding the body of the initialization
306      * packet are respected.
307      *
308      * NOTE: bullet 2 pag 34 is not clear. Ignored for now.
309      * @throws ProtocolException if body requirements are not respected
310      */

311     public void checkBodyRequirements() throws ProtocolException {
312         // NOTE: initializes the clientCommands property
313
clientCommands = (AbstractCommand[])syncBody.getCommands().toArray(new AbstractCommand[0]);
314         
315         //
316
// If the server sent the device information to the client and requested
317
// a response, serverCapabilitiesCmdId contains the command id of the
318
// request command. A Status command with the same cmd id reference
319
// must exist.
320
//
321
checkServerCapabilitiesStatus();
322         
323         //
324
// If the server requested the device capabilities of the client,
325
// clientCapabilitiesCmdId contains the command id of the Get command.
326
// A Results command with the same cmd id reference must exist.
327
//
328
checkClientCapabilitiesResult();
329
330         //
331
// The Sync command must exists
332
//
333
checkSyncCommand();
334     }
335         
336     /**
337      * Constructs a proper response message.<p>
338      * The sync package to the client has the following purposes:
339      * <ul>
340      * <li>To inform the client about the results of sync analysis.
341      * <li>To inform about all data modifications, which have happened in the
342      * server since the previous time when the server has sent the
343      * modifications to the client.
344      * </ul>
345      *
346      * @param msgId the msg id of the response
347      * @return the response message
348      *
349      * @throws ProtocolException in case of error or inconsistency
350      */

351     public SyncML getResponseMessage(String JavaDoc msgId)
352     throws ProtocolException {
353         SyncHdr responseHeader = getResponseHeader(msgId);
354         AbstractCommand[] commands =
355             (AbstractCommand[])getResponseCommands(msgId).toArray(new AbstractCommand[0]);
356         
357         SyncBody responseBody = new SyncBody(
358                                    commands,
359                                     isFlag(FLAG_FINAL_MESSAGE) /* final */
360                                 );
361
362         try {
363             return new SyncML(responseHeader, responseBody);
364         } catch (RepresentationException e) {
365             //
366
// It should never happen !!!!
367
//
368
throw new ProtocolException("Unexpected error", e);
369         }
370     }
371     
372     /**
373      * Returns the response commands in response to the incoming synchronization
374      * message.
375      *
376      * @param msgId the message id to use
377      *
378      * @return an array of AbstractCommand
379      *
380      * @throws ProtocolException in case of errors
381      */

382     public List JavaDoc getResponseCommands(String JavaDoc msgId) throws ProtocolException {
383         ArrayList JavaDoc commandList = new ArrayList JavaDoc();
384         
385         assert(idGenerator != null);
386         
387         //
388
// Constructs all required response commands.
389
//
390
// NOTE: if NoResp is specified in the header element, than no
391
// response commands must be returned regardless NoResp is
392
// specified or not in subsequent commands
393
//
394
if (syncHeader.isNoResp() == false) {
395
396             TargetRef[] targetRefs = new TargetRef[] { new TargetRef(syncHeader.getTarget().getLocURI()) };
397             SourceRef[] sourceRefs = new SourceRef[] { new SourceRef(syncHeader.getSource().getLocURI()) };
398
399             Status statusCommand = new Status(
400                                               idGenerator.next() ,
401                                               syncHeader.getMsgID() ,
402                                               "0" /* command ref */ ,
403                                               "SyncHdr" /* see SyncML specs */ ,
404                                               targetRefs ,
405                                               sourceRefs ,
406                                               null /* credential */ ,
407                                               null /* challenge */ ,
408                                               new Data(StatusCode.OK) ,
409                                               new Item[0]
410                                           );
411
412             commandList.add(statusCommand);
413         
414             //
415
// 2. The Status element MUST be included in SyncBody if requested by
416
// the client. It is now used to indicate the general status of
417
// the sync analysis and the status information related to data
418
// items sent by the client (e.g., a conflict has happened.).
419
//
420
for (int i=0; ( isFlag(FLAG_SYNC_STATUS_REQUIRED)
421                           && (clientModificationsStatus != null)
422                           && (i<clientModificationsStatus.length) ); ++i) {
423                 commandList.add(clientModificationsStatus[i]);
424             }
425             
426             //
427
// Create Status command for client Alerts which have a code that
428
// isn't an initialization code
429
//
430
for (int i=0; clientCommands != null && i<clientCommands.length; ++i) {
431                 if (clientCommands[i] instanceof Alert) {
432                     if (AlertCode.isInitializationCode(((Alert)clientCommands[i]).getData())) {
433                         continue;
434                     }
435                     Item[] items =
436                         (Item[])((ItemizedCommand)clientCommands[i]).getItems().toArray(new Item[0]);
437
438                     ArrayList JavaDoc trefs = new ArrayList JavaDoc();
439                     ArrayList JavaDoc srefs = new ArrayList JavaDoc();
440                     Target t;
441                     Source s;
442                     for (int j=0; j<items.length; ++j) {
443                         t = items[j].getTarget();
444                         s = items[j].getSource();
445
446                         if (t != null) {
447                             trefs.add(new TargetRef(t));
448                         }
449                         if (s != null) {
450                             srefs.add(new SourceRef(s));
451                         }
452                     } // next j
453

454                     if (trefs.size() > 0) {
455                         targetRefs = (TargetRef[])trefs.toArray(new TargetRef[trefs.size()]);
456                     }
457                     if (srefs.size() > 0) {
458                         sourceRefs = (SourceRef[])srefs.toArray(new SourceRef[srefs.size()]);
459                     }
460
461                     Status status = new Status(
462                         idGenerator.next(),
463                         syncHeader.getMsgID(),
464                         clientCommands[i].getCmdID().getCmdID(),
465                         clientCommands[i].getName(),
466                         targetRefs,
467                         sourceRefs,
468                         null,
469                         null,
470                         new Data(StatusCode.OK),
471                         new Item[0]
472                     );
473                     commandList.add(status);
474                 }//end if Alert
475
}//end for clientCommands
476
}
477         
478         //
479
// The Alert element, if present, MUST be included in SyncBody.
480
//
481
for (int i=0; ((modificationsAlert != null) && (i<modificationsAlert.length)); ++i) {
482             commandList.add(modificationsAlert[i]);
483         }
484         
485         //
486
// 3. The Sync element MUST be included in SyncBody, if earlier there
487
// were no occurred errors, which could prevent the server to process
488
// the sync analysis and to send its modifications back to the client.
489
//
490
for (int i=0; ((serverModifications != null) && (i<serverModifications.length)); ++i) {
491             commandList.add(serverModifications[i]);
492         }
493         
494         return commandList;
495     }
496     
497     /**
498      * Create a Status command for the Sync sent by the client.
499      *
500      * <b>NOTE</b>: the protocol does not specify any information about the format
501      * and the content of this message. By now a dummy status command is created
502      * and returned.
503      *
504      * @return a StatusCommand object
505      */

506     public Status createSyncStatusCommand() {
507         return new Status( idGenerator.next(),
508                             "0" /* message id; TO DO */ ,
509                             clientSyncCmdId.getCmdID() ,
510                             Sync.COMMAND_NAME ,
511                             (TargetRef[])null /* target refs */ ,
512                             (SourceRef[])null /* source refs */ ,
513                             null /* credential */ ,
514                             null /* chal */ ,
515                             null /* Data */ ,
516                             null /* items */
517         );
518         
519     }
520     
521     /** For the Sync element, there are the following requirements.
522      * <ul>
523      * <li> CmdID is required.
524      * <li> The response can be required for the Sync command. (See the Caching of Map Item,
525      * Chapter 2.3.1)
526      * <li> Target is used to specify the target database.
527      * <li> Source is used to specify the source database.
528      * </ul>
529      *
530      * 5. If there is any modification in the server after the previous sync,
531      * there are following requirements for the operational elements (e.g.,
532      * Replace, Delete, and Add 4 ) within the Sync element.
533      * <ul>
534      * <li> CmdID is required.
535      * <li> The response can be required for these operations.
536      * <li> Source MUST be used to define the temporary GUID (See Definitions)
537      * of the data item in the server if the operation is an addition.
538      * If the operation is not an addition, Source MUST NOT be included.
539      * <li> Target MUST be used to define the LUID (See Definitions) of the
540      * data item if the operation is not an addition. If the operation is
541      * an addition, Target MUST NOT be included.
542      * <li> The Data element inside Item is used to include the data itself if
543      * the operation is not a seletion.
544      * <li> The Type element of the MetaInf DTD MUST be included in the Meta
545      * element to indicate the type of the data item (E.g., MIME type).
546      * The Meta element inside an operation or inside an item can be used.
547      * </ul>
548      * @param db the database to be synchronized
549      * @return a Sync command
550      * @throws ProtocolException if any protocol requirement is not respected
551      */

552     public Sync createSyncCommand(Database db)
553     throws ProtocolException {
554         CmdID syncId = idGenerator.next();
555         
556         AbstractCommand[] commands = null;
557
558         // if db.getMethod is One_Way_Sync_CLIENT
559
// no synccommand from Server to Client
560

561         if(db.getMethod() != AlertCode.ONE_WAY_FROM_CLIENT){
562                 commands = prepareCommands(db);
563         }
564         
565         return new Sync(
566             syncId ,
567             isFlag(FLAG_SYNC_RESPONSE_REQUIRED),
568             null , /* credentials */
569             db.getTarget() ,
570             db.getSource() ,
571             null , /* Meta */
572             new Long JavaDoc(0) ,
573             commands
574         );
575             
576     }
577     
578     /**
579      * Returns an array of synchronization commands (Add, Copy, Delete, Exec,
580      * Replace) based on the content of the given database.
581      *
582      * @param db the database to be synchronized
583      *
584      * @return an array of AbstractCommand
585      */

586     public AbstractCommand[] prepareCommands(Database db) {
587         ArrayList JavaDoc commands = new ArrayList JavaDoc();
588         
589         Meta meta = new Meta();
590         meta.setType(db.getType());
591         
592         Item[] items = null; // reused many times
593

594         //
595
// Add
596
//
597
items = db.getAddItems();
598         if (items != null) {
599             commands.add(
600                 new Add(
601                     idGenerator.next() ,
602                     isFlag(FLAG_MODIFICATIONS_RESPONSE_REQUIRED),
603                     null /* credentials */ ,
604                     meta ,
605                     items )
606             );
607         }
608         
609         //
610
// Copy
611
//
612
items = db.getCopyItems();
613         if (items != null) {
614             commands.add(
615                 new Copy(
616                     idGenerator.next() ,
617                     isFlag(FLAG_MODIFICATIONS_RESPONSE_REQUIRED),
618                     null /* credentials */ ,
619                     meta ,
620                     items )
621             );
622         }
623         
624         //
625
// Delete
626
//
627
items = db.getDeleteItems();
628         if (items != null) {
629             commands.add(
630                 new Delete(
631                     idGenerator.next() ,
632                     isFlag(FLAG_MODIFICATIONS_RESPONSE_REQUIRED),
633                     isFlag(FLAG_ARCHIVE_DATA) ,
634                     isFlag(FLAG_SOFT_DELETE) ,
635                     null /* credentials */ ,
636                     meta ,
637                     items )
638             );
639         }
640         
641         //
642
// Exec
643
//
644
items = db.getExecItems();
645         
646         for (int i=0; ((items != null) && (i<items.length)); ++i) {
647             commands.add(
648                 new Exec(
649                     idGenerator.next() ,
650                     isFlag(FLAG_MODIFICATIONS_RESPONSE_REQUIRED),
651                     null /* credentials */ ,
652                     items[i] )
653             );
654         }
655         
656         //
657
// Replace
658
//
659
items = db.getReplaceItems();
660         if (items != null) {
661             commands.add(
662                 new Replace(
663                     idGenerator.next() ,
664                     isFlag(FLAG_MODIFICATIONS_RESPONSE_REQUIRED),
665                     null /* credentials */ ,
666                     meta ,
667                     items )
668             );
669         }
670
671         int size = commands.size();
672         AbstractCommand [] aCommands = new AbstractCommand[size];
673         for (int i=0; i < size; i++) {
674             aCommands[i] = (AbstractCommand)commands.get(i);
675         }
676         return aCommands;
677     }
678     
679     /**
680      * Returns the response SyncHdr to return in response of the incoming SyncML
681      * message.
682      *
683      * @param msgId the message id to use
684      *
685      * @return the SyncHdr object
686      *
687      * @thorws ProtocolException in case of errors
688      */

689     public SyncHdr getResponseHeader(String JavaDoc msgId)
690     throws ProtocolException {
691         Target target = new Target(syncHeader.getSource().getLocURI(),
692                                    syncHeader.getSource().getLocName());
693         Source source = new Source(syncHeader.getTarget().getLocURI(),
694                                    syncHeader.getTarget().getLocName());
695         return new SyncHdr (
696                    getDTDVersion() ,
697                    getProtocolVersion() ,
698                    syncHeader.getSessionID(),
699                    msgId ,
700                    target ,
701                    source ,
702                    null /* response URI */ ,
703                    false ,
704                    null /* credentials */ ,
705                    null /* meta data */
706                );
707     }
708     
709     // --------------------------------------------------------- Private methods
710

711     /**
712      * Checks if the requested status for server capabilities has been specified.
713      * <p>
714      *
715      * @throws ProtocolException
716      */

717     private void checkServerCapabilitiesStatus()
718     throws ProtocolException {
719         //
720
// If serverCapabilitiesCmdId is null no serverCapabilities status is required
721
//
722
if (serverCapabilitiesCmdId == null) return;
723         
724         List JavaDoc list = ProtocolUtil.filterCommands(clientCommands ,
725                                                 Status.class ,
726                                                 serverCapabilitiesCmdId);
727         
728         if (list.size() == 0) {
729             Object JavaDoc[] args = new Object JavaDoc[] { serverCapabilitiesCmdId.getCmdID() };
730             throw new ProtocolException(SyncModificationsRequirements.ERRMSG_MISSING_STATUS_COMMAND, args);
731         }
732         
733         serverCapabilitiesStatus = (Status)list.get(0);
734     }
735     
736     /**
737      * Checks if the result for client capabilities has been given.
738      * <p>
739      *
740      * @throws ProtocolException
741      */

742     private void checkClientCapabilitiesResult()
743     throws ProtocolException {
744         //
745
// If clientCapabilitiesCmdId is null no client capabilities were required
746
//
747
if (clientCapabilitiesCmdId == null) return;
748         
749         List JavaDoc list = ProtocolUtil.filterCommands(clientCommands ,
750                                                 Results.class ,
751                                                 clientCapabilitiesCmdId);
752         
753         if (list.size() == 0) {
754             Object JavaDoc[] args = new Object JavaDoc[] { clientCapabilitiesCmdId.getCmdID() };
755             throw new ProtocolException(SyncModificationsRequirements.ERRMSG_MISSING_RESULTS_COMMAND, args);
756         }
757         
758         Results results = (Results)list.get(0);
759         
760         SyncModificationsRequirements.checkCapabilities(
761             results,
762             SyncModificationsRequirements.CLIENT_CAPABILITIES
763         );
764         
765         clientCapabilitiesResults = results;
766     }
767     
768     /**
769      * Checks the Sync command.
770      * <p>Filters out the Sync Messages from client to Server with
771      * ONE_WAY_SYNC_SERVER
772      *
773      * @throws ProtocolException
774      */

775     private void checkSyncCommand()
776     throws ProtocolException {
777         List JavaDoc list = ProtocolUtil.filterCommands(clientCommands ,
778                                                 Sync.class);
779         
780         if (list.size() == 0) {
781             clientSyncCommands = new Sync[0];
782             return;
783         }
784
785         clientSyncCommands = (Sync[])list.toArray(new Sync[list.size()]);
786     }
787 }
788
789
Popular Tags