package com.android.mms.dom; import java.io.ByteArrayInputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Hashtable; import java.util.TimeZone; import com.android.mms.dom.WbxmlParser; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.util.Config; import android.util.Log; import com.android.mms.transaction.WapPushMsg; public class WapPushParser { /** * The log tag. */ private static final String LOG_TAG = "WapPushParser"; private static final boolean DEBUG = true; private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV; /** * The wap push data. */ private ByteArrayInputStream mWapPushDataStream = null; private WbxmlParser mParser = null; private WapPushMsg mPushMsg = null;//store the parsing results. /** * Constructor. * * @param wapPushDataStream wap push data to be parsed */ public WapPushParser(byte[] pushDataStream) { mWapPushDataStream = new ByteArrayInputStream(pushDataStream); } /** * Parse the wap push. * type the push message type WAP_PUSH_TYPE_SI or WAP_PUSH_TYPE_SL * @return the push structure if parsing successfully. * null if parsing error happened or mandatory fields are not set. */ public WapPushMsg parse(int type) { String tagName = null; if (mWapPushDataStream == null) { Log.e(LOG_TAG, "mWapPushDataStream is not set!"); return null; } mPushMsg = new WapPushMsg(type); if (WapPushMsg.WAP_PUSH_TYPE_SI == type) { mParser = createSIParser(); } else if (WapPushMsg.WAP_PUSH_TYPE_SL == type) { mParser = createSLParser(); } else { Log.e(LOG_TAG, "wap push unknown type=" + type); return null; } try { mParser.setInput(mWapPushDataStream, null); if(LOCAL_LOGV) { Log.i(LOG_TAG, "Document charset : " + mParser.getInputEncoding()); } int eventType = mParser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_DOCUMENT: Log.i(LOG_TAG, "Start document"); break; case XmlPullParser.END_DOCUMENT: Log.i(LOG_TAG, "End document"); break; case XmlPullParser.START_TAG: Log.i(LOG_TAG, "Start tag = "+mParser.getName()); elementParser(mParser.getName()); //parsing si or sl tag //add by liguxiang 08-18-11 for NEWMS00109865 begin String expires = mPushMsg.getAttributeValueString(WapPushMsg.WAP_PUSH_PROJECTION_SI_EXPIRED); Log.d(LOG_TAG,"expires = " + expires); SimpleDateFormat date = new SimpleDateFormat("yyyyMMddHHmmss"); String currentTime = date.format(new Date()); Log.d(LOG_TAG,"currentSystemTime = " + currentTime); if(expires != null){ if(expires.compareTo(currentTime) < 0){ return null; } } //add by liguxiang 08-18-11 for NEWMS00109865 end break; case XmlPullParser.END_TAG: Log.i(LOG_TAG, "End tag = "+mParser.getName()); break; case XmlPullParser.TEXT: Log.i(LOG_TAG, "Text = "+mParser.getText()); if (WapPushMsg.WAP_PUSH_TYPE_SI == type) { mPushMsg.setAttributeValue(WapPushMsg.WAP_PUSH_PROJECTION_SI_TEXT, mParser.getText()); } break; default: Log.i(LOG_TAG, "unknown event type = "+eventType); break; } eventType = mParser.next(); } } catch (IOException e) { if(LOCAL_LOGV) { Log.e(LOG_TAG, e.toString()); } return null; } catch (XmlPullParserException e) { if(LOCAL_LOGV) { Log.e(LOG_TAG, e.toString()); } return null; } return mPushMsg; } private static WbxmlParser createSIParser() { WbxmlParser p = new WbxmlParser(); p.setTagTable(0, TAG_TABLE_SI); p.setAttrStartTable(0, ATTR_START_TABLE_SI); p.setAttrValueTable(0, ATTR_VALUE_TABLE_SI_SL); return p; } private static WbxmlParser createSLParser() { WbxmlParser p = new WbxmlParser(); p.setTagTable(0, TAG_TABLE_SL); p.setAttrStartTable(0, ATTR_START_TABLE_SL); p.setAttrValueTable(0, ATTR_VALUE_TABLE_SI_SL); return p; } private void elementParser(String tagName){ int attrCount = mParser.getAttributeCount(); String attrName = null; String attrValue = null; if (tagName.equalsIgnoreCase(TAG_TABLE_SL[0]) || tagName.equalsIgnoreCase(TAG_TABLE_SI[0]) || tagName.equalsIgnoreCase(TAG_TABLE_SI[1])) { for (int i = 0; i < attrCount; i++) { attrValue = mParser.getAttributeValue(i); attrName = mParser.getAttributeName(i); if(LOCAL_LOGV) { Log.i(LOG_TAG, "attrName = "+attrName + ", attrValue =" + attrValue); } if(PUSH_ATTR_NAME_MAP.containsKey(attrName)) { int attr = PUSH_ATTR_NAME_MAP.get(attrName); mPushMsg.setAttributeValue(attr, attrValue); } } } else { Log.e(LOG_TAG, "Unknown tag = " + tagName); } } //// SI Documents private static final String [] TAG_TABLE_SI = { "si", // 05 "indication", // 06 "info", // 07 "item", // 08 }; private static final String [] ATTR_START_TABLE_SI = { "action=signal-none", // 05 "action=signal-low", // 06 "action=signal-medium", // 07 "action=signal-high", // 08 "action=signal-delete", // 09 "created", // 0A "href", // 0B "href=http://", // 0C "href=http://www.", // 0D "href=https://", // 0E "href=https://www.", // 0F "si-expires", // 10 "si-id", // 11 "class", // 12 }; //// SL Documents private static final String [] TAG_TABLE_SL = { "sl", // 05 }; private static final String [] ATTR_START_TABLE_SL = { "action=execute-low", // 05 "action=execute-high",// 06 "action=cache", // 07 "href", // 08 "href=http://", // 09 "href=http://www.", // 0A "href=https://", // 0B "href=https://www.", // 0C }; //// COMMON FOR ALL PUHS DOCUMENTS private static final String [] ATTR_VALUE_TABLE_SI_SL = { ".com/", // 85 ".edu/", // 86 ".net/", // 87 ".org/", // 88 }; private static Hashtable<String,Integer> PUSH_ATTR_NAME_MAP; static { PUSH_ATTR_NAME_MAP = new Hashtable<String, Integer>(5); PUSH_ATTR_NAME_MAP.put("action", WapPushMsg.WAP_PUSH_PROJECTION_PRIOR); PUSH_ATTR_NAME_MAP.put("href", WapPushMsg.WAP_PUSH_PROJECTION_HREF); PUSH_ATTR_NAME_MAP.put("si-expires", WapPushMsg.WAP_PUSH_PROJECTION_SI_EXPIRED); PUSH_ATTR_NAME_MAP.put("created", WapPushMsg.WAP_PUSH_PROJECTION_SI_CREATED); PUSH_ATTR_NAME_MAP.put("si-id", WapPushMsg.WAP_PUSH_PROJECTION_SI_ID); } private static Hashtable<String,Integer> PUSH_ATTR_VALUE_MAP; static { PUSH_ATTR_VALUE_MAP = new Hashtable<String, Integer>(7); PUSH_ATTR_VALUE_MAP.put("signal-none", WapPushMsg.WAP_PUSH_PRIO_NONE); PUSH_ATTR_VALUE_MAP.put("signal-low", WapPushMsg.WAP_PUSH_PRIO_LOW); PUSH_ATTR_VALUE_MAP.put("signal-medium", WapPushMsg.WAP_PUSH_PRIO_MEDIUM); PUSH_ATTR_VALUE_MAP.put("signal-high", WapPushMsg.WAP_PUSH_PRIO_HIGH); PUSH_ATTR_VALUE_MAP.put("signal-delete", WapPushMsg.WAP_PUSH_PRIO_DELETE); PUSH_ATTR_VALUE_MAP.put("execute-low", WapPushMsg.WAP_PUSH_SL_PRIO_LOW); PUSH_ATTR_VALUE_MAP.put("execute-high", WapPushMsg.WAP_PUSH_SL_PRIO_HIGH); PUSH_ATTR_VALUE_MAP.put("cache", WapPushMsg.WAP_PUSH_SL_PRIO_CACHE); } public static int getPushAttrValue(String key){ //If the attribute is not specified, the value "signal-medium" is used.(copy from the document <wap-167-serviceind-20010731-a>) int nullresult = WapPushMsg.WAP_PUSH_PRIO_MEDIUM; if(key == null || key.trim().length() <= 0){ return nullresult; } Integer value = PUSH_ATTR_VALUE_MAP.get(key); if(value == null) return nullresult; return value.intValue(); } }