⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wmldeckbuilder.java

📁 An open_source WAP browser. include Java code. support WML documents and WBMP images.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
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 &lt;robert.fuller@applepiesolutions.com&gt;
 *
 */
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 \"&#34;\">     <!-- quotation mark -->"
        +"<!ENTITY amp  \"&#38;#38;\"> <!-- ampersand -->"
        +"<!ENTITY apos \"&#39;\">     <!-- apostrophe -->"
        +"<!ENTITY lt   \"&#38;#60;\"> <!-- less than -->"
        +"<!ENTITY gt   \"&#62;\">     <!-- greater than -->"
        +"<!ENTITY nbsp \"&#160;\">    <!-- non-breaking space -->"
        +"<!ENTITY shy  \"&#173;\">    <!-- 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 + -