/* JEditorPane.java --
   Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath 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, or (at your option)
any later version.

GNU Classpath 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 GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing;

import java.awt.Container;
import java.awt.Dimension;
import java.io.BufferedInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;

import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleHyperlink;
import javax.accessibility.AccessibleHypertext;
import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleText;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.plaf.TextUI;
import javax.swing.text.AbstractDocument;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.Document;
import javax.swing.text.EditorKit;
import javax.swing.text.Element;
import javax.swing.text.JTextComponent;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
import javax.swing.text.WrappedPlainView;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;

/**
 * A powerful text editor component that can handle different types of
 * content.
 *
 * The JEditorPane text component is driven by an instance of
 * {@link EditorKit}. The editor kit is responsible for providing
 * a default {@link Document} implementation, a mechanism for loading
 * and saving documents of its supported content type and providing
 * a set of {@link Action}s for manipulating the content.
 *
 * By default the following content types are supported:
 * <ul>
 * <li><code>text/plain</code>: Plain text, handled by
 *   {@link javax.swing.text.DefaultEditorKit}.</li>
 * <li><code>text/html</code>: HTML 4.0 styled text, handled by
 *   {@link javax.swing.text.html.HTMLEditorKit}.</li>
 * <li><code>text/rtf</code>: RTF text, handled by
 *   {@link javax.swing.text.rtf.RTFEditorKit}.</li>
 * </ul>
 *
 * @author original author unknown
 * @author Roman Kennke (roman@kennke.org)
 * @author Anthony Balkissoon abalkiss at redhat dot com
 */
public class JEditorPane extends JTextComponent
{
  /**
   * Provides accessibility support for <code>JEditorPane</code>.
   *
   * @author Roman Kennke (kennke@aicas.com)
   */
  protected class AccessibleJEditorPane extends AccessibleJTextComponent
  {

    /**
     * Creates a new <code>AccessibleJEditorPane</code> object.
     */
    protected AccessibleJEditorPane()
    {
      super();
    }

    /**
     * Returns a description of this <code>AccessibleJEditorPane</code>. If
     * this property is not set, then this returns the content-type of the
     * editor pane.
     *
     * @return a description of this AccessibleJEditorPane
     */
    public String getAccessibleDescription()
    {
      String descr = super.getAccessibleDescription(); 
      if (descr == null)
        return getContentType();
      else
        return descr;
    }

    /**
     * Returns the accessible state of this <code>AccessibleJEditorPane</code>.
     *
     * @return  the accessible state of this <code>AccessibleJEditorPane</code>
     */
    public AccessibleStateSet getAccessibleStateSet()
    {
      AccessibleStateSet state = super.getAccessibleStateSet();
      // TODO: Figure out what state must be added here to the super's state.
      return state;
    }
  }

  /**
   * Provides accessibility support for <code>JEditorPane</code>s, when the
   * editor kit is an instance of {@link HTMLEditorKit}.
   *
   * @author Roman Kennke (kennke@aicas.com)
   */
  protected class AccessibleJEditorPaneHTML extends AccessibleJEditorPane
  {
    /**
     * Returns the accessible text of the <code>JEditorPane</code>. This will
     * be an instance of
     * {@link JEditorPaneAccessibleHypertextSupport}.
     *
     * @return the accessible text of the <code>JEditorPane</code>
     */
    public AccessibleText getAccessibleText()
    {
      return new JEditorPaneAccessibleHypertextSupport();
    }
  }

  /**
   * This is the accessible text that is returned by
   * {@link AccessibleJEditorPaneHTML#getAccessibleText()}.
   *
   * @author Roman Kennke (kennke@aicas.com)
   */
  protected class JEditorPaneAccessibleHypertextSupport
    extends AccessibleJEditorPane implements AccessibleHypertext
  {

    /**
     * Creates a new JEditorPaneAccessibleHypertextSupport object.
     */
    public JEditorPaneAccessibleHypertextSupport()
    {
      super();
    }
    
    /**
     * The accessible representation of a HTML link. 
     *
     * @author Roman Kennke (kennke@aicas.com)
     */
    public class HTMLLink extends AccessibleHyperlink
    {

      /**
       * The element in the document that represents the link.
       */
      Element element;

      /**
       * Creates a new <code>HTMLLink</code>.
       *
       * @param el the link element
       */
      public HTMLLink(Element el)
      {
        this.element = el;
      }

      /**
       * Returns <code>true</code> if this <code>HTMLLink</code> is still
       * valid. A <code>HTMLLink</code> can become invalid when the document
       * changes.
       *
       * @return <code>true</code> if this <code>HTMLLink</code> is still
       *         valid
       */
      public boolean isValid()
      {
        // I test here if the element at our element's start offset is the
        // same as the element in the document at this offset. If this is true,
        // I consider the link valid, if not, then this link no longer
        // represented by this HTMLLink and therefor invalid.
        HTMLDocument doc = (HTMLDocument) getDocument();
        return doc.getCharacterElement(element.getStartOffset()) == element;
      }

      /**
       * Returns the number of AccessibleActions in this link object. In
       * general, link have 1 AccessibleAction associated with them. There are
       * special cases where links can have multiple actions associated, like
       * in image maps.
       * 
       * @return the number of AccessibleActions in this link object
       */
      public int getAccessibleActionCount()
      {
        // TODO: Implement the special cases.
        return 1;
      }

      /**
       * Performs the specified action on the link object. This ususally means
       * activating the link.
       *
       * @return <code>true</code> if the action has been performed
       *         successfully, <code>false</code> otherwise
       */
      public boolean doAccessibleAction(int i)
      {
        String href = (String) element.getAttributes().getAttribute("href");
        HTMLDocument doc = (HTMLDocument) getDocument();
        try
          {
            URL url = new URL(doc.getBase(), href);
            setPage(url);
            String desc = doc.getText(element.getStartOffset(),
                            element.getEndOffset() - element.getStartOffset());
            HyperlinkEvent ev =
              new HyperlinkEvent(JEditorPane.this,
                                 HyperlinkEvent.EventType.ACTIVATED, url, desc,
                                 element);
            fireHyperlinkUpdate(ev);
            return true;
          }
        catch (Exception ex)
          {
            return false;
          }
      }

      /**
       * Returns the description of the action at action index <code>i</code>.
       * This method returns the text within the element associated with this
       * link.
       *
       * @param i the action index
       *
       * @return the description of the action at action index <code>i</code>
       */
      public String getAccessibleActionDescription(int i)
      {
        HTMLDocument doc = (HTMLDocument) getDocument();
        try
          {
            return doc.getText(element.getStartOffset(),
                            element.getEndOffset() - element.getStartOffset());
          }
        catch (BadLocationException ex)
          {
            throw (AssertionError)
            new AssertionError("BadLocationException must not be thrown "
                               + "here.")
              .initCause(ex);
          }
      }

      /**
       * Returns an {@link URL} object, that represents the action at action
       * index <code>i</code>.
       *
       * @param i the action index
       *
       * @return an {@link URL} object, that represents the action at action
       *         index <code>i</code>
       */
      public Object getAccessibleActionObject(int i)
      {
        String href = (String) element.getAttributes().getAttribute("href");
        HTMLDocument doc = (HTMLDocument) getDocument();
        try
          {
            URL url = new URL(doc.getBase(), href);
            return url;
          }
        catch (MalformedURLException ex)
          {
            return null;
          }
      }

      /**
       * Returns an object that represents the link anchor. For examples, if
       * the link encloses a string, then a <code>String</code> object is
       * returned, if the link encloses an &lt;img&gt; tag, then an
       * <code>ImageIcon</code> object is returned.
       *
       * @return an object that represents the link anchor
       */
      public Object getAccessibleActionAnchor(int i)
      {
        // TODO: This is only the String case. Implement all cases.
        return getAccessibleActionDescription(i);
      }

      /**
       * Returns the start index of the hyperlink element.
       *
       * @return the start index of the hyperlink element
       */
      public int getStartIndex()
      {
        return element.getStartOffset();
      }

      /**
       * Returns the end index of the hyperlink element.
       *
       * @return the end index of the hyperlink element
       */
      public int getEndIndex()
      {
        return element.getEndOffset();
      }
      
    }

    /**
     * Returns the number of hyperlinks in the document.
     *
     * @return the number of hyperlinks in the document
     */
    public int getLinkCount()
    {
      HTMLDocument doc = (HTMLDocument) getDocument();
      HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
      int count = 0;
      while (linkIter.isValid())
        {
          count++;
          linkIter.next();
        }
      return count;
    }

    /**
     * Returns the <code>i</code>-th hyperlink in the document or
     * <code>null</code> if there is no hyperlink with the specified index.
     *
     * @param i the index of the hyperlink to return
     *
     * @return the <code>i</code>-th hyperlink in the document or
     *         <code>null</code> if there is no hyperlink with the specified
     *         index
     */
    public AccessibleHyperlink getLink(int i)
    {
      HTMLDocument doc = (HTMLDocument) getDocument();
      HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
      int count = 0;
      while (linkIter.isValid())
        {
          count++;
          if (count == i)
            break;
          linkIter.next();
        }
      if (linkIter.isValid())
        {
          int offset = linkIter.getStartOffset();
          // TODO: I fetch the element for the link via getCharacterElement().
          // I am not sure that this is correct, maybe we must use
          // getParagraphElement()?
          Element el = doc.getCharacterElement(offset);
          HTMLLink link = new HTMLLink(el);
          return link;
        }
      else
        return null;
    }

    /**
     * Returns the index of the link element at the character position
     * <code>c</code> within the document, or <code>-1</code> if there is no
     * link at the specified position.
     *
     * @param c the character index from which to fetch the link index
     *
     * @return the index of the link element at the character position
     *         <code>c</code> within the document, or <code>-1</code> if there
     *         is no link at the specified position
     */
    public int getLinkIndex(int c)
    {
      HTMLDocument doc = (HTMLDocument) getDocument();
      HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
      int count = 0;
      while (linkIter.isValid())
        {
          if (linkIter.getStartOffset() <= c && linkIter.getEndOffset() > c)
            break;
          count++;
          linkIter.next();
        }
      if (linkIter.isValid())
        return count;
      else
        return -1;
    }

    /**
     * Returns the link text of the link at index <code>i</code>, or
     * <code>null</code>, if there is no link at the specified position.
     *
     * @param i the index of the link
     *
     * @return  the link text of the link at index <code>i</code>, or
     *          <code>null</code>, if there is no link at the specified
     *          position
     */
    public String getLinkText(int i)
    {
      HTMLDocument doc = (HTMLDocument) getDocument();
      HTMLDocument.Iterator linkIter = doc.getIterator(HTML.Tag.A);
      int count = 0;
      while (linkIter.isValid())
        {
          count++;
          if (count == i)
            break;
          linkIter.next();
        }
      if (linkIter.isValid())
        {
          int offset = linkIter.getStartOffset();
          // TODO: I fetch the element for the link via getCharacterElement().
          // I am not sure that this is correct, maybe we must use
          // getParagraphElement()?
          Element el = doc.getCharacterElement(offset);
          try
            {
              String text = doc.getText(el.getStartOffset(),
                                      el.getEndOffset() - el.getStartOffset());
              return text;
            }
          catch (BadLocationException ex)
            {
              throw (AssertionError)
                new AssertionError("BadLocationException must not be thrown "
                                   + "here.")
                  .initCause(ex);
            }
        }
      else
        return null;
    }
  }

  /**
   * Used to store a mapping for content-type to editor kit class.
   */
  private static class EditorKitMapping
  {
    /**
     * The classname of the editor kit.
     */
    String className;

    /**
     * The classloader with which the kit is to be loaded.
     */
    ClassLoader classLoader;

    /**
     * Creates a new EditorKitMapping object.
     * 
     * @param cn the classname
     * @param cl the classloader
     */
    EditorKitMapping(String cn, ClassLoader cl)
    {
      className = cn;
      classLoader = cl;
    }
  }

  /**
   * An EditorKit used for plain text. This is the default editor kit for
   * JEditorPanes.
   *
   * @author Roman Kennke (kennke@aicas.com)
   */
  private static class PlainEditorKit extends DefaultEditorKit
  {

    /**
     * Returns a ViewFactory that supplies WrappedPlainViews.
     */
    public ViewFactory getViewFactory()
    {
      return new ViewFactory()
      {
        public View create(Element el)
        {
          return new WrappedPlainView(el);
        }
      };
    }
  }

  /**
   * A special stream that can be cancelled.
   */
  private class PageStream
    extends FilterInputStream
  {
    /**
     * True when the stream has been cancelled, false otherwise.
     */
    private boolean cancelled;

    protected PageStream(InputStream in)
    {
      super(in);
      cancelled = false;
    }

    private void checkCancelled()
      throws IOException
    {
      if (cancelled)
        throw new IOException("Stream has been cancelled");
    }

    void cancel()
    {
      cancelled = true;
    }

    public int read()
      throws IOException
    {
      checkCancelled();
      return super.read();
    }

    public int read(byte[] b, int off, int len)
      throws IOException
    {
      checkCancelled();
      return super.read(b, off, len);
    }

    public long skip(long n)
      throws IOException
    {
      checkCancelled();
      return super.skip(n);
    }

    public int available()
      throws IOException
    {
      checkCancelled();
      return super.available();
    }

    public void reset()
      throws IOException
    {
      checkCancelled();
      super.reset();
    }
  }

  /**
   * The thread that loads documents asynchronously.
   */
  private class PageLoader
    implements Runnable
  {
    private Document doc;
    private PageStream in;
    private URL old;
    URL page;
    PageLoader(Document doc, InputStream in, URL old, URL page)
    {
      this.doc = doc;
      this.in = new PageStream(in);
      this.old = old;
      this.page = page;
    }

    public void run()
    {
      try
        {
          read(in, doc);
        }
      catch (IOException ex)
        {
          UIManager.getLookAndFeel().provideErrorFeedback(JEditorPane.this);
        }
      finally
        {
          if (SwingUtilities.isEventDispatchThread())
            firePropertyChange("page", old, page);
          else
            {
              SwingUtilities.invokeLater(new Runnable()
              {
                public void run()
                {
                  firePropertyChange("page", old, page);
                }
              });
            }
         }
     }

     void cancel()
     {
       in.cancel();
     }
  }

  private static final long serialVersionUID = 3140472492599046285L;
  
  private EditorKit editorKit;
  
  boolean focus_root;
  
  /**
   * Maps content-types to editor kit instances.
   */
  static HashMap editorKits;

  // A mapping between content types and registered EditorKit types
  static HashMap registerMap;

  static
  {
    registerMap = new HashMap();
    editorKits = new HashMap();
    registerEditorKitForContentType("application/rtf",
                                    "javax.swing.text.rtf.RTFEditorKit");
    registerEditorKitForContentType("text/plain",
                                    "javax.swing.JEditorPane$PlainEditorKit");
    registerEditorKitForContentType("text/html",
                                    "javax.swing.text.html.HTMLEditorKit");
    registerEditorKitForContentType("text/rtf",
                                    "javax.swing.text.rtf.RTFEditorKit");

  }

  // A mapping between content types and used EditorKits
  HashMap editorMap;  

  /**
   * The currently loading stream, if any.
   */
  private PageLoader loader;

  public JEditorPane()
  {
    init();
    setEditorKit(createDefaultEditorKit());
  }

  public JEditorPane(String url) throws IOException
  {
    this(new URL(url));
  }

  public JEditorPane(String type, String text)
  {
    init();
    setEditorKit(createEditorKitForContentType(type));
    setText(text);
  }

  public JEditorPane(URL url) throws IOException
  {
    init();
    setEditorKit(createEditorKitForContentType("text/html"));
    setPage(url);
  }
  
  /**
   * Called by the constructors to set up the default bindings for content 
   * types and EditorKits.
   */
  void init()
  {
    editorMap = new HashMap();
  }

  protected EditorKit createDefaultEditorKit()
  {
    return new PlainEditorKit();
  }

  /**
   * Creates and returns an EditorKit that is appropriate for the given 
   * content type.  This is created using the default recognized types
   * plus any EditorKit types that have been registered.
   * 
   * @see #registerEditorKitForContentType(String, String)
   * @see #registerEditorKitForContentType(String, String, ClassLoader)
   * @param type the content type
   * @return an EditorKit for use with the given content type
   */
  public static EditorKit createEditorKitForContentType(String type)
  {
    // Try cached instance.
    EditorKit e = (EditorKit) editorKits.get(type);
    if (e == null)
      {
        EditorKitMapping m = (EditorKitMapping) registerMap.get(type);
        if (m != null)
          {
            String className = m.className;
            ClassLoader loader = m.classLoader;
            try
              {
                e = (EditorKit) loader.loadClass(className).newInstance();
              }
            catch (Exception e2)
              {    
                // The reference implementation returns null when class is not
                // loadable or instantiatable.
              }
          }
        // Cache this for later retrieval.
        if (e != null)
          editorKits.put(type, e);
      }
    return e;
  }

  /**
   * Sends a given <code>HyperlinkEvent</code> to all registered listeners.
   *
   * @param event the event to send
   */
  public void fireHyperlinkUpdate(HyperlinkEvent event)
  {
    HyperlinkListener[] listeners = getHyperlinkListeners();

    for (int index = 0; index < listeners.length; ++index)
       listeners[index].hyperlinkUpdate(event);
  }

  /**
   * Returns the accessible context associated with this editor pane.
   *
   * @return the accessible context associated with this editor pane
   */
  public AccessibleContext getAccessibleContext()
  {
    if (accessibleContext == null)
      {
        if (getEditorKit() instanceof HTMLEditorKit)
          accessibleContext = new AccessibleJEditorPaneHTML();
        else
          accessibleContext = new AccessibleJEditorPane();
      }
    return accessibleContext;
  }

  public final String getContentType()
  {
    return getEditorKit().getContentType();
  }

  /**
   * Returns the EditorKit. If there is no EditorKit set this method
   * calls createDefaultEditorKit() and setEditorKit() first.
   */
  public EditorKit getEditorKit()
  {
    if (editorKit == null)
      setEditorKit(createDefaultEditorKit());
    return editorKit;
  }

  /**
   * Returns the class name of the EditorKit associated with the given
   * content type.
   * 
   * @since 1.3
   * @param type the content type
   * @return the class name of the EditorKit associated with this content type
   */
  public static String getEditorKitClassNameForContentType(String type)
  {
    EditorKitMapping m = (EditorKitMapping) registerMap.get(type);
    String kitName = m != null ? m.className : null;
    return kitName;
  }

  /**
   * Returns the EditorKit to use for the given content type.  If an
   * EditorKit has been explicitly set via 
   * <code>setEditorKitForContentType</code>
   * then it will be returned.  Otherwise an attempt will be made to create
   * an EditorKit from the default recognzied content types or any
   * EditorKits that have been registered.  If none can be created, a
   * PlainEditorKit is created.
   * 
   * @see #registerEditorKitForContentType(String, String)
   * @see #registerEditorKitForContentType(String, String, ClassLoader)
   * @param type the content type
   * @return an appropriate EditorKit for the given content type
   */
  public EditorKit getEditorKitForContentType(String type)
  {
    // First check if an EditorKit has been explicitly set.
    EditorKit e = (EditorKit) editorMap.get(type);
    // Then check to see if we can create one.
    if (e == null)
      {
        e = createEditorKitForContentType(type);
        if (e != null)
          setEditorKitForContentType(type, e);
      }
    // Otherwise default to PlainEditorKit.
    if (e == null)
      e = createDefaultEditorKit();
    return e;
  }

  /**
   * Returns the preferred size for the JEditorPane. This is implemented to
   * return the super's preferred size, unless one of
   * {@link #getScrollableTracksViewportHeight()} or
   * {@link #getScrollableTracksViewportWidth()} returns <code>true</code>,
   * in which case the preferred width and/or height is replaced by the UI's
   * minimum size.
   *
   * @return the preferred size for the JEditorPane
   */
  public Dimension getPreferredSize()
  {
    Dimension pref = super.getPreferredSize();
    Container parent = getParent();
    if (parent instanceof JViewport)
      {
        JViewport vp = (JViewport) getParent();
        TextUI ui = getUI();
        Dimension min = null;
        if (! getScrollableTracksViewportWidth())
          {
            min = ui.getMinimumSize(this);
            int vpWidth = vp.getWidth();
            if (vpWidth != 0 && vpWidth < min.width)
              pref.width = min.width;
          }
        if (! getScrollableTracksViewportHeight())
          {
            if (min == null)
              min = ui.getMinimumSize(this);
            int vpHeight = vp.getHeight();
            if (vpHeight != 0 && vpHeight < min.height)
              pref.height = min.height;
          }
      }
    return pref;
  }

  /**
   * Returns <code>true</code> when a Viewport should force the height of
   * this component to match the viewport height. This is implemented to return
   * <code>true</code> when  the parent is an instance of JViewport and
   * the viewport height > the UI's minimum height.
   *
   * @return <code>true</code> when a Viewport should force the height of
   *         this component to match the viewport height
   */
  public boolean getScrollableTracksViewportHeight()
  {
    // Tests show that this returns true when the parent is a JViewport
    // and has a height > minimum UI height.
    Container parent = getParent();
    int height = parent.getHeight();
    TextUI ui = getUI();
    return parent instanceof JViewport
           && height >= ui.getMinimumSize(this).height
           && height <= ui.getMaximumSize(this).height;
  }

  /**
   * Returns <code>true</code> when a Viewport should force the width of
   * this component to match the viewport width. This is implemented to return
   * <code>true</code> when  the parent is an instance of JViewport and
   * the viewport width > the UI's minimum width.
   *
   * @return <code>true</code> when a Viewport should force the width of
   *         this component to match the viewport width
   */
  public boolean getScrollableTracksViewportWidth()
  {
    // Tests show that this returns true when the parent is a JViewport
    // and has a width > minimum UI width.
    Container parent = getParent();
    return parent != null && parent instanceof JViewport
           && parent.getWidth() > getUI().getMinimumSize(this).width;
  }

  public URL getPage()
  {
    return loader != null ? loader.page : null;
  }

  protected InputStream getStream(URL page)
    throws IOException
  {
    URLConnection conn = page.openConnection();
    // Try to detect the content type of the stream data.
    String type = conn.getContentType();
    if (type != null)
      setContentType(type);
    InputStream stream = conn.getInputStream();
    return new BufferedInputStream(stream);
  }

  public String getText()
  {
    return super.getText();
  }

  public String getUIClassID()
  {
    return "EditorPaneUI";
  }

  public boolean isFocusCycleRoot()
  {
    return focus_root;
  }

  protected String paramString()
  {
    return "JEditorPane";
  }

  /**
   * This method initializes from a stream. 
   */
  public void read(InputStream in, Object desc) throws IOException
  {
    EditorKit kit = getEditorKit();
    if (kit instanceof HTMLEditorKit && desc instanceof HTMLDocument)
      {
        HTMLDocument doc = (HTMLDocument) desc;
        setDocument(doc);
        try
          {
            InputStreamReader reader = new InputStreamReader(in);
            kit.read(reader, doc, 0);
          }
        catch (BadLocationException ex)
          {
            assert false : "BadLocationException must not be thrown here.";
          }
      }
    else
      {
        Reader inRead = new InputStreamReader(in);
        super.read(inRead, desc);
      }
  }

  /**
   * Establishes a binding between type and classname.  This enables
   * us to create an EditorKit later for the given content type.
   * 
   * @param type the content type
   * @param classname the name of the class that is associated with this 
   * content type
   */
  public static void registerEditorKitForContentType(String type,
                                                     String classname)
  {
    registerEditorKitForContentType(type, classname,
                               Thread.currentThread().getContextClassLoader());
  }

  /**
   * Establishes the default bindings of type to classname.
   */
  public static void registerEditorKitForContentType(String type,
                                                     String classname,
                                                     ClassLoader loader)
  {
    registerMap.put(type, new EditorKitMapping(classname, loader));
  }

  /**
   * Replaces the currently selected content with new content represented
   * by the given string.
   */
  public void replaceSelection(String content)
  {
    // TODO: Implement this properly.
    super.replaceSelection(content);
  }

  /**
   * Scrolls the view to the given reference location (that is, the value
   * returned by the UL.getRef method for the URL being displayed).
   */
  public void scrollToReference(String reference)
  {
    // TODO: Implement this properly.
  }

  public final void setContentType(String type)
  {
    // Strip off content type parameters.
    int paramIndex = type.indexOf(';');
    if (paramIndex > -1)
      {
        // TODO: Handle character encoding.
        type = type.substring(0, paramIndex).trim();
      }
    if (editorKit != null
	&& editorKit.getContentType().equals(type))
      return;
    	      
    EditorKit kit = getEditorKitForContentType(type);
	    	
    if (kit != null)
      setEditorKit(kit);
  }

  public void setEditorKit(EditorKit newValue)
  {
    if (editorKit == newValue)
      return;
    	
    if (editorKit != null)
      editorKit.deinstall(this);
	    	    
    EditorKit oldValue = editorKit;
    editorKit = newValue;
			    	
    if (editorKit != null)
      {
	editorKit.install(this);
	setDocument(editorKit.createDefaultDocument());
      }
				    	    
    firePropertyChange("editorKit", oldValue, newValue);
    invalidate();
    repaint();
    // Reset the accessibleContext since this depends on the editorKit.
    accessibleContext = null;
  }

  /**
   * Explicitly sets an EditorKit to be used for the given content type.
   * @param type the content type
   * @param k the EditorKit to use for the given content type
   */
  public void setEditorKitForContentType(String type, EditorKit k)
  {
    editorMap.put(type, k);
  }

  /**
   * Sets the current URL being displayed.  
   */
  public void setPage(String url) throws IOException
  {
    setPage(new URL(url));
  }

  /**
   * Sets the current URL being displayed.  
   */
  public void setPage(URL page) throws IOException
  {
    if (page == null)
      throw new IOException("invalid url");

    URL old = getPage();
    // Only reload if the URL doesn't point to the same file.
    // This is not the same as equals because there might be different
    // URLs on the same file with different anchors.
    if (old == null || ! old.sameFile(page))
      {
        InputStream in = getStream(page);
        if (editorKit != null)
          {
            Document doc = editorKit.createDefaultDocument();
            doc.putProperty(Document.StreamDescriptionProperty, page);

            if (loader != null)
              loader.cancel();
            loader = new PageLoader(doc, in, old, page);

            int prio = -1;
            if (doc instanceof AbstractDocument)
              {
                AbstractDocument aDoc = (AbstractDocument) doc;
                prio = aDoc.getAsynchronousLoadPriority();
              }
            if (prio >= 0)
              {
                // Load asynchronously.
                setDocument(doc);
                Thread loadThread = new Thread(loader,
                                               "JEditorPane.PageLoader");
                loadThread.setDaemon(true);
                loadThread.setPriority(prio);
                loadThread.start();
              }
            else
              {
                // Load synchronously.
                loader.run();
                setDocument(doc);
              }
          }
      }
  }

  /**
   * Sets the text of the JEditorPane.  The argument <code>t</code>
   * is expected to be in the format of the current EditorKit.  This removes
   * the content of the current document and uses the EditorKit to read in the
   * new text.  This allows the EditorKit to handle the String rather than just
   * inserting in plain text.
   * 
   * @param t the text to display in this JEditorPane
   */
  public void setText(String t)
  {
    try
    {
      // Remove the current content.
      Document doc = getDocument();
      doc.remove(0, doc.getLength());
      if (t == null || t.equals(""))
        return;
      
      // Let the EditorKit read the text into the Document.
      getEditorKit().read(new StringReader(t), doc, 0);
    }
    catch (BadLocationException ble)
    {
      // TODO: Don't know what to do here.
    }
    catch (IOException ioe)
    {
      // TODO: Don't know what to do here.
    }
  }

  /**
   * Add a <code>HyperlinkListener</code> object to this editor pane.
   *
   * @param listener the listener to add
   */
  public void addHyperlinkListener(HyperlinkListener listener)
  {
    listenerList.add(HyperlinkListener.class, listener);
  }

  /**
   * Removes a <code>HyperlinkListener</code> object to this editor pane.
   *
   * @param listener the listener to remove
   */
  public void removeHyperlinkListener(HyperlinkListener listener)
  {
    listenerList.remove(HyperlinkListener.class, listener);
  }

  /**
   * Returns all added <code>HyperlinkListener</code> objects.
   *
   * @return array of listeners
   *
   * @since 1.4
   */
  public HyperlinkListener[] getHyperlinkListeners()
  {
    return (HyperlinkListener[]) getListeners(HyperlinkListener.class);
  }
}
