/*
* XMLParser.java
*
* � <your company here>, 2003-2007
* Confidential and proprietary.
*/
package com.funambol.syncclient.blackberry.parser;
import com.funambol.syncclient.util.Log;
import java.util.Hashtable;
import com.funambol.syncclient.spds.SyncException;
/**
*
*/
abstract class XMLParser {
private static final String[][] BASIC_ARRAY = {
{"&", "&"},
{"<", "<"},
{">", ">"},
};
protected String START_MARKER;
protected String END_MARKER;
XMLParser() {
}
private String unEscapeXML(String data) {
String result = data;
String temp;
int index;
try {
if (result != null) {
for (int i = 0; i < BASIC_ARRAY.length; i++) {
while(result.indexOf(BASIC_ARRAY[i][0])>-1){
index=result.indexOf(BASIC_ARRAY[i][0]);
temp = result.substring(0, index);
temp+=BASIC_ARRAY[i][1];
temp+=result.substring(index+BASIC_ARRAY[i][0].length());
result=temp;
}
}
}
} catch (Exception e) {
result = data;
}
return result;
}
/**
* This method creates a hashtable with keys and values associated with
* the BlackBerry contact/appointment list attributes (picked from the great ordered
* list defined at the top of this class, {@code tagArray})
*
* @param String A SIF XML string representing a BlackBerry Contact/Appointment
* from the server
* @return Hashtable
* @throws SyncException if no correct contact element in SIF comes from
* the server
*/
protected Hashtable buildMapFromXML(String xmlString) throws SyncException {
int startMarkerIndex = xmlString.indexOf(START_MARKER);
int endMarkerIndex = xmlString.indexOf(END_MARKER);
if (startMarkerIndex == -1 || endMarkerIndex == -1) {
throw new SyncException("Improper data from the server");
//Dialog.inform("Improper data from the server");
//return null;
}
//Check if xml is got an utf-8 encoding in header. TODO: Generalize to other encodings.
boolean is_utf8 = (xmlString.substring(0, startMarkerIndex).toLowerCase().indexOf("encoding=\"utf-8\"") != -1);
Hashtable propertyMap = new Hashtable();
boolean readNothing = true;
boolean readOpenTag = false;
boolean readData = false;
int openTagPos = 0;
int dataPos = 0;
String tagName = "";
String data = "";
int tagLength = START_MARKER.length();
//TODO: Handle CDATA
for(int i=startMarkerIndex + tagLength; i< endMarkerIndex; i++){
char c = xmlString.charAt(i);
switch(c){
case '<':
if(readNothing){
openTagPos = i+1;
readOpenTag = true;
readNothing = false;
}
else if(readData){
int p = xmlString.indexOf("</" + tagName + '>', i);
if(p != -1){
data = xmlString.substring(dataPos, i);
if(is_utf8){
try{
data = new String(data.getBytes(), "UTF-8");
}
catch (java.io.UnsupportedEncodingException e){
Log.debug(e.toString());
}
}
i += tagName.length() + 2;
readData = false;
dataPos = 0;
readNothing = true;
data = unEscapeXML(data);
//Insert into map
propertyMap.put(tagName, data);
}
else {
//Tag mismatch
//TODO:Exception
}
}
else {
//Unexpected <
//TODO:Exception
}
break;
case '/':
if(readOpenTag){
//<Tag />
readOpenTag = false;
readNothing = true;
openTagPos = 0;
i++;
}
break;
case ' ':
if(readOpenTag){
tagName = xmlString.substring(openTagPos, i);
int p = xmlString.indexOf('>', i);
if(p != -1){
if(xmlString.substring(i,p).indexOf('/') != -1){
//<Tag />
readOpenTag = false;
readNothing = true;
openTagPos = 0;
i = p;
}
else {
//Finished reading open tag
i = p;
readOpenTag = false;
readData = true;
dataPos = i+1;
}
}
else {
//Tag not closed
//TODO:Exception
}
}
break;
case '>':
if(readOpenTag){
tagName = xmlString.substring(openTagPos, i);
readOpenTag = false;
readData = true;
dataPos = i+1;
}
break;
default:
}
}
return propertyMap;
}
}