📄 syncmanager.java
字号:
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 + -