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

📄 syncmanager.java

📁 SyncML的java实现类库 funambol公司发布的
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        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() < 200
                                || status.getStatus() >= 300) {
                            String msg = "Server responded "
                                    +status.getStatus()
                                    +" to command "
                                    +cmd;
                            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);
                            }
                        } else {
                            source.setItemStatus(status.getRef(), code);
                        }
                    }
                    
                    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
        modMsg.append("<Status>\n")
        .append("<CmdID>").append(resetCmdID()).append("</CmdID>\n")
        .append("<MsgRef>1</MsgRef><CmdRef>0</CmdRef>\n")
        .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");
        }
        
        // Add status commands, if any
        appendStatusTags(modMsg);
        
        // Add mappings if necessary.
        appendMapTag(modMsg);
        
        if(this.state != STATE_MODIFICATION_COMPLETED) {
            modMsg.append(prepareSyncTag(modMsg.length()));
        }
        
        //Adding the device capabilities as response to the <Get> command
        //TODO: check if the response from server is the best place to set this
        if (addDevInfResults) {
            modMsg.append(createResults(config.deviceConfig));
            //reset the flag
            addDevInfResults = false;
        }
        
        if(this.state == STATE_MODIFICATION_COMPLETED) {
            Log.info("Modification done, sending <final> tag.");
            modMsg.append("<Final/>\n");
        }
        
        modMsg.append("</SyncBody></SyncML>");
        
        return modMsg.toString();
    }
    
    
    /**
     * Prepare mapping message
     *
     **/
    private String prepareMappingMessage() {
        
        int i = 0;
        
        StringBuffer ret = new StringBuffer("<SyncML>\n");
        
        // Add SyncHdr
        ret.append( prepareSyncHeader(sessionID, getNextMsgID(),
                deviceId, serverUrl, null ) );
        
        // Add SyncBody
        ret.append("<SyncBody>\n");
        
        // Add Status to the alert (FIXME)
        ret.append("<Status>\n")
        .append("<CmdID>").append(resetMsgID()).append("</CmdID>\n")
        .append("<MsgRef>1</MsgRef>\n")        // FIXME
        .append("<CmdRef>0</CmdRef>\n")
        .append("<Cmd>SyncHdr</Cmd>\n")
        .append("<TargetRef>").append(deviceId).append("</TargetRef>\n")
        .append("<SourceRef>").append(config.syncUrl).append("</SourceRef>\n")
        .append("<Data>200</Data>\n")
        .append("</Status>\n");
        
        appendStatusTags(ret);
        
        appendMapTag(ret);
        
        ret.append("<Final/>\n")
        .append("</SyncBody>\n")
        .append("</SyncML>");
        
        return ret.toString();
    }
    
    /**
     * Prepares the Map tag if there is some mappings to send, and append
     * it to the given StringBuffer.
     * It cleans up the mapping table at the end.
     *
     * @param out the StringBuffer to append the Map tag to.
     * @return none.
     */
    private void appendMapTag(StringBuffer out) {
        if(mappings.size() == 0) {
            // No mappings to add
            return ;
        }
        
        String targetRef    = null ;
        String sourceRef    = null ;
        
        Enumeration e = mappings.keys();
        
        out.append("<Map>\n")
        .append("<CmdID>" + getNextCmdID() + "</CmdID>\n")
        .append("<Target>\n")
        .append("<LocURI>" + source.getSourceUri() + "</LocURI>\n")
        .append("</Target>\n")
        .append("<Source>\n")
        .append("<LocURI>" + source.getName() + "</LocURI>\n")
        .append("</Source>\n");
        
        while ( e.hasMoreElements() ) {
            
            sourceRef = (String) e.nextElement();
            targetRef = (String) mappings.get(sourceRef);
            
            out.append("<MapItem>\n")
            .append("<Target>\n")
            .append("<LocURI>" + targetRef + "</LocURI>\n")
            .append("</Target>\n")
            .append("<Source>\n")
            .append("<LocURI>" + sourceRef + "</LocURI>\n")
            .append("</Source>\n")
            .append("</MapItem>\n");
        }
        out.append("</Map>\n");
        
        // Cleanup mappings table before returning.
        mappings.clear();
    }
    
    /**
     * Prepares the Status tags if there is some status commands to send,
     * and append it to the given StringBuffer.
     * It cleans up the status lost at the end.
     *
     * @param out the StringBuffer to append the Status tags to.
     * @return none.
     */
    private void appendStatusTags(StringBuffer out) {
        
        int l = statusList.size();
        if(l == 0) {
            // Nothing to send
            return;
        }
        
        SyncMLStatus status = null;
        
        // Build status commands...
        for (int idx = 0; idx < l; idx++) {
            status = (SyncMLStatus)statusList.elementAt(idx);
            status.setCmdId(getNextCmdID());    // update the command id
            out.append(status.toString());
        }
        // ...and cleanup the status vector
        statusList.removeAllElements();
    }
    
    /**
     * Contructs the alerts for the given source.
     * @param src SyncSource
     * @param syncMode
     * @return the XML for the SyncML Alert commands
     */
    private String createAlerts(SyncSource src, int syncMode) {
        
        StringBuffer sb = new StringBuffer();
        
        // XXX CHECK IT OUT XXX

⌨️ 快捷键说明

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