📄 syncmanager.java
字号:
}
// 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");
// This is used to address the correct MsgIdRef on the outgoing message
int msgIdRef = msgID - 1;
// Add Status to the alert (FIXME)
ret.append("<Status>\n") // CMD ID were not correctly reset before sending the mapping message
.append("<CmdID>").append(resetCmdID()).append("</CmdID>\n").append("<MsgRef>" + msgIdRef + "</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
// the Last overwrite the Next?????????????????
String timestamp = "<Next>" + src.getNextAnchor() + "</Next>\n";
if (source.getLastAnchor() != 0l) {
timestamp = "<Last>" + src.getLastAnchor() + "</Last>\n" + timestamp;
}
sb.append("<Alert>\n");
sb.append("<CmdID>1</CmdID>\n");
sb.append("<Data>");
// First, use the syncMode passed as argument,
// if not valid, use the default for the source
// as last chance, check the anchor.
if (syncMode != 0) {
sb.append(syncMode);
} else if (src.getSyncMode() != 0) {
sb.append(SyncML.ALERT_CODE_SLOW);
} else if (src.getLastAnchor() != 0) {
sb.append(SyncML.ALERT_CODE_FAST);
} else {
sb.append(src.getSyncMode());
}
SyncFilter f = src.getFilter();
sb.append("</Data>\n");
sb.append("<Item>\n");
sb.append("<Target><LocURI>");
sb.append(src.getSourceUri());
sb.append("</LocURI>\n");
// Apply source filter with a default limit to maxMsgSize.
// TODO: change it to maxObjSize when the Large Object will be
// implemented.
if (f != null) {
int maxDataSize = maxMsgSize - PROTOCOL_OVERHEAD;
sb.append(f.toSyncML(maxDataSize));
}
sb.append("</Target>\n");
sb.append("<Source><LocURI>");
sb.append(src.getName());
sb.append("</LocURI></Source>\n");
sb.append("<Meta>\n");
sb.append("<Anchor xmlns=\"syncml:metinf\">\n");
sb.append(timestamp);
sb.append("</Anchor>\n");
sb.append("</Meta>\n");
sb.append("</Item>\n");
sb.append("</Alert>");
sb.append("\n");
return sb.toString();
}
/**
* Constructs the <Put> section of a SyncML initialization message used to
* carry the device capabilities with the <DevInf> element
*
* @param devInf
* A reference to the current device configuration (<code>DeviceConfig</code>)
* @return a String to be added to the initialization SyncML message
*/
private String createPut(DeviceConfig devInf) {
StringBuffer sb = new StringBuffer();
//TODO: retrieve most values from the passed DeviceConfig object
sb.append("<Put>\n").append("<CmdID>2</CmdID>\n")// TODO: this is normally the cmd 2, but...
.append("<Meta>\n").append("<Type xmlns='syncml:metinf'>application/vnd.syncml-devinf+xml</Type>\n").append("</Meta>\n").append("<Item>\n").append("<Source><LocURI>./devinf12</LocURI></Source>\n").append("<Data>\n").append(createDevInf(devInf)) //closing all tags
.append("</Data>\n").append("</Item>\n").append("</Put>\n");
//reset the flag
sendDevInf = false;
return sb.toString();
}
/**
* Used to build the part of the SyncML modification message containing the
* device sync capabilities (<Results>) when requested by the server with
* the command <Get>
*
* @param devInf
* A reference to the current device configuration (<code>DeviceConfig</code>)
* @return the string containing the device capabilities part of the SyncML
* message sent to the server
*/
private String createResults(DeviceConfig devInf) {
StringBuffer sb = new StringBuffer();
sb.append("<Results>\n").append("<CmdID>" + getNextCmdID() + "</CmdID>\n").append("<MsgRef>" + msgIDget + "</MsgRef>\n").append("<CmdRef>" + cmdIDget + "</CmdRef>\n").append("<Meta>\n").append("<Type xmlns='syncml:metinf'>application/vnd.syncml-devinf+xml</Type>\n").append("</Meta>\n").append("<Item>\n").append("<Source><LocURI>./devinf12</LocURI></Source>\n").append("<Data>\n").append(createDevInf(devInf)) //closing all tags
.append("</Data>\n").append("</Item>\n").append("</Results>");
return sb.toString();
}
/**
* Used to build the <DevInf> element as part of a SyncML message's <Put> or
* <Results> section
*
* @param devInf
* A reference to the current device configuration (<code>DeviceConfig</code>)
* @return the string containing the device capabilities part of the SyncML
* message sent to the server
*/
private String createDevInf(DeviceConfig devInf) {
StringBuffer sb = new StringBuffer();
if (devInf.man == null) {
devInf.man = "";
}
if (devInf.mod == null) {
devInf.mod = "";
}
if (devInf.oem == null) {
devInf.oem = "";
}
if (devInf.fwv == null) {
devInf.fwv = "";
}
if (devInf.swv == null) {
devInf.swv = "";
}
if (devInf.hwv == null) {
devInf.hwv = "";
}
if (devInf.devID == null) {
devInf.devID = "";
}
if (devInf.devType == null) {
devInf.devType = "";
}
sb.append("<DevInf xmlns='syncml:devinf'>\n").append("<VerDTD>1.2</VerDTD>\n")//mandatory
.append("<Man>" + devInf.man + "</Man>\n")//mandatory: name of the manufacturer of the device
.append("<Mod>" + devInf.mod + "</Mod>\n")//mandatory: model name or model number of the device
.append("<OEM>" + devInf.oem + "</OEM>\n")//optional: Original Equipment Manufacturer
.append("<FwV>" + devInf.fwv + "</FwV>\n")//mandatory: firmware version of the device or a date
.append("<SwV>" + devInf.swv + "</SwV>\n")//mandatory: software version of the device or a date
.append("<HwV>" + devInf.hwv + "</HwV>\n")//mandatory: hardware version of the device or a date
.append("<DevID>" + devInf.devID + "</DevID>\n")//mandatory: identifier of the source synchronization device
.append("<DevTyp>" + devInf.devType + "</DevTyp>\n");//mandatory: type of the source synchronization device (see OMA table)
//optional flag (if present, the server SHOULD send time in UTC form)
if (devInf.utc) {
sb.append("<UTC/>\n");
}
//optional (if present, it specifies that the device supports receiving
//large objects)
if (devInf.loSupport) {
sb.append("<SupportLargeObjs/>\n");
}
//optional: server MUST NOT send <NumberOfChanges> if the client has
//not specified this flag
if (devInf.nocSupport) {
sb.append("<SupportNumberOfChanges/>\n");
}
//<DataStore> one for each of the local datastores
sb.append("<DataStore>\n")//
.append("<SourceRef>" + source.getName() + "</SourceRef>\n") //required for each specified datastore
.append("<Rx-Pref>\n").append("<CTType>").append(source.getType()).append("</CTType>\n").append("<VerCT></VerCT>\n").append("</Rx-Pref>\n") //required for each specified datastore
.append("<Tx-Pref>\n").append("<CTType>").append(source.getType()).append("</CTType>\n").append("<VerCT></VerCT>\n").append("</Tx-Pref>\n") //SyncCap
.append("<SyncCap>\n")//mandatory
.append("<SyncType>1</SyncType>\n")//Support of 'two-way sync'
.append("<SyncType>2</SyncType>\n")//Support of 'slow two-way sync'
//TODO: add support of one way?
.append("<SyncType>7</SyncType>\n")//Support of 'server alerted sync'
.append("</SyncCap>\n").append("</DataStore>\n").append("</DevInf>\n");
return sb.toString();
}
/**
* Checks if in the response from server a <Get> command is present and that
* the information required by the server with this command is the device
* capabilities
*
* @param response
* The SyncML message received from server
* @return <code>true</code> if the <Get> tag is presen
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -