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

📄 syncmanager.java

📁 j2me java syncml moblie
💻 JAVA
📖 第 1 页 / 共 5 页
字号:

        String cmdTag = cmd.getName();

        if (cmdTag.equals(SyncML.TAG_ADD)) {
            item = this.getItem(item.STATE_NEW, cmd.getType(), xmlItem, formatList);
            // Save the key sent by server, it will be replaced by the SyncSource
            // with the local UID.
            guid = new String(item.getKey());   // Duplicate to avoid leaks!!
            // Preliminary check: don't pass a null item to the SyncSource
            // for add
            if (item.getContent() != null) {
                status = source.addItem(item);
                if (SyncMLStatus.isSuccess(status)) {
                    listener.itemReceived(item.getClientRepresentation());
                }
            } else {
                status = SyncMLStatus.GENERIC_ERROR;
            }
            if (SyncMLStatus.isSuccess(status)) {
                mappings.put(new String(item.getKey()), guid); // Avoid leaks!!
            }

        } else if (cmdTag.equals(SyncML.TAG_REPLACE)) {
            item = this.getItem(item.STATE_UPDATED, cmd.getType(), xmlItem, formatList);
            // Preliminary check: don't pass a null item to the SyncSource
            // for update
            if (item.getContent() != null) {
                status = source.updateItem(item);
                if (SyncMLStatus.isSuccess(status)) {
                    listener.itemUpdated(item.getKey(),
                            item.getClientRepresentation());
                }
            } else {
                status = SyncMLStatus.GENERIC_ERROR;
            }
        } else if (cmdTag.equals(SyncML.TAG_DELETE)) {
            item = this.getItem(item.STATE_DELETED, cmd.getType(), xmlItem, formatList);
            status = this.source.deleteItem(item.getKey());
            if (SyncMLStatus.isSuccess(status)) {
                listener.itemDeleted(item.getKey());
            }
        } else {
            Log.error("[processItem] Invalid command: " + cmd.toString());
        }

        // Init the status object
        SyncMLStatus ret = new SyncMLStatus();
        ret.setCmd(cmdTag);
        ret.setCmdRef(cmd.getCmdId());
        // Save the source ref if present (ADD), otherwise the target ref (UPD & DEL)
        if (guid != null) {
            ret.setSrcRef(guid);
        } else {
            ret.setTgtRef(item.getKey());
        }
        ret.setStatus(status);

        return ret;
    }

    /**
     * Processes a modification command received from server,
     * returning the command parts in an Hashtable
     *
     * @param msgRef The messageId tag of the message containing this command
     * @param cmdName the command name
     * @param command the body of the command
     *
     * @return the number of modifications made
     *
     * @throws SyncException if the command parsing failed
     *
     */
    private int processCommand(ChunkedString msgRef, String cmdName, ChunkedString command)
            throws SyncException {

        ChunkedString cmdId = null;
        int i = 0;

        // Get command Id
        try {
            cmdId = XmlUtil.getTagValue(command, SyncML.TAG_CMDID);
        } catch (XmlException e) {
            Log.error("[processCommand] Invalid command Id from server: " + command);
            e.printStackTrace();
            throw new SyncException(
                    SyncException.SERVER_ERROR,
                    "Invalid command from server.");
        }

        SyncMLCommand cmd = new SyncMLCommand(cmdName, cmdId.toString());

        try {
            // Get the type of the items for this command, if present
            // otherwise use the type defined for this source.
            int pos = XmlUtil.getTag(command, SyncML.TAG_TYPE);
            String itemType = null;

            if (pos != -1) {
                try {
                    itemType = XmlUtil.getTagValue(command, SyncML.TAG_TYPE).toString();
                //int begin = command.indexOf(">", pos);
                //int end = command.indexOf("</"++">", begin);
                //if(begin != -1 && end != -1) {
                //    itemType = command.substring(begin+1, end).toString();
                //}
                } catch (XmlException xe) {
                    xe.printStackTrace();
                    Log.error("Error parsing item type, using default for source.");
                }
            }
            // Set the command type or use the source one
            if (itemType != null) {
                cmd.setType(itemType);
            } else {
                cmd.setType(source.getType());
            }

            // Process format tag (encryption and encoding)
            String[] formatList = this.processFormat(command);

            Vector itemTags = XmlUtil.getTagValues(command, SyncML.TAG_ITEM);
            int len = itemTags.size();

            // Process items
            SyncMLStatus status = null;
            for (i = 0; i < len; i++) {
                status = this.processSyncItem(cmd, (ChunkedString) itemTags.elementAt(i), formatList);
                status.setMsgRef(msgRef.toString());
                statusList.addElement(status);
            }

        } catch (XmlException xe) {
            xe.printStackTrace();
            Log.error("[processCommand] Parse error: " + xe.toString());
            throw new SyncException(
                    SyncException.SERVER_ERROR,
                    "Error processing command:" + cmdName + " in message " + msgRef);
        }


        return i;
    }

    /**
     * Processes the modifications from the received response from server
     *
     * @param modifications The modification message from server
     * @return true if a response message is required, false otherwise
     * @throws SyncException
     */
    private boolean processModifications(ChunkedString modifications)
            throws SyncException {
        boolean ret = false;

        ChunkedString msgId = null;
        ChunkedString bodyTag = null;

        try {
            // Check the SyncML tag
            if (XmlUtil.getTag(modifications, SyncML.TAG_SYNCML) == -1) {
                Log.error("Invalid message from server.");
                throw new SyncException(
                        SyncException.SERVER_ERROR,
                        "Invalid message from server.");
            }
            // Process header
            ChunkedString syncHdr = XmlUtil.getTagValue(modifications,
                    SyncML.TAG_SYNCHDR);
            // Get message id
            msgId = XmlUtil.getTagValue(syncHdr, SyncML.TAG_MSGID);

            // Get message body
            bodyTag = XmlUtil.getTagValue(modifications, SyncML.TAG_SYNCBODY);

        } catch (XmlException e) {
            Log.error("[processModification] error parsing message: " + e.toString());
            throw new SyncException(
                    SyncException.SERVER_ERROR,
                    "Error parsing message: " + e.getMessage());
        }

        // Process body
        Vector cmdTags = null;
        Vector xmlBody = new Vector(1);
        xmlBody.addElement(bodyTag);

        // Ignore incoming modifications for one way from client modes
        if (alertCode != SyncML.ALERT_CODE_ONE_WAY_FROM_CLIENT &&
                alertCode != SyncML.ALERT_CODE_REFRESH_FROM_CLIENT) {

            try {

                // If the server sends a <Sync> tag, the message contains
                // modifications, otherwise it contains only status.
                if (XmlUtil.getTag(bodyTag, SyncML.TAG_SYNC) != - 1) {
                    ret = true;
                    String[] cmdNames = {SyncML.TAG_ADD,
                        SyncML.TAG_REPLACE,
                        SyncML.TAG_DELETE
                    };

                    processSyncCommand(msgId, bodyTag);
                    bodyTag = null;

                    // Process commands, one kind at a time, in the order
                    // defined above
                    for (int c = 0; c < cmdNames.length; c++) {
                        int count = 0;
                        Log.debug("[processModification] processing " + cmdNames[c] + " commands");
                        cmdTags = XmlUtil.getTagValues(xmlBody, cmdNames[c]);

                        for (int i = 0,  l = cmdTags.size(); i < l; i++) {
                            ChunkedString command = (ChunkedString) cmdTags.elementAt(i);
                            count += processCommand(msgId, cmdNames[c], command);

                            command = null;

                        }
                        cmdTags = null;

                        Log.info(cmdNames[c] + ": " + count + " items processed");
                    }

                }
            } catch (XmlException e) {
                e.printStackTrace();
                Log.error("[processModification] error parsing command: " + e.toString());
            }
        }

        try {
            // Process status commands
            cmdTags = XmlUtil.getTagValues(xmlBody, SyncML.TAG_STATUS);
            SyncMLStatus status = null;
            for (int i = 0,  l = cmdTags.size(); i < l; i++) {
                status = SyncMLStatus.parse((ChunkedString) cmdTags.elementAt(i));
                if (status != null) {
                    String cmd = status.getCmd();
                    Log.debug("[processModification] processing Status for <" + cmd + "> command.");

                    // Check status to SyncHdr and Sync
                    if (cmd.equals(SyncML.TAG_SYNCHDR) || cmd.equals(SyncML.TAG_SYNC)) {
                        if (status.getStatus() == 506) {
                            String msg = "Server responded " + status.getStatus() + " to command " + cmd + " [" + status.getStatusDataMessage() + "]"; //506
                            Log.error(msg);
                            throw new SyncException(SyncException.BACKEND_ERROR, msg);
                        } else if (status.getStatus() == 511) {
                            String msg = "Server responded " + status.getStatus() + " to command " + cmd + " [" + status.getStatusDataMessage() + "]"; //511
                            Log.error(msg);
                            throw new SyncException(SyncException.BACKEND_AUTH_ERROR, msg);
                        }else if (status.getStatus() < 200 || status.getStatus() >= 300) {
                        
                            String msg = "Server responded " + status.getStatus() + " to command " + cmd + " [" + status.getStatusDataMessage() + "]"; //XXX
                            Log.error(msg);
                            throw new SyncException(SyncException.SERVER_ERROR, msg);
                        }
                    } else {
                        // Otherwise, pass it to the source
                        String[] items = status.getItemKeys();
                        int code = status.getStatus();
                        // Check if it's a multi-item response
                        if (items != null) {
                            for (int j = 0,  n = items.length; j < n; j++) {
                                source.setItemStatus(items[j], code);
                                // Notify the listener
                                listener.itemUpdated(items[j]);
                            }
                        } else {
                            source.setItemStatus(status.getRef(), code);
                            // Notify the listener
                            listener.itemUpdated(status.getRef());
                        }
                    }

                    status = null;

                } else {
                    Log.error("[processModification] error in Status command.");
                }
            }
        } catch (XmlException e) {
            e.printStackTrace();
            Log.error("[processModification] error parsing status: " + e.toString());
        }
        modifications = null;
        return ret;
    }

    /**
     * Prepares the modification message in SyncML.
     *
     * @return the formatted message
     */
    private String prepareModificationMessage() throws SyncException {


        StringBuffer modMsg = new StringBuffer("<SyncML>");

        // Meta
        String meta = "<Meta><MaxMsgSize>" + maxMsgSize + "</MaxMsgSize></Meta>\n";

        // Sync header
        String syncHdr = prepareSyncHeader(sessionID, getNextMsgID(),
                deviceId, serverUrl,
                meta);

        modMsg.append(syncHdr);

        // Sync Body
        modMsg.append("<SyncBody>\n");

        // Status to the alert command
        // This is used to address the correct MsgIdRef on the outgoing message
        int msgIdRef = msgID - 1;
        modMsg.append("<Status>\n").append("<CmdID>").append(resetCmdID()).append("</CmdID>\n").append("<MsgRef>" + msgIdRef + "</MsgRef><CmdRef>0</CmdRef>\n") //fixMe
                .append("<Cmd>SyncHdr</Cmd>\n").append("<TargetRef>").append(deviceId).append("</TargetRef>\n").append("<SourceRef>").append(serverUrl).append("</SourceRef>\n").append("<Data>200</Data>\n</Status>\n");

        // Add the status to the Alert message
        // FIXME: now it checks msgId, but this test is not very smart
        //        should use SyncMLStatus for this too? (anchor must be added)
        if (msgID == 2) {
            modMsg.append("<Status>\n").append("<CmdID>").append(getNextCmdID()).append("</CmdID>\n").append("<MsgRef>1</MsgRef><CmdRef>1</CmdRef><Cmd>Alert</Cmd>\n").append("<TargetRef>").append(source.getSourceUri()).append("</TargetRef>\n").append("<SourceRef>").append(source.getSourceUri()).append("</SourceRef>\n").append("<Data>200</Data>\n").append("<Item>\n").append("<Data>\n").append("<Anchor xmlns=\"syncml:metinf\"><Next>").append(source.getNextAnchor()).append("</Next></Anchor>\n").append("</Data>\n").append("</Item>\n").append("</Status>\n");

⌨️ 快捷键说明

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