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

📄 browser.java

📁 j2me is based on j2mepolish, client & server for mobile application. menu sample
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
//#condition polish.usePolishGui
/*
 * Created on 11-Jan-2006 at 19:20:28.
 * 
 * Copyright (c) 2007 Michael Koch / Enough Software
 *
 * This file is part of J2ME Polish.
 *
 * J2ME Polish 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.
 * 
 * J2ME Polish 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 J2ME Polish; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 
 * Commercial licenses are also available, please
 * refer to the accompanying LICENSE.txt or visit
 * http://www.j2mepolish.org for details.
 */
package de.enough.polish.browser;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Stack;

import javax.microedition.io.StreamConnection;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

import de.enough.polish.browser.protocols.HttpProtocolHandler;
import de.enough.polish.browser.protocols.ResourceProtocolHandler;
import de.enough.polish.io.RedirectHttpConnection;
import de.enough.polish.io.StringReader;
import de.enough.polish.util.HashMap;
import de.enough.polish.xml.SimplePullParser;
import de.enough.polish.xml.XmlPullParser;

//#if polish.LibraryBuild
	//# import de.enough.polish.ui.FakeContainerCustomItem;
//#else
	import de.enough.polish.ui.Container;
//#endif
import de.enough.polish.ui.Container;
import de.enough.polish.ui.Gauge;
import de.enough.polish.ui.Item;
import de.enough.polish.ui.Style;

/**
 * TODO: Write good docs.
 * 
 * polish.Browser.UserAgent
 * polish.Browser.MaxRedirects
 * polish.Browser.Gzip
 * polish.Browser.POISupport
 * polish.Browser.PaintDownloadIndicator
 * 
 * @see HttpProtocolHandler
 * @see ResourceProtocolHandler
 * @see RedirectHttpConnection
 */
public abstract class Browser
//#if polish.LibraryBuild
	//# extends FakeContainerCustomItem
//#else
  extends Container
//#endif
implements Runnable
 {
  private static final String BROKEN_IMAGE = "resource://broken.png";

  private HashMap imageCache = new HashMap();

  protected String currentDocumentBase = null;
  protected HashMap protocolHandlers = new HashMap();
  protected HashMap tagHandlers = new HashMap();
  
  protected Stack history = new Stack();
  //#if polish.Browser.PaintDownloadIndicator
	  //# protected Gauge loadingIndicator;
	  //# private boolean isStoppedWorking;
  //#endif
  
  private Thread loadingThread;
  private boolean isRunning;
  private boolean isWorking;
  private boolean isCancelRequested;
  private String nextUrl;

  /**
   * Creates a new Browser without any protocol handlers, tag handlers or style.
   */
  public Browser()
  {
	  //#style browser?
    this( (String[])null, (TagHandler[])null, (ProtocolHandler[]) null , de.enough.polish.ui.StyleSheet.browserStyle );
  }
  
  /**
   * Creates a new Browser without any protocol handler or tag handlers.
   * 
   * @param style the style of this browser
   */
  public Browser( Style style )
  {
    this( (String[])null, (TagHandler[])null, (ProtocolHandler[]) null, style );
  }

  /**
   * Creates a new Browser with the specified handlers and style.
   * 
   * @param protocolHandlers the tag handlers
   */
  public Browser( ProtocolHandler[] protocolHandlers )
  {
	  //#if polish.css.style.browser && !polish.LibraryBuild
	  	//#style browser
	  	this(protocolHandlers, de.enough.polish.ui.StyleSheet.browserStyle );
	  //#else
	  	//# this(protocolHandlers, null);
	  //#endif
  }
  
  /**
   * Creates a new Browser with the specified handlers and style.
   * 
   * @param protocolHandlers the tag handlers
   * @param style the style to use for the browser item
   */
  public Browser( ProtocolHandler[] protocolHandlers, Style style )
  {
	  this( (String[])null, (TagHandler[])null, protocolHandlers, style);
  }

  /**
   * Creates a new Browser with the specified handlers and style.
   * 
   * @param tagNames the names of the tags that the taghandler should handle (this allows to use a single taghandler for several tags)
   * @param tagHandlers the tag handlers
   * @param protocolHandlers the protocol handlers
   */
  public Browser( String[] tagNames, TagHandler[] tagHandlers, ProtocolHandler[] protocolHandlers )
  {
	  //#if polish.css.style.browser && !polish.LibraryBuild
	  	//#style browser
	  	this(tagNames, tagHandlers, protocolHandlers, de.enough.polish.ui.StyleSheet.browserStyle );
	  //#else
	  	//# this(tagNames,tagHandlers, protocolHandlers, null);
	  //#endif
  }

  /**
   * Creates a new Browser with the specified handlers and style.
   * 
   * @param tagNames the names of the tags that the taghandler should handle (this allows to use a single taghandler for several tags)
   * @param tagHandlers the tag handlers
   * @param protocolHandlers the protocol handlers
   * @param style the style of this browser
   */
  public Browser( String[] tagNames, TagHandler[] tagHandlers, ProtocolHandler[] protocolHandlers, Style style )
  {
    super( true, style );
    if (tagHandlers != null && tagNames != null && tagNames.length == tagHandlers.length) {
	    for (int i = 0; i < tagHandlers.length; i++) {
	    	TagHandler handler = tagHandlers[i];
			addTagHandler(tagNames[i], handler);
		}
    }
    if (protocolHandlers != null) {
    	for (int i = 0; i < protocolHandlers.length; i++) {
			ProtocolHandler handler = protocolHandlers[i];
			addProtocolHandler( handler );
			
		}
    }
    //#if polish.Browser.PaintDownloadIndicator
	    //#style browserDownloadIndicator
	    //# this.loadingIndicator = new Gauge(null, false, Gauge.INDEFINITE, Gauge.CONTINUOUS_RUNNING);
	//#endif
	this.loadingThread = new Thread( this );
	this.loadingThread.start();
  }
  
  /**
   * Instantiates and returns the default tag handlers for "http", "https" and "resource" URLs.
   * 
   * @return new default tag handlers
   * @see HttpProtocolHandler
   * @see ResourceProtocolHandler
   */
  protected static ProtocolHandler[] getDefaultProtocolHandlers() {
	  return new ProtocolHandler[] { new HttpProtocolHandler("http"), new HttpProtocolHandler("https"), new ResourceProtocolHandler("resource") };  
  }

  public void addTagCommand(String tagName, Command command)
  {
	  TagHandler handler = getTagHandler(tagName);
	  
    if (handler != null )
    {
		  handler.addTagCommand( tagName, command );
	  }
  }
  
  public void addAttributeCommand(String attributeName, String attributeValue, Command command)
  {
    addAttributeCommand(null, attributeName, attributeValue, command);
  }
  
  public void addAttributeCommand(String tagName, String attributeName, String attributeValue, Command command)
  {
	  TagHandler handler = getTagHandler(tagName);
	  
    if (handler != null )
    {
		  handler.addAttributeCommand( tagName, attributeName, attributeValue, command );
	  }
  }

  public void addProtocolHandler(ProtocolHandler handler)
  {
    this.protocolHandlers.put(handler.getProtocolName(), handler);
  }
  
  public void addProtocolHandler(String protocolName, ProtocolHandler handler)
  {
    this.protocolHandlers.put(protocolName, handler);
  }
  
  protected ProtocolHandler getProtocolHandler(String protocolName)
  {
    return (ProtocolHandler) this.protocolHandlers.get(protocolName);
  }

  protected ProtocolHandler getProtocolHandlerForURL(String url)
    throws IOException
  {
    int pos = url.indexOf(':');
    
    if (pos < 0)
    {
      throw new IOException("malformed url");
    }
    
    String protocol = url.substring(0, pos);
    ProtocolHandler handler = (ProtocolHandler) this.protocolHandlers.get(protocol);
    
    if (handler == null)
      throw new IOException("protocol handler not found");
    
    return handler;
  }
  
  public void addTagHandler(String tagName, TagHandler handler)
  {
    this.tagHandlers.put(new TagHandlerKey(tagName), handler);
  }
  
  public void addTagHandler(String tagName, String attributeName, String attributeValue, TagHandler handler)
  {
    TagHandlerKey key = new TagHandlerKey(tagName, attributeName, attributeValue);
    
    //#debug
    //# System.out.println("Browser.addTagHandler: adding key: " + key);
    
    this.tagHandlers.put(key, handler);
  }
  
  public TagHandler getTagHandler(String tagName)
  {
    TagHandlerKey key = new TagHandlerKey(tagName);
    return (TagHandler) this.tagHandlers.get(key);
  }
  
  public TagHandler getTagHandler(String tagName, String attributeName, String attributeValue)
  {
    TagHandlerKey key = new TagHandlerKey(tagName, attributeName, attributeValue);
    return (TagHandler) this.tagHandlers.get(key);
  }
  
  /**
   * @param parser the parser to read the page from
   */
  private void parsePage(SimplePullParser parser)
  {
    // Clear out all items in the browser.
    clear();
    
    // Clear image cache when visiting a new page.
    this.imageCache.clear();
    
    while (parser.next() != SimplePullParser.END_DOCUMENT)
    {
      if (parser.getType() == SimplePullParser.START_TAG
          || parser.getType() == SimplePullParser.END_TAG)
      {
        boolean openingTag = parser.getType() == SimplePullParser.START_TAG;

        //#debug
        //# System.out.println( "looking for handler for " + parser.getName()  + ", openingTag=" + openingTag );
        
        HashMap attributeMap = new HashMap();
        TagHandler handler = getTagHandler(parser, attributeMap);
        
        if (handler != null)
        {
          //#debug
          //# System.out.println("Michael: Calling handler: " + parser.getName() + " " + attributeMap);
          
          handler.handleTag(this, parser, parser.getName(), openingTag, attributeMap);
        }
        else
        {
          //#debug
        	//# System.out.println( "no handler for " + parser.getName() );
        }
      }
      else if (parser.getType() == SimplePullParser.TEXT)
      {
        handleText(parser.getText().trim());
      }
      else
      {
    	  System.out.println("unknown type: " + parser.getType() + ", name=" + parser.getName());
      }
    } // end while (parser.next() != PullParser.END_DOCUMENT)

    //#debug
    //# System.out.println("end of document...");
  }

  private TagHandler getTagHandler(SimplePullParser parser, HashMap attributeMap)
  {
    TagHandlerKey key;
    TagHandler handler = null;
    
    for (int i = 0; i < parser.getAttributeCount(); i++)
    {
      String attributeName = parser.getAttributeName(i);
      String attributeValue = parser.getAttributeValue(i);
      attributeMap.put(attributeName, attributeValue);
      
      key = new TagHandlerKey(parser.getName(),
                              attributeName,
                              attributeValue);
      handler = (TagHandler) this.tagHandlers.get(key);
      
      if (handler != null)
      {
        break;
      }
    }
    
    if (handler == null)
    {
      key = new TagHandlerKey(parser.getName());
      handler = (TagHandler) this.tagHandlers.get(key);
    }
    
    return handler;
  }
  
  /**
   * Handles norml text.
   *  
   * @param text the text
   */
  protected abstract void handleText(String text);

  /**
   * Loads a page from a given <code>Reader</code>.
   * 
   * @param reader the reader to load the page from
   * @throws IOException of an error occurs
   */
  public void loadPage(Reader reader)
    throws IOException
  {
    XmlPullParser xmlReader = new XmlPullParser(reader);
    xmlReader.relaxed = true;
    parsePage(xmlReader);
  }

  /**
   * "http://foo.bar.com/baz/blah.html" => "http://foo.bar.com"
   * <p>
   * "resource://baz/blah.html" => "resource://"
   */
  protected String protocolAndHostOf(String url)
  {
    if ("resource://".regionMatches(true, 0, url, 0, 11))
    {
      return "resource://";
    }
    else if ("http://".regionMatches(true, 0, url, 0, 7))
    {
      int hostStart = url.indexOf("//");
      // figure out what error checking to do here
      hostStart+=2;
      // look for next '/'. If none, assume rest of string is hostname
      int hostEnd = url.indexOf("/", hostStart);
    
      if (hostEnd != -1)
      {
        return url.substring(0, hostEnd);
      }
      else
      {
        return url;
      }
    }
    else
    {
      // unsupported protocol
      return url;
    }
  }

  /**
   * Takes a possibly relative URL, and generate an absolute URL, merging with
   * the current documentbase if needed.
   * 
   * <ol>
   * <li> If URL starts with http:// or resource:// leave it alone
   * <li> If URL starts with '/', prepend document base protocol and host name.
   * <li> Otherwise, it's a relative URL, so prepend current document base and
   * directory path.
   * </ol>
   * 
   * @param url the (possibly relative) URL
   * @return absolute URL
   */
  public String makeAbsoluteURL(String url)
  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -