⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sync4jstrategy.java

📁 实现了SyncML无线同步协议
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/** * Copyright (C) 2003-2004 Funambol * *  This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  */package sync4j.server.engine;import java.util.List;import java.util.Arrays;import java.util.Iterator;import java.util.ArrayList;import java.util.Collection;import java.util.logging.*;import java.security.Principal;import java.sql.Timestamp;import sync4j.framework.core.ModificationCommand;import sync4j.framework.core.StatusCode;import sync4j.framework.engine.source.SyncSource;import sync4j.framework.engine.source.SyncSourceException;import sync4j.framework.engine.*;import sync4j.server.engine.SyncItemHelper;import sync4j.server.engine.Sync4jOperationStatusOK;import sync4j.server.engine.Sync4jOperationStatusError;import sync4j.server.engine.Sync4jOperationStatusConflict;import org.apache.commons.collections.ListUtils;/** * This class represents a synchronization process. * * The base concrete implementation of a synchronization strategy. It implements * the <i>ConcreteStrategy</i> partecipant of the Strategy Pattern. * <p> * The synchronization process is implemented in this class as follows: * <p> * Given a set of sources A, B, C, D, etc, the synchronization process takes place  * between two sources at a time: A is first synchronzed with B, then AB with * C, then ABC with D and so on. <br> * The synchronization process is divided in three phases: preparation, synchronization, * finalization. These phases correspond to the methdos prepareSync, sync and * endSync; they are call-back methods called sequentially by a driver object, * usually a SyncMethod object. In this way the SyncMethod object has a chance  * to communicate with the external world before carry on the process.  * For example a SyncMethod object can show to the user the items that are going * to be synchronized, so that the user can let the process carry on or stop it. <br> * prepareSync returns an array of SyncOperation, in which each element represents * a particular synchronization action, ie. create an item in the source A, * delete the item X from the source B, etc. Sometime it is not possible decide  * what to do, thus a SyncConflict operation is used. A conflict must be solved * by something external the synchronization process, for instance by a user * action. Below is a table of all possible situations. * <pre> * * | -------- | --- | --- | --- | --- | --- | * | Source A |     |     |     |     |     | * |    /     |  N  |  D  |  U  |  S  |  X  |     N : item new * | Source B |     |     |     |     |     |     D : item deleted * | -------- | --- | --- | --- | --- | --- |     U : item updated * |       N  |  O  |  O  |  O  |  O  |  B  |     S : item synchronized/unchanged * | -------- | --- | --- | --- | --- | --- |     X : item not existing * |       D  |  O  |  X  |  O  |  X  |  X  |     O : conflict * | -------- | --- | --- | --- | --- | --- |     A : item A replaces item B * |       U  |  O  |  O  |  O  |  B  |  B  |     B : item B replaces item A * | -------- | --- | --- | --- | --- | --- | * |       S  |  O  |  X  |  A  |  =  |  B  | * | -------- | --- | --- | --- | --- | --- | * |       X  |  A  |  X  |  A  |  A  |  X  | * | -------- | --- | --- | --- | --- | --- | * * </pre> * * @author Stefano Fornari @ Funambol *  * @version  $Id: Sync4jStrategy.java,v 1.25 2004/04/13 09:35:29 luigia Exp $ */public class Sync4jStrategy implements SyncStrategy, java.io.Serializable {        // --------------------------------------------------------------- Constants        public static String LOG_NAME = "sync4j.framework.engine";        private transient static Logger log = Logger.getLogger(LOG_NAME);        // -------------------------------------------------------------- Properties        /**     * The synchronization source      */    private transient SyncSource[] sources = null;     public SyncSource[] getSources(){ return sources; }    public void setSources(SyncSource[] sources){ this.sources = sources; }    /**     * The process' name     */    public String getName(){ return name; }    private String name;    public void setName(String name){ this.name = name; }        // ------------------------------------------------------------ Constructors        public Sync4jStrategy() {    }        public Sync4jStrategy(SyncSource[] syncSources) {        sources = syncSources;    }        // ---------------------------------------------------------- Public methods        /**     * Preparation for the synchronization. If <i>sources</i> is not null,     * the preparation works on the given sources. Otherwise it works on the      * sources as they were set in the constructor.     *     * @param sources the sources to be synchronized     * @param principal the entity for which the synchronization is required     *     * @return an array of SyncOperation, one for each SyncItem that must be     *         created/updated/deleted or in conflict.     *     * @see sync4j.framework.engine.SyncStrategy     */    public SyncOperation[] prepareSlowSync(SyncSource[] sources  ,                                            Principal    principal)     throws SyncException {                SyncItem[] allA = null, allB = null;                if (sources != null) {            this.sources = sources;        }                List syncOperations = null           ,             Am             = new ArrayList(),             Bm             = new ArrayList(),             AmBm           = null           ;        Logger log = Logger.getLogger(LOG_NAME);                if (log.isLoggable(Level.INFO)) {            log.info("Preparing slow synchronization for " + principal + " ...");        }                    allA = sources[1].getAllSyncItems(principal);        allB = sources[0].getAllSyncItems(principal);                         //        // Because it is a slow sync, items state must be reset to S        //        EngineHelper.resetState(Arrays.asList(allA));        EngineHelper.resetState(Arrays.asList(allB));                //        // If any item from the client has not a corresponding mapping, the         // server source must be queried for the item, since the client item         // could be the same of an existing server item. In this case,  the old        // unmapped item is replaced in Map by the newly mapped item.        //        ArrayList newlyMappedItems = new ArrayList();                        fixMappedItems(newlyMappedItems, allA, sources[0], principal, true);                        Am.addAll(Arrays.asList(allA));        Bm.addAll(Arrays.asList(allB));                AmBm = EngineHelper.intersect(Am, Bm);                if (log.isLoggable(Level.FINEST)) {            log.finest("Am: "   + Am  );            log.finest("Bm: "   + Bm  );            log.finest("AmBm: " + AmBm);        }                syncOperations =             checkSyncOperations(principal, Am, Bm, AmBm, new ArrayList(), new ArrayList());                //        // In the case of slow sync, delete operations are not needed        //        SyncOperation o = null;                ArrayList ret = new ArrayList();                Iterator i = syncOperations.iterator();        while (i.hasNext()) {            o = (SyncOperation)i.next();                        if (o.getOperation() != SyncOperation.DELETE) {                ret.add(o);            }        }                if (log.isLoggable(Level.FINEST)) {            log.finest("operations: " + ret);        }                log.info("Preparation completed.");                return (SyncOperation[])ret.toArray(new SyncOperationImpl[] {});    }        /**     * Preparation for faset synchronization. If <i>sources</i> is not null,     * the preparation operates on the given sources. Otherwise it works on the      * sources as they were set in the constructor.     * <p>     * Refer to the <a href="http://sync4j.sourceforge.net/web/project/architecture/sync4j-architecture.html">     * architecture document</a> for details about the algoritm applied.     *     * @param sources the sources to be synchronized     * @param principal the entity for which the synchronization is required     *     * @return an array of SyncOperation, one for each SyncItem that must be     *         created/updated/deleted or in conflict.     *     * @see sync4j.framework.engine.SyncStrategy     */    public SyncOperation[] prepareFastSync(SyncSource[] sources  ,                                            Principal    principal,                                           Timestamp    since    )     throws SyncException {        if (sources != null) {            this.sources = sources;        }                // ---------------------------------------------------------------------                List Am    ,  // items modified in A             Bm    ,  // items modified in B             AmBm  ,  // Am intersect Bm             AAmBm ,  // items unmodified in A, but modified in B             AmBBm ;  // items unmodified in B, but modified in A                ArrayList syncOperations = null;        SyncItem[] newA       = null, newB       = null,                   updatedA   = null, updatedB   = null,                   deletedA   = null, deletedB   = null;        if (log.isLoggable(Level.INFO)) {            log.info( "Preparing fast synchronization for "                    + principal                    + " since "                    + since                    );        }                // ---------------------------------------------------------------------        //        // NOTE: simplified version - only two sources, the first one of which         // is the client        //        newA       = sources[1].getNewSyncItems      (principal, since);        updatedA   = sources[1].getUpdatedSyncItems  (principal, since);        deletedA   = sources[1].getDeletedSyncItems  (principal, since);        newB       = sources[0].getNewSyncItems      (principal, since);        updatedB   = sources[0].getUpdatedSyncItems  (principal, since);        deletedB   = sources[0].getDeletedSyncItems  (principal, since);        if (log.isLoggable(Level.FINEST)) {            log.finest("newA: " + Util.arrayToString(newA));            log.finest("newB: " + Util.arrayToString(newB));            log.finest("updatedA: " + Util.arrayToString(updatedA));            log.finest("updatedB: " + Util.arrayToString(updatedB));            log.finest("deletedA: " + Util.arrayToString(deletedA));            log.finest("deletedB: " + Util.arrayToString(deletedB));        }                //        // If any item from the client has not a corresponding mapping, the         // server source must be queried for the item, since the client item         // could be the same of an existing server item. In this case,  the old        // unmapped item is replaced in Ma by the newly mapped item.        //        ArrayList newlyMappedItems = new ArrayList();                fixMappedItems(newlyMappedItems, newA,     sources[0], principal, false);        fixMappedItems(newlyMappedItems, updatedA, sources[0], principal, false);        fixMappedItems(newlyMappedItems, deletedA, sources[0], principal, false);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -