原文地址+源代碼 http://javaeye.5d6d.com/thread-150-1-1.html
Wap Explorer的核心部件 WML解釋引擎
今天也夠郁悶的,論壇一直上不去,不過也好,稱這下有時間,把Wap Explorer的核心部件剝離出來,給大家一個思路。
Wap Explorer的核心部件 WML解釋引擎。
做Wap的最重要的解釋解釋引擎了,不管是wml ,html,還是經過服務中轉的數據也好,最后來到 手機客戶端的時候都是要經過一個解釋引擎,說白了就是手機客戶端可以識別的數據。 據我所知道下面主流的Wap手機瀏覽器的做法是: 1. oprea mini 是通過服務器中轉的。 2. UCWeb 也是通過服務中轉,不過有一小部分是解釋wml的,特別是解釋html的是一定要通過服務器中轉。 3. 3GExplorer同上 4. 航海家,以前主要是解釋WML,不過最近新版本好像也是通過服務器中轉 5. Wap Explorer 全部解釋wml引擎。 6. 其他一些非主流的瀏覽器,基本上也是通過解釋wml的,因為他們自己本身沒有實力架構服務器吧
下面看看我寫的WML解釋引擎。下面直接運行WMLParser,我是采用輸出文本的形式來解釋的,至于解釋后生成UI以后再慢 慢詳說。 需要用到的只是,以及包: kxml
下面是一段核心代碼
/******************************************************************** * 項目名稱 :<b>j2me學習 J2me Wap Explorer</b> <br/> * * Copyright 2005-2006 Wuhua. All rights reserved </br> * * 本程序只用于學習目的,不能用于商業目的。如有需要請聯系作者 ********************************************************************/ package org.fox.wap.parser;
import java.io.IOException; import java.io.Reader; import java.util.Hashtable;
import javax.microedition.lcdui.Choice; import javax.microedition.lcdui.Font; import javax.microedition.lcdui.TextField;
import org.kxml2.io.KXmlParser; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException;
/** * <b>類名:WmlParser.java</b> </br> 編寫日期: 2006-12-29 <br/> * 程序功能描述:WML的解釋器, 采用Kxml解釋引擎。<br/> * 解釋策略是,解釋多少就繪制多少 <br/> * Demo: <br/> Bug: <br/> * * 程序變更日期 :<br/> 變更作者 :<br/> 變更說明 :<br/> * * @author wuhua </br> <a href="mailto:rrq12345@163.com">rrq12345@163.com</a> */ public final class WmlParser implements Parser {
private Hashtable attr = new Hashtable();
private String url; //記錄當前的URL
/** * 當前標記,通過當前標記來創建Wap UI. */ private String currentTag;
/** * 創建當前Align. */ private String align;
KXmlParser parser;
private WmlParser(String url) { parser = new KXmlParser(); this.url = url;
}
public static WmlParser getWmlParser(String url) { return new WmlParser(url); }
/** * 解釋wml,并生成一系列的Wap GUI部件。 比如遇到<a href="index.wml">首頁</a> 則對于的生成一個 * HyperLink; * * @see WAPGUIFactory.createHyperLink(String text, String url, String algin) ; * @param in -- * 通過Net獲取InputStream, 或者是本地文件解釋WML * @return -- 返回一個Vector集,里面包含了,Wap GUI * @throws XmlPullParserException -- * 解釋出錯的時候拋出異常 * @throws IOException -- * 讀取數據的時候拋出異常 */ public final void parser() throws Exception {
//logger.debug(System.currentTimeMillis()); ; int eventType;
eventType = parser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { if (eventType == XmlPullParser.START_DOCUMENT) { } else if (eventType == XmlPullParser.END_DOCUMENT) {
} else if (eventType == XmlPullParser.START_TAG) { parserStartTagImpl(parser); } else if (eventType == XmlPullParser.END_TAG) { parserEndTagImpl(); } else if (eventType == XmlPullParser.TEXT) { parserTextImpl(parser); } eventType = parser.next(); } Runtime.getRuntime().freeMemory();
//logger.debug(System.currentTimeMillis()); // return parts; }
public void setInput(Reader reader) throws XmlPullParserException {
parser.setInput(reader);
}
private void parserEndTagImpl() { String name = parser.getName(); if (name.equals(WmlTag.P_TAG) || name.equals(WmlTag.BR_TAG) || name.equals(WmlTag.CARD_TAG)) {
this.parserBrImpl(); }
}
/** * 此方法是處理各個標記 但是有一個問題,就是會出現兩次標記 比如 <a> </a>的時候就會處理兩次br * * @param parser */ private void parserTextImpl(KXmlParser parser) { parserAlign(); //logger.debug("Tag = " + currentTag + " Text = " // + this.parser.getText()); if (currentTag.equals(WmlTag.P_TAG)) { System.out.println("處理 P Tag "); //paserStringPart(Style.PLAIN_SMALL, align, true); } else if (currentTag.equals(WmlTag.A_TAG)) { System.out.println("處理 A Tag "); //parserHyperLinkImpl(parser); } else if (currentTag.equals(WmlTag.BR_TAG)) { System.out.println("處理 BR Tag "); //paserStringPart(Style.PLAIN_SMALL, align, true); } else if (currentTag.equals(WmlTag.CARD_TAG)) { System.out.println("處理 CARD Tag "); //parserCardTag(parser); } else if (currentTag.equals(WmlTag.BIG_TAG)) { System.out.println("處理 BIG Tag "); //parserBigTag(parser); } else if (currentTag.equals(WmlTag.U_TAG)) { System.out.println("處理 U Tag "); //parserUTag(parser); } else if (currentTag.equals(WmlTag.EM_TAG)) { System.out.println("處理 EM Tag "); //parserEmTag(parser); } else if (currentTag.equals(WmlTag.INPUT_TAG)) { System.out.println("處理 INPUT Tag "); //parserInputTag(); } else if (currentTag.equals(WmlTag.SELECT_TAG)) { System.out.println("處理 SELECT Tag "); //parserSelectTag(); } else if (currentTag.equals(WmlTag.OPTION_TAG)) { System.out.println("處理 OPTION_TAG "); //parserOptionTag(); } else { System.out.println("處理 String 內容 "); //paserStringPart(Style.PLAIN_SMALL, align, true); }
currentTag = WmlTag.UNKNOW;
}
/** * 處理圖片顯示問題,這里要處理圖片的相對路徑問題 * */ private void parserImgTag() {
}
private void parserOptionTag() {
}
/** * 處理Select標記 * */ private void parserSelectTag() {
}
/** * 處理InputTag * */ private void parserInputTag() {
}
private void parserEmTag() {
}
private void parserUTag() {
}
/** * 此方法是繪制,大字體時候用的。 * * @param parser */ private void parserBigTag() {
}
private void parserCardTag() {
}
/** * 處理<br/>標記 比如: -----<br/> <br/> ------ 則創建StringPart("---------")并且設計換行<br/> * 換行的實現是:Part.setNextRow(true); * * @param parser2 */ private void parserBrImpl() {
}
/** * 處理String的顯示 paintMainform();這個必須放在當text,或者是UI存在的時候才可以進行更新 * * @param font * TODO * @param align * TODO * @param nextRow * TODO * @param parser2 */ private void paserStringPart(Font font, String align, boolean nextRow) {
attr.clear(); }
/** * 處理HyperLink,并生成HyperLink控件 * * @param parser */ private void parserHyperLinkImpl(KXmlParser parser) {
attr.clear();
}
private void parserAlign() {
}
/** * 解釋Wap標記,并把屬性保存到attr * * @param parser */ private void parserStartTagImpl(KXmlParser parser) {
}
public Object getResult() { return null; }
}
源代碼里面具體可以運行main類,就可以看到結果了 有不明白的地方到這里討論。
|