📄 wmldeckbuilder.java
字号:
package com.aplpi.wapreview;
import java.lang.String;
import java.io.InputStream;
import java.io.Reader;
import java.io.UTFDataFormatException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Hashtable;
import java.util.Stack;
import java.util.Enumeration;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.IOException;
import com.microstar.xml.XmlHandler;
import com.microstar.xml.XmlParser;
/**
*
* see http://wapreview.sourceforge.net
*
* Copyright (C) 2000 Robert Fuller, Applepie Solutions Ltd.
* <robert.fuller@applepiesolutions.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* This is the handler for parsing the wml content
* into a deck containing cards which can be displayed.
*
* @author Copyright (c) 2000, Applepie Solutions Ltd.
* @author Written by Robert Fuller <robert.fuller@applepiesolutions.com>
*
*/
public class WmlDeckBuilder implements XmlHandler {
public XmlParser parser;
private Hashtable attributes;
private Stack wmlelements;
private WmlTask sourceTask = null;
private String url = "http://oiler/not/set/yet";
public static String imgconverter = "http://www.applepiesolutions.com/cgi-bin/wbmp2gif?img=";
public static String gateway ="http://www.applepiesolutions.com/cgi-bin/lwpproxy.cgi";
public static String errlog = null;
private WmlDeck deck;
private URL sourceUrl;
private WmlDeck sourceDeck;
private ByteArrayOutputStream rawWML;
private int errors = 0; //keep count of errors
/**
* Construct a new WmlDeckBuilder
* using the provided deck and task as references.
*
* @param d The WmlDeck to use as a reference
* @param t The WmlTask to use as a reference
*/
public WmlDeckBuilder(WmlDeck d, WmlTask t){
sourceDeck = d;
sourceTask = t;
url = t.getUrl();
init();
}
/**
* Construct a new WmlDeckBuilder
* using the provided deck and url as references
*
* @param d The WmlDeck to use as a reference
* @param d A String representing the URL that contains the WML deck
* to be built.
*/
public WmlDeckBuilder(WmlDeck d, String u){
sourceDeck = d;
url = u;
init();
}
/**
* Start parsing the url specified when this WmlDeckBuilder
* was constructed. The constructed deck will be returned.
* If an error occurs while retrieving or parsing,
* a deck with a single card containing an error message
* will be constructed and returned.
*/
public WmlDeck startParse(){
if(sourceDeck != null){
//Expand any variables contained in the url
try{
url = sourceDeck.expandVariables(url);
}
catch(java.io.IOException E){
System.err.println("caught exception:"+E.toString());
}
}
try{
sourceUrl = new URL(url);
}
catch(java.net.MalformedURLException E){
sourceUrl = null;
}
wmlelements = new Stack();
attributes = new Hashtable();
deck = null;
System.err.println("URL:["+sourceUrl.toString()+"]");
/*
* Open a connection to the URL via the gateway.
* Send any post data to the URL, then
* retrieve the URL
*/
try {
XmlParser parser = new XmlParser();
parser.setHandler(this);
try{
URL url = new URL(gateway+sourceUrl.toString());
//System.err.println("url is to:"+gateway+systemId);
URLConnection connection = url.openConnection();
if(sourceTask != null){
connection.setDoOutput(true);
PrintWriter out =
new PrintWriter(connection.getOutputStream());
out.write(sourceTask.getparams());
out.close();
}
InputStream is = connection.getInputStream();
rawWML = new ByteArrayOutputStream();
int r;
while((r = is.read())>-1){
rawWML.write(r);
}
is.close();
rawWML.close(); //ok to do this?
connection=null;
url=null;
}
catch(java.io.IOException E){
System.err.println("Error:Cannot retrieve URL");
String ioerr=
"<wml><card title=\"Error!\"><p>The requested URL "
+ "<!--["+url.toString()+"]-->"
+"could not be retrieved.</p></card></wml>";
rawWML = new ByteArrayOutputStream();
rawWML.write(ioerr.getBytes());
}
catch(Exception E){
//Hmm.... error reading input stream
System.err.println("Error:"+E.toString());
throw (E);
}
/* Try to autodetect the encoding scheme. If we get a UTF-8
Encoding error, then retry iwth ISO-8859-1
*/
try{
parser.parse(url, null,
new ByteArrayInputStream(rawWML.toByteArray()),
(String)null);
}catch(UTFDataFormatException E){
parser.parse(url, null,
new ByteArrayInputStream(rawWML.toByteArray()),
"ISO-8859-1");
System.err.println("WARNING:Encoding MAY be ISO-8859-1");
}
System.err.println("[ok]");
}
catch (java.io.FileNotFoundException e){
deck = new WmlDeck(sourceUrl);
WmlCard ioerr = new WmlCard(deck, "file_not_found");
ioerr.cardData("<center><b>Error!</b></center>"+url
+"<br>not found.<br>");
deck.addCard(ioerr);
}
catch (Exception e) {
e.printStackTrace();
System.err.println("[not ok]"+e.getMessage());
logFatalError("fatal="+sourceUrl);
deck = new WmlDeck(sourceUrl);
WmlCard wmlerr = new WmlCard(deck, "wml_error");
wmlerr.cardData("<center><b>Error!</b></center>"+url
+"<br>may contain errors.<br>");
deck.addCard(wmlerr);
}
if(deck != null){
deck.url = url;
deck.wml(rawWML.toString());
}
return deck;
}
/**
* Initialise the deck builder when it is constructed.
*/
private void init ()
{
wmlelements = new Stack();
attributes = new Hashtable();
deck = null;
}
/**
* Logs a fatal error message on the server.
* This is useful for debugging purposes.
*/
private void logFatalError(String message){
errors++;
//log only one error at most...
if(errlog != null && errors<=1){
try{
URL url2 = new URL(gateway+errlog);
URLConnection connection = url2.openConnection();
connection.setDoOutput(true);
PrintWriter out =
new PrintWriter(connection.getOutputStream());
out.write(message);
out.close();
}
catch(Exception E){
// do nothing. The errlog could be wrong.
}
}
}
/**
* Resolve an external entity.
* <p>This method will generate a new URL which will be
* behind the proxy server. This is required, since an
* applet can only contact the server from which it was
* downloaded.
*/
public Object resolveEntity (String publicId, String systemId){
//System.err.println("resolveEntity:publicId="+publicId+"\n systemId="+systemId);
if(publicId == null){
//System.err.println("resolved to ["+gateway+systemId+"]");
return gateway+systemId;
}else{
return new ByteArrayInputStream(new String(
"<!ENTITY quot \""\"> <!-- quotation mark -->"
+"<!ENTITY amp \"&#38;\"> <!-- ampersand -->"
+"<!ENTITY apos \"'\"> <!-- apostrophe -->"
+"<!ENTITY lt \"&#60;\"> <!-- less than -->"
+"<!ENTITY gt \">\"> <!-- greater than -->"
+"<!ENTITY nbsp \" \"> <!-- non-breaking space -->"
+"<!ENTITY shy \"­\"> <!-- soft hyphen (discretionary hyphen) -->"
).getBytes());;
}
}
/**
* This method is required to implement XmlHandler interface
* but does nothing for now.
*
* @see com.microstar.xml.XmlHandler#startExternalEntity
*/
public void startExternalEntity (String systemId)
{
}
/**
* This method is required to implement XmlHandler interface
* but does nothing for now.
*
* @see com.microstar.xml.XmlHandler#endExternalEntity
*/
public void endExternalEntity (String systemId)
{
}
/**
* This method is required to implement XmlHandler interface
* but does nothing for now.
*
* @see com.microstar.xml.XmlHandler#startDocument
*/
public void startDocument ()
{
}
/**
* This method is required to implement XmlHandler interface
* but does nothing for now.
*
* @see com.microstar.xml.XmlHandler#endDocument
*/
public void endDocument ()
{
}
/**
* This method is required to implement XmlHandler interface
* but does nothing for now.
*
* @see com.microstar.xml.XmlHandler#doctypeDecl
*/
public void doctypeDecl (String name,
String pubid, String sysid)
{
}
/**
* Record the value of the named attribute.
* Since wapreview is non validating, the values of all attributes
* will be recorded, but unknown attributes will be
* ignored.
*
* @see com.microstar.xml.XmlHandler#attribute
*/
public void attribute (String name, String value,
boolean isSpecified)
{
if(attributes != null){
attributes.put(name.toLowerCase(), value);
}
}
/**
* Start the next WmlElement.
*/
private void beginWmlElement(){
if(!wmlelements.empty()){
wmlelement lastel = (wmlelement)wmlelements.peek();
lastel.begin(attributes);
}
attributes = new Hashtable();
}
/**
* Handle the start of an element.
* A new object of the internal class wmlelement is
* constructed, and given the attributes of this
* element for interperetation.
*
* @see com.microstar.xml.XmlHandler#startElement
*/
public void startElement (String name)
{
wmlelement el = new wmlelement(name, this);
el.begin(attributes);
attributes = new Hashtable();
wmlelements.push(el);
}
/**
* sets the current deck
*/
public void setDeck(WmlDeck d){
deck = d;
}
/**
* returns the current deck
*/
public WmlDeck getDeck(){
return deck;
}
/**
* Handle the end of an element.
* The current wmlelement is popped off the stack
* of wmlelements and it's end() method is invoked.
* @see com.microstar.xml.XmlHandler#endElement
*/
public void endElement (String name)
{
if(!wmlelements.empty()){
wmlelement el = (wmlelement) wmlelements.pop();
el.end();
}
}
/**
* Handle character data.
* <p>Character Data will appear unchanged in its dhtml representation.
*/
public void charData (char ch[], int start, int length)
{
String chdata = (new String(ch, start, length).replace('\n',' '));
if(deck != null){
WmlCardInterface card = deck.currentcard;
if(card != null){
card.cardData(this.encode(chdata,false));
}
}
}
/**
* This method is required to implement XmlHandler interface
* but does nothing for now.
*
* @see com.microstar.xml.XmlHandler#ignorableWhitespace
* Handle ignorable whitespace.
* <p>Do nothing for now. Insignificant whitespace is not of concern.
*/
public void ignorableWhitespace (char ch[],
int start, int length)
{
}
/**
* This method is required to implement XmlHandler interface
* but does nothing for now.
*
* @see com.microstar.xml.XmlHandler#
* Handle a processing instruction.
* <p>Do nothing for now.
*/
public void processingInstruction (String target,
String data)
{
}
/**
* Handle a parsing error.
* A message will be logged on the server, if possible.
* @see com.microstar.xml.XmlHandler#error
*/
public void error (String message,
String url, int line, int column)throws Exception
{
/**
* Catch UTF-8 encoding errors, we will subsequently
* retry with ISO-8859-1
*/
if(message != null && (message.indexOf("UTF-8")>-1)){
String emsg = "UTF-8 Encoding Error";
System.err.println(emsg);
throw new UTFDataFormatException(emsg);
}
/* Some other error... log it somewhere? */
String longMessage = "\nFATAL+ERROR=" + (message==null?"":message) +
"\nurl=" + (url==null?sourceUrl.toString():url.toString()) + "\nline=" + line
+ "\ncolumn=" + column + "\n";
System.err.println(longMessage);
//Try logging the message on the server
String params = "";
if(sourceTask != null){
params = "\n===========================\n"
+ sourceTask.getparams()
+ "\n===========================\n";
}
logFatalError(longMessage+params);
throw new Exception(message);
}
/**
* Re-encode encoded characters.
*/
public static String encode(String source, boolean encodeCR){
int i=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -