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

📄 enginehelper.java

📁 实现了SyncML无线同步协议
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/** * 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.*;import java.util.Map;import java.util.logging.Logger;import java.util.logging.Level;import java.sql.Timestamp;import java.security.Principal;import sync4j.framework.core.*;import sync4j.framework.protocol.CommandIdGenerator;import sync4j.framework.engine.SyncOperationStatus;import sync4j.framework.engine.SyncOperation;import sync4j.framework.engine.SyncItemKey;import sync4j.framework.engine.SyncItem;import sync4j.framework.engine.SyncItemImpl;import sync4j.framework.engine.SyncProperty;import sync4j.framework.engine.SyncItemMapping;import sync4j.framework.engine.SyncItemState;import sync4j.framework.engine.SyncConflict;import sync4j.framework.engine.source.*;import sync4j.framework.server.ClientMapping;import sync4j.framework.server.error.MappingException;import sync4j.framework.logging.Sync4jLogger;import sync4j.server.engine.Sync4jOperationStatus;/** * This class collects helper methods used by the engine. * * @author  Stefano Fornari */public class EngineHelper {    public static Logger log = Sync4jLogger.getLogger(Sync4jEngine.LOG_NAME);     /**      * Status are grouped as per their original commands and status code so      * that the number of returned status will be minimal. This is done by      * generating an hash map where the key is a couple      * <i>(original command id, status code)</i> and the value is the      * <i>StatusCommand</i> object. Finally the hash map is iterated over to      * return the status commands array.<br>      * Note that Sync4jOperationStatus's command is meaningful only for items      * that derive from a SyncML command. If the associated command is null,      * there is no need to generate a status. Of course, also if the command was      * flagged as "noResponse" no status is required.      *      * @param operationStatus the status object returned as the result of      *        commands execution      * @param msgId the message id      * @param the command id generator      *      * @return a <i>StatusCommand[]</i> array containing the status to return      *         to the client      */    public static Status[]    generateStatusCommands(SyncOperationStatus[] operationStatus,                           String                msgId          ,                           CommandIdGenerator    idGenerator    ) {        HashMap   statusMap = new HashMap();        ArrayList itemList  = null;        StatusKey key       = null;        ModificationCommand cmd = null;        for (int i=0; i < operationStatus.length ; ++i) {            cmd = ((Sync4jOperationStatus)operationStatus[i]).getCmd();            if ((cmd == null) || (cmd.isNoResp())) {                continue; // skip the operation status            }            //            // Check if a status command has been already created for the given            // original command and status code. If it is found, than a new            // item is added to the existing ones, otherwise a new item list            // is created            //            key = new StatusKey(                      cmd,                      operationStatus[i].getStatusCode()                  );            itemList = (ArrayList)statusMap.get(key);            if (itemList == null){                itemList = new ArrayList();                statusMap.put(key, itemList);            }            itemList.add(operationStatus[i].getOperation().getSyncItemA().getKey());        }        //        // Now we can loop over the map and create a list of status commands.        //        ArrayList ret = new ArrayList();        Item[] items = null;        Iterator i = statusMap.keySet().iterator();        while(i.hasNext()) {            key = (StatusKey)i.next();            itemList = (ArrayList)statusMap.get(key);            items = new Item[itemList.size()];            for (int j = 0; j<items.length; ++j) {                items[j] = new Item(                               null,                               new Source(((SyncItemKey)itemList.get(j)).getKeyAsString()),                               null,                               null,                               false                           );            }            ret.add(                new Status(                    idGenerator.next()                       ,                    msgId                                    ,                    key.cmd.getCmdID().getCmdID()            ,                    key.cmd.getName()                        ,                    null                                     ,                    (items.length == 1)                      ?                    new SourceRef(items[0].getSource())      :                    null                                     ,                    null /* credential */                    ,                    null /* challenge  */                    ,                    new Data(key.statusCode)                 ,                    (items.length > 1)                       ?                    items                                    :                    new Item[0]                )           );        }        return (Status[])ret.toArray(new Status[ret.size()]);    }    /**     * Translates an array of <i>SyncOperation</i> objects to an array of     * <i>(Add,Delete,Replace)Command</i> objects. Only client side operations     * are translated.     *     * @param clientMapping the associated existing client mapping     * @param operations the operations to be translated     * @param sourceName the corresponding source name     * @param idGenerator the ID generator for command ids     *     * @return the sync4j commands corresponding to <i>operations</i>     */    public static    ItemizedCommand[] operationsToCommands(ClientMapping      clientMapping,                                           SyncOperation[]    operations   ,                                           String             sourceName   ,                                           CommandIdGenerator idGenerator  ) {        ArrayList commands = new ArrayList();        SyncItem item = null;        for (int i=0; ((operations != null) && (i<operations.length)); ++i) {            if (log.isLoggable(Level.FINEST)) {                log.finest( "Converting the operation\n"                          + operations[i]                          + "\nfor the source "                          + sourceName                          );            }            item = operations[i].getSyncItemB(); // this is the server-side item            if (operations[i].isAOperation() && (item != null)) {                char op = operations[i].getOperation();                //                // Should not translates a NOP operation                //                if (op == SyncOperation.NOP) {                    continue;                }                commands.add(operationToCommand(clientMapping, operations[i], idGenerator));            }        }        return (ItemizedCommand[])commands.toArray(new ItemizedCommand[0]);    }    /**     * Translates a <i>SyncOperation</i> object to a <i>(Add,Delete,Replace)Command</i>     * object.     *     * @param clientMapping the item ids mapping     * @param operation the operation to be translated     * @param command id generator to use to create command ids     *     * @return the sync4j command corresponding to <i>operation</i>     */    public static    ItemizedCommand operationToCommand(ClientMapping      clientMapping,                                       SyncOperation      operation    ,                                       CommandIdGenerator idGenerator  ) {        ItemizedCommand cmd = null;        if (idGenerator == null) {            log.finest("idGenerator is null. Cannot continue");            throw new NullPointerException("idGenerator cannot be null!");        }        char op = operation.getOperation();        //        // The item key must reflect the value known by the client agent. It        // thus must be adjusted using the client mapping, but if the        // operation is an addition. In this case the client key is generated        // by the engine (the client will provide the right key with a        // subsequent Map command).        //        String itemKey = operation.getSyncItemB().getKey().getKeyAsString();        if (op != SyncOperation.NEW && op != SyncOperation.CONFLICT) {            itemKey = clientMapping.getMappedValueForGuid(itemKey);        }        assert (itemKey != null);        //        // The following rules apply:        // - If the operation is an addition, Targer MUST NOT be included.        // - If the operation is not an addition, Source MUST NOT be included.        // - If the operation is not a deletion, Data element MUST be used to carry data ifself        //        // TO DO: noResponse, credential        //        Meta m = null;        if (op == SyncOperation.NEW) {            m = new Meta();            m.setType(operation.getSyncItemB().getSyncSource().getType());            cmd = new Add(                      idGenerator.next(),                      false             ,                      null              ,                      m                 , // meta                      new Item[] {                          SyncItemHelper.toItem(                              itemKey                 ,                              operation.getSyncItemA(),                              false                   ,                              true                    ,                              true                          )                      }                  );        } else  if (op == SyncOperation.DELETE) {            cmd = new Delete(                      idGenerator.next(),                      false				,                      false				,                      false				,                      null				,                      null 				, // meta                      new Item[] {                          SyncItemHelper.toItem(                              itemKey,                              operation.getSyncItemA(),                              true,                              false,                              false                          )                      }                  );        } else  if (op == SyncOperation.UPDATE) {            m = new Meta();            m.setType(operation.getSyncItemB().getSyncSource().getType());            cmd = new Replace(                      idGenerator.next(),                      false				,                      null				,                      m					,                      new Item[] {                          SyncItemHelper.toItem(                              itemKey,                              operation.getSyncItemA(),                              true,                              false,                              true                          )                      }                  );        } else if (op == SyncOperation.CONFLICT) {            //            // Server wins!            //            // TO DO: implement other conflict resolution policies            //            if (operation.getSyncItemB().getSyncSource() != null) {				m = new Meta();				m.setType(operation.getSyncItemB().getSyncSource().getType());            }            if (operation.getSyncItemB().getState() == SyncItemState.NOT_EXISTING) {                itemKey = operation.getSyncItemA().getKey().getKeyAsString();            }            //View the state of syncItemB and then say to client which the operation            //to do in order to resolve the conflict            char s = operation.getSyncItemB().getState();            switch (s) {                case SyncItemState.UPDATED:                case SyncItemState.SYNCHRONIZED:                    cmd = new Replace(                              idGenerator.next(),                              false				,                              null				,                              m					,                              new Item[] {                                  SyncItemHelper.toItem(                                      itemKey,                                      operation.getSyncItemA(),                                      true,                                      false,                                      true                                  )                              }                          );                    break;                case SyncItemState.DELETED:                case SyncItemState.NOT_EXISTING:                    cmd = new Delete(                              idGenerator.next(),                              false				,                              false				,                              false				,                              null				,                              null				, // meta                              new Item[] {                                  SyncItemHelper.toItem(                                      itemKey,                                      operation.getSyncItemA(),                                      true,                                      false,                                      false                                  )                              }                          );                    break;                case SyncItemState.NEW:                    cmd = new Add(                              idGenerator.next(),                              false				,                              null				,                              m					, // meta                              new Item[] {                                  SyncItemHelper.toItem(                                      itemKey                 ,                                      operation.getSyncItemA(),                                      false                   ,                                      true                    ,                                      true                                  )                              }                          );                    break;            }        }        return cmd;    }    /**     * Converts an array of <i>Item</i> objects belonging to the same     * <i>SyncSource</i> into an array of <i>SyncItem</i> objects.     * <p>     * The <i>Item</i>s created are enriched with an additional property     * called as in SyncItemHelper.PROPERTY_COMMAND, which is used to bound the     * newly created object with the original command.     *     * @param syncSource the <i>SyncSource</i> items belong to - NOT NULL     * @param items the <i>Item</i> objects     * @param state the state of the item as one of the values defined in     *              <i>SyncItemState</i>     * @param the timestamp to assign to the last even on this item     *     *     * @return an array of <i>SyncItem</i> objects     */    public static SyncItem[] itemsToSyncItems(ClientMapping       clientMapping,                                              SyncSource          syncSource   ,

⌨️ 快捷键说明

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