原文地址+源代码 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类,就可以看到结果了 有不明白的地方到这里讨论。
|