📄 syncmanager.java
字号:
if (format != null && !format.equals("")) {
ret = StringUtil.split(format.toString(), ";");
}
}
} catch (XmlException e) {
Log.error("[processFormat] Error parsing format from server: "
+xml+". Ignoring it.");
e.printStackTrace();
}
return ret;
}
/**
* Get the format string to add to the outgoing message.
*
* @return the Format string, according to the source encoding
*/
private String getFormat(){
// Get the Format tag from the SyncSource encoding.
if( !source.getEncoding().equals(source.ENCODING_NONE) ) {
return "<Format xmlns=\'syncml:metinf\'>"
+source.getEncoding()+"</Format>\n";
} else return "";
}
/**
* Encode the item data according to the format specified by the SyncSource.
*
* @param formats the list of requested encodings (des, 3des, b64)
* @param data the byte array of data to encode
* @return the encoded byte array, or <code>null</code> in case of error
*/
private byte[] encodeItemData(String[] formats, byte[] data) {
if (formats != null && data != null) {
// If ecryption types are specified, apply them
for (int count = formats.length - 1; count >= 0; count--) {
String encoding = formats[count];
if (encoding.equals("b64")) {
data = Base64.encode(data);
}
/*
else if (encoding.equals("des")) {
// DES not supported now, ignore SyncSource encoding
}
else if (currentDecodeType.equals("3des")) {
// 3DES not supported now, ignore SyncSource encoding
}
*/
}
}
return data;
}
/**
* Decode the item data according to the format specified by the server.
*
* @param formats the list of requested decodings (des, 3des, b64)
* @param data the byte array of data to decode
* @return the decode byte array, or <code>null</code> in case of error
*
* @throws UnsupportedEncodingException
*/
private byte[] decodeItemData(String[] formats, byte[] data)
throws UnsupportedEncodingException {
if (formats != null && data != null) {
// If ecryption types are specified, apply them
for (int count = formats.length - 1; count >= 0; count--) {
String currentDecodeType = formats[count];
if (currentDecodeType.equals("b64")) {
data = Base64.decode(data);
} else if (currentDecodeType.equals("des")) {
// Error, DES not supported now, send error to the server
return null;
/*
desCrypto = new Sync4jDesCrypto(Base64.encode(login.getBytes()));
data = desCrypto.decryptData(data);
*/
} else if (currentDecodeType.equals("3des")) {
// Error, 3DES not supported now, send error to the server
return null;
/*
sync3desCrypto = new Sync4j3DesCrypto(Base64.encode(login.getBytes()));
data = sync3desCrypto.decryptData(data);
*/
}
}
}
return data;
}
/**
* Get an item from the SyncML tag.
*
* @param command The name command from server
* @param type the mime type of the item
* @param xmlItem the SyncML tag for this item
*
* @return the SyncItem object
*
* @throws SyncException if the command parsing failed
*
*/
private SyncItem getItem(char state, String type, ChunkedString xmlItem)
throws SyncException {
String key = null;
String data = null;
String parent = null;
byte[] content = null;
// Get item key
try {
key = XmlUtil.getTagValue(xmlItem, SyncML.TAG_LOC_URI).toString();
} catch (XmlException e) {
Log.error("[getItem] Invalid item key from server: " + xmlItem);
e.printStackTrace();
throw new SyncException(
SyncException.SERVER_ERROR,
"Invalid item key from server.");
}
// Get item parent, if present
if( XmlUtil.getTag(xmlItem, SyncML.TAG_TARGET_PARENT) > 0 ) {
try {
parent = XmlUtil.getTagValue(
XmlUtil.getTagValue(
xmlItem, SyncML.TAG_TARGET_PARENT),
SyncML.TAG_LOC_URI).toString();
} catch (XmlException e) {
Log.error("[getItem] Invalid item parent from server: "
+ e.toString());
throw new SyncException(
SyncException.SERVER_ERROR,
"Invalid item parent from server.");
}
}
// Get the item data, if present
if( XmlUtil.getTag(xmlItem, SyncML.TAG_DATA) != -1 ) {
try {
// Get item data
data = XmlUtil.getTagValue(xmlItem, SyncML.TAG_DATA).toString();
// Process format tag (encryption and encoding)
String[] formatList = processFormat(xmlItem);
if(formatList != null) {
// Format tag from server
content = decodeItemData(formatList, data.getBytes());
} else if( !source.getEncoding().equals(source.ENCODING_NONE) ) {
// If the server does not send a format, apply the one
// defined for the sync source
formatList = processFormat(new ChunkedString(source.getEncoding()));
content = decodeItemData(formatList, data.toString().getBytes());
} else {
// Else, the data is text/plain,
// and the XML special chars are escaped.
content = XmlUtil.unescapeXml(data.toString()).getBytes();
}
} catch (UnsupportedEncodingException uee) {
uee.printStackTrace();
Log.error("[getItem] Can't decode content for item: "+key);
// in case of error, the content is null
// and this will be reported as an error to the server
content = null;
} catch (XmlException xe) {
xe.printStackTrace();
Log.error("[getItem] Can't parse data tag for item: "+key);
// in case of error, the content is null
// and this will be reported as an error to the server
content = null;
}
}
// Create the item
return new SyncItem(
key, type, state, parent, content);
}
/**
* Processes an item in a modification command received from server.
*
* @param cmd the cmmand info
* @param xmlItem the SyncML tag for this item
* @return the status code for this item
*
* @throws SyncException if the command parsing failed
*
*/
private SyncMLStatus processSyncItem(SyncMLCommand cmd, ChunkedString xmlItem)
throws SyncException {
int status = 0;
SyncItem item = null;
String guid = null;
String cmdTag = cmd.getName();
if(cmdTag.equals(SyncML.TAG_ADD)) {
item = getItem(item.STATE_NEW, cmd.getType(), xmlItem);
// 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);
} 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 = getItem(item.STATE_UPDATED, cmd.getType(), xmlItem);
// Preliminary check: don't pass a null item to the SyncSource
// for update
if (item.getContent() != null) {
status = source.updateItem(item);
} else {
status = SyncMLStatus.GENERIC_ERROR ;
}
} else if(cmdTag.equals(SyncML.TAG_DELETE)) {
item = getItem(item.STATE_DELETED, cmd.getType(), xmlItem);
status = source.deleteItem(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());
}
Vector itemTags = XmlUtil.getTagValues(command, SyncML.TAG_ITEM);
int len = itemTags.size();
// Process items
SyncMLStatus status = null;
for(i=0; i<len; i++) {
status = processSyncItem(cmd, (ChunkedString)itemTags.elementAt(i));
//System.gc(); // XXX: TEST
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 {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -