You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jmeter-dev@jakarta.apache.org by wo...@apache.org on 2003/10/16 21:08:20 UTC

cvs commit: jakarta-jmeter/src/htmlparser/org/htmlparser/beans BeanyBaby.java HTMLLinkBean.java HTMLTextBean.java LinkBean.java StringBean.java

woolfel     2003/10/16 12:08:20

  Added:       src/htmlparser/org/htmlparser/beans BeanyBaby.java
                        HTMLLinkBean.java HTMLTextBean.java LinkBean.java
                        StringBean.java
  Log:
  adding more classes
  
  Revision  Changes    Path
  1.1                  jakarta-jmeter/src/htmlparser/org/htmlparser/beans/BeanyBaby.java
  
  Index: BeanyBaby.java
  ===================================================================
  /*
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   * if any, must include the following acknowledgment:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowledgment may appear in the software itself,
   * if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   * "Apache JMeter" must not be used to endorse or promote products
   * derived from this software without prior written permission. For
   * written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   * "Apache JMeter", nor may "Apache" appear in their name, without
   * prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   * 
   */
  
  // The developers of JMeter and Apache are greatful to the developers
  // of HTMLParser for giving Apache Software Foundation a non-exclusive
  // license. The performance benefits of HTMLParser are clear and the
  // users of JMeter will benefit from the hard work the HTMLParser
  // team. For detailed information about HTMLParser, the project is
  // hosted on sourceforge at http://htmlparser.sourceforge.net/.
  //
  // HTMLParser was originally created by Somik Raha in 2000. Since then
  // a healthy community of users has formed and helped refine the
  // design so that it is able to tackle the difficult task of parsing
  // dirty HTML. Derrick Oswald is the current lead developer and was kind
  // enough to assist JMeter.
  
  package org.htmlparser.beans;
  
  import javax.swing.JCheckBoxMenuItem;
  import javax.swing.JMenuItem;
  
  /**
   * Demo of beans.
   * Created on December 30, 2002, 7:54 PM
   * @author Derrick Oswald
   */
  public class BeanyBaby
      extends javax.swing.JFrame
      implements
          java.beans.PropertyChangeListener,
          java.awt.event.ActionListener,
          java.awt.event.MouseListener
  {
      /**
       * Bread crumb trail of visited URLs.
       */
      java.util.Vector mTrail;
  
      /**
       * Current position on the bread crumb trail.
       */
      int mCrumb;
  
      /** Creates new form BeanyBaby */
      public BeanyBaby()
      {
          initComponents();
          mTrail = new java.util.Vector(25);
          mCrumb = -1;
  
          // shenanigans to get the splitter bar at the midpoint
          show();
          mSplitPane.setDividerLocation(0.5);
          hide();
  
          // set up twinning
          mLinkBean.addPropertyChangeListener(this);
          mStringBean.addPropertyChangeListener(this);
          // set up user input
          mTextField.addActionListener(this);
          mLinkBean.addMouseListener(this);
  
          // set initial checkbox states
          mLinks.setSelected(mStringBean.getLinks());
          mCollapse.setSelected(mStringBean.getCollapse());
          mNobreak.setSelected(mStringBean.getReplaceNonBreakingSpaces());
      }
  
      //
      // PropertyChangeListener interface
      //
  
      /**
       * This method ties the two beans together on the same connection.
       * Whenever a property changes on one bean, make sure the URL properties
       * agree by setting the connection from one to the other.
       * @param event The event describing the event source
       * and the property that has changed.
       */
      public void propertyChange(java.beans.PropertyChangeEvent event)
      {
          Object source;
          String name;
  
          source = event.getSource();
          if (source == mLinkBean)
          {
              if (!mLinkBean.getURL().equals(mStringBean.getURL()))
                  mStringBean.setConnection(mLinkBean.getConnection());
          }
          else if (source == mStringBean)
          {
              if (!mStringBean.getURL().equals(mLinkBean.getURL()))
                  mLinkBean.setConnection(mStringBean.getConnection());
              // check for menu status changes
              name = event.getPropertyName();
              if (name.equals(StringBean.PROP_LINKS_PROPERTY))
                  mLinks.setSelected(
                      ((Boolean) event.getNewValue()).booleanValue());
              else if (name.equals(StringBean.PROP_COLLAPSE_PROPERTY))
                  mCollapse.setSelected(
                      ((Boolean) event.getNewValue()).booleanValue());
              else if (name.equals(StringBean.PROP_REPLACE_SPACE_PROPERTY))
                  mNobreak.setSelected(
                      ((Boolean) event.getNewValue()).booleanValue());
          }
      }
  
      //
      // ActionListener interface
      //
  
      public void actionPerformed(java.awt.event.ActionEvent event)
      {
          Object source;
          String url;
          String name;
          JMenuItem item;
  
          source = event.getSource();
          if (source == mTextField)
          {
              url = mTextField.getText();
              mTextField.selectAll();
              setURL(url);
          }
          else if (source instanceof JCheckBoxMenuItem)
          {
              item = (JMenuItem) source;
              name = item.getName();
              if ("Links".equals(name))
                  mStringBean.setLinks(item.isSelected());
              else if ("Collapse".equals(name))
                  mStringBean.setCollapse(item.isSelected());
              else if ("Nobreak".equals(name))
                  mStringBean.setReplaceNonBreakingSpaces(item.isSelected());
          }
          else if (source instanceof JMenuItem)
          {
              name = ((JMenuItem) source).getName();
              if ("Back".equals(name))
              {
                  if (mCrumb > 0)
                  {
                      mCrumb--;
                      url = (String) mTrail.elementAt(mCrumb);
                      mCrumb--;
                      setURL(url);
                  }
              }
              else if ("Forward".equals(name))
              {
                  if (mCrumb < mTrail.size())
                  {
                      mCrumb++;
                      url = (String) mTrail.elementAt(mCrumb);
                      mCrumb--;
                      setURL(url);
                  }
              }
          }
  
      }
  
      //
      // MouseListener interface
      //
      /**
       * Invoked when the mouse button has been clicked (pressed and released) on a component.
       */
      public void mouseClicked(java.awt.event.MouseEvent event)
      {
          int index;
          String url;
  
          if (2 == event.getClickCount())
          {
              index = mLinkBean.locationToIndex(event.getPoint());
              url = mLinkBean.getModel().getElementAt(index).toString();
              setURL(url);
          }
      }
  
      /**
       * Invoked when the mouse enters a component.
       */
      public void mouseEntered(java.awt.event.MouseEvent event)
      {
      }
  
      /**
       * Invoked when the mouse exits a component.
       */
      public void mouseExited(java.awt.event.MouseEvent event)
      {
      }
  
      /**
       * Invoked when a mouse button has been pressed on a component.
       */
      public void mousePressed(java.awt.event.MouseEvent event)
      {
      }
  
      /**
       * Invoked when a mouse button has been released on a component.
       */
      public void mouseReleased(java.awt.event.MouseEvent event)
      {
      }
  
      //
      // API control
      //
      public void setURL(String url)
      {
          mTextField.setText(url);
          mCrumb++;
          if (mTrail.size() <= mCrumb)
              mTrail.addElement(url);
          else
              mTrail.setElementAt(url, mCrumb);
          mLinkBean.setURL(url);
  
          // update navigation menu
          mBack.setEnabled(mCrumb > 0);
          mForward.setEnabled(mCrumb + 1 < mTrail.size());
      }
  
      /** This method is called from within the constructor to
       * initialize the form.
       * WARNING: Do NOT modify this code. The content of this method is
       * always regenerated by the Form Editor.
       */
      private void initComponents() //GEN-BEGIN:initComponents
      {
          javax.swing.JMenuBar menubar;
          javax.swing.JScrollPane pane1;
          javax.swing.JScrollPane pane2;
          javax.swing.JMenu go;
          javax.swing.JMenu options;
          javax.swing.JPanel panel;
  
          menubar = new javax.swing.JMenuBar();
          setJMenuBar(menubar);
          go = new javax.swing.JMenu();
          mBack = new javax.swing.JMenuItem();
          mForward = new javax.swing.JMenuItem();
          options = new javax.swing.JMenu();
          mLinks = new javax.swing.JCheckBoxMenuItem();
          mCollapse = new javax.swing.JCheckBoxMenuItem();
          mNobreak = new javax.swing.JCheckBoxMenuItem();
          panel = new javax.swing.JPanel();
          mSplitPane = new javax.swing.JSplitPane();
          pane1 = new javax.swing.JScrollPane();
          mLinkBean = new org.htmlparser.beans.HTMLLinkBean();
          pane2 = new javax.swing.JScrollPane();
          mStringBean = new org.htmlparser.beans.HTMLTextBean();
          mTextField = new javax.swing.JTextField();
  
          go.setMnemonic('G');
          go.setText("Go");
          go.setToolTipText("crude URL navigation");
          mBack.setMnemonic('B');
          mBack.setText("Back");
          mBack.setToolTipText("back one URL");
          mBack.setName("Back");
          mBack.addActionListener(this);
          go.add(mBack);
  
          mForward.setMnemonic('F');
          mForward.setText("Forward");
          mForward.setToolTipText("forward one URL");
          mForward.setName("Forward");
          mForward.addActionListener(this);
          go.add(mForward);
  
          menubar.add(go);
  
          options.setMnemonic('O');
          options.setText("Options");
          options.setToolTipText("Bean settings");
          mLinks.setMnemonic('L');
          mLinks.setText("Links");
          mLinks.setToolTipText("show/hide links in text");
          mLinks.setName("Links");
          mLinks.addActionListener(this);
          options.add(mLinks);
  
          mCollapse.setMnemonic('C');
          mCollapse.setText("Collapse");
          mCollapse.setToolTipText("collapse/retain whitespace sequences");
          mCollapse.setName("Collapse");
          mCollapse.addActionListener(this);
          options.add(mCollapse);
  
          mNobreak.setMnemonic('N');
          mNobreak.setText("Non-breaking Spaces");
          mNobreak.setToolTipText("replace/retain non-breaking spaces");
          mNobreak.setName("Nobreak");
          mNobreak.addActionListener(this);
          options.add(mNobreak);
  
          menubar.add(options);
  
          setTitle("BeanyBaby");
          addWindowListener(new java.awt.event.WindowAdapter()
          {
              public void windowClosing(java.awt.event.WindowEvent evt)
              {
                  exitForm(evt);
              }
          });
  
          panel.setLayout(new java.awt.BorderLayout());
  
          pane1.setViewportView(mLinkBean);
  
          mSplitPane.setLeftComponent(pane1);
  
          pane2.setViewportView(mStringBean);
  
          mSplitPane.setRightComponent(pane2);
  
          panel.add(mSplitPane, java.awt.BorderLayout.CENTER);
  
          mTextField.setToolTipText("Enter the URL to view");
          panel.add(mTextField, java.awt.BorderLayout.SOUTH);
  
          getContentPane().add(panel, java.awt.BorderLayout.CENTER);
  
          pack();
          java.awt.Dimension screenSize =
              java.awt.Toolkit.getDefaultToolkit().getScreenSize();
          setSize(new java.awt.Dimension(640, 480));
          setLocation(
              (screenSize.width - 640) / 2,
              (screenSize.height - 480) / 2);
      } //GEN-END:initComponents
  
      /** Exit the Application */
      private void exitForm(java.awt.event.WindowEvent evt)
      {
          //GEN-FIRST:event_exitForm
          System.exit(0);
      } //GEN-LAST:event_exitForm
  
      // Variables declaration - do not modify//GEN-BEGIN:variables
      private org.htmlparser.beans.HTMLLinkBean mLinkBean;
      private javax.swing.JMenuItem mForward;
      private javax.swing.JMenuItem mBack;
      private javax.swing.JCheckBoxMenuItem mCollapse;
      private javax.swing.JTextField mTextField;
      private javax.swing.JSplitPane mSplitPane;
      private javax.swing.JCheckBoxMenuItem mLinks;
      private org.htmlparser.beans.HTMLTextBean mStringBean;
      private javax.swing.JCheckBoxMenuItem mNobreak;
      // End of variables declaration//GEN-END:variables
  
      /**
       * Unit test.
       */
      public static void main(String[] args)
      {
          BeanyBaby bb = new BeanyBaby();
          bb.show();
          bb.setURL("http://www.netbeans.org");
      }
  }
  
  
  
  1.1                  jakarta-jmeter/src/htmlparser/org/htmlparser/beans/HTMLLinkBean.java
  
  Index: HTMLLinkBean.java
  ===================================================================
  /*
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   * if any, must include the following acknowledgment:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowledgment may appear in the software itself,
   * if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   * "Apache JMeter" must not be used to endorse or promote products
   * derived from this software without prior written permission. For
   * written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   * "Apache JMeter", nor may "Apache" appear in their name, without
   * prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   * 
   */
  
  // The developers of JMeter and Apache are greatful to the developers
  // of HTMLParser for giving Apache Software Foundation a non-exclusive
  // license. The performance benefits of HTMLParser are clear and the
  // users of JMeter will benefit from the hard work the HTMLParser
  // team. For detailed information about HTMLParser, the project is
  // hosted on sourceforge at http://htmlparser.sourceforge.net/.
  //
  // HTMLParser was originally created by Somik Raha in 2000. Since then
  // a healthy community of users has formed and helped refine the
  // design so that it is able to tackle the difficult task of parsing
  // dirty HTML. Derrick Oswald is the current lead developer and was kind
  // enough to assist JMeter.
  
  package org.htmlparser.beans;
  
  import java.awt.Dimension;
  import java.awt.FontMetrics;
  import java.beans.PropertyChangeEvent;
  import java.beans.PropertyChangeListener;
  import java.io.Serializable;
  import java.net.URL;
  import java.net.URLConnection;
  
  import javax.swing.JList;
  
  /**
   * Display the links from a URL.
   * @author Derrick Oswald
   * Created on December 24, 2002, 3:49 PM
   */
  public class HTMLLinkBean
      extends JList
      implements Serializable, PropertyChangeListener
  {
      /**
       * The underlying bean that provides our htmlparser specific properties.
       */
      protected LinkBean mBean;
  
      /**
       * Creates a new HTMLTextBean.
       * This uses an underlying StringBean and displays the text.
       */
      public HTMLLinkBean()
      {
          getBean().addPropertyChangeListener(this);
      }
  
      /**
       * Return the underlying bean object.
       * Creates a new one if it hasn't been initialized yet.
       * @return The StringBean this bean uses to fetch text.
       */
      protected LinkBean getBean()
      {
          if (null == mBean)
              mBean = new LinkBean();
  
          return (mBean);
      }
  
      /**
       * Return the minimum dimension for this visible bean.
       */
      public Dimension getMinimumSize()
      {
          FontMetrics metrics;
          int width;
          int height;
  
          metrics = getFontMetrics(getFont());
          width = metrics.stringWidth("http://localhost");
          height =
              metrics.getLeading() + metrics.getHeight() + metrics.getDescent();
  
          return (new Dimension(width, height));
      }
  
      /**
       * Add a PropertyChangeListener to the listener list.
       * The listener is registered for all properties.
       * <p><em>Delegates to the underlying StringBean</em>
       * @param listener The PropertyChangeListener to be added.
       */
      public void addPropertyChangeListener(PropertyChangeListener listener)
      {
          super.addPropertyChangeListener(listener);
          getBean().addPropertyChangeListener(listener);
      }
  
      /**
       * Remove a PropertyChangeListener from the listener list.
       * This removes a PropertyChangeListener that was registered for all properties.
       * <p><em>Delegates to the underlying StringBean</em>
       * @param the PropertyChangeListener to be removed.
       */
      public void removePropertyChangeListener(PropertyChangeListener listener)
      {
          super.addPropertyChangeListener(listener);
          getBean().removePropertyChangeListener(listener);
      }
  
      //
      // Properties
      //
  
      /**
       * Getter for property links.
       * <p><em>Delegates to the underlying StringBean</em>
       * @return Value of property links.
       */
      public URL[] getLinks()
      {
          return (getBean().getLinks());
      }
  
      /**
       * Getter for property URL.
       * <p><em>Delegates to the underlying StringBean</em>
       * @return Value of property URL.
       */
      public String getURL()
      {
          return (getBean().getURL());
      }
  
      /**
       * Setter for property URL.
       * <p><em>Delegates to the underlying StringBean</em>
       * @param url New value of property URL.
       */
      public void setURL(String url)
      {
          getBean().setURL(url);
      }
  
      /**
       * Getter for property Connection.
       * @return Value of property Connection.
       */
      public URLConnection getConnection()
      {
          return (getBean().getConnection());
      }
  
      /**
       * Setter for property Connection.
       * @param url New value of property Connection.
       */
      public void setConnection(URLConnection connection)
      {
          getBean().setConnection(connection);
      }
  
      //
      // PropertyChangeListener inteface
      //
  
      /**
       * Responds to changes in the underlying bean's properties.
       * @param event The event triggering this listener method call.
       */
      public void propertyChange(PropertyChangeEvent event)
      {
          if (event.getPropertyName().equals(LinkBean.PROP_LINKS_PROPERTY))
          {
              setListData(getBean().getLinks());
          }
      }
  }
  
  
  
  
  
  
  1.1                  jakarta-jmeter/src/htmlparser/org/htmlparser/beans/HTMLTextBean.java
  
  Index: HTMLTextBean.java
  ===================================================================
  /*
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   * if any, must include the following acknowledgment:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowledgment may appear in the software itself,
   * if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   * "Apache JMeter" must not be used to endorse or promote products
   * derived from this software without prior written permission. For
   * written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   * "Apache JMeter", nor may "Apache" appear in their name, without
   * prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   * 
   */
  
  // The developers of JMeter and Apache are greatful to the developers
  // of HTMLParser for giving Apache Software Foundation a non-exclusive
  // license. The performance benefits of HTMLParser are clear and the
  // users of JMeter will benefit from the hard work the HTMLParser
  // team. For detailed information about HTMLParser, the project is
  // hosted on sourceforge at http://htmlparser.sourceforge.net/.
  //
  // HTMLParser was originally created by Somik Raha in 2000. Since then
  // a healthy community of users has formed and helped refine the
  // design so that it is able to tackle the difficult task of parsing
  // dirty HTML. Derrick Oswald is the current lead developer and was kind
  // enough to assist JMeter.
  
  package org.htmlparser.beans;
  
  import java.awt.Dimension;
  import java.awt.FontMetrics;
  import java.beans.PropertyChangeEvent;
  import java.beans.PropertyChangeListener;
  import java.io.Serializable;
  import java.net.URLConnection;
  
  import javax.swing.JTextArea;
  
  /**
   * Display the textual URL contents.
   * @author Derrick Oswald
   * Created on December 24, 2002, 3:49 PM
   */
  public class HTMLTextBean
      extends JTextArea
      implements Serializable, PropertyChangeListener
  {
      /**
       * The underlying bean that provides our htmlparser specific properties.
       */
      protected StringBean mBean;
  
      /**
       * Creates a new HTMLTextBean.
       * This uses an underlying StringBean and displays the text.
       */
      public HTMLTextBean()
      {
          getBean().addPropertyChangeListener(this);
      }
  
      /**
       * Return the minimum dimension for this visible bean.
       */
      public Dimension getMinimumSize()
      {
          FontMetrics metrics;
          int width;
          int height;
  
          metrics = getFontMetrics(getFont());
          width = metrics.stringWidth("Hello World");
          height =
              metrics.getLeading() + metrics.getHeight() + metrics.getDescent();
  
          return (new Dimension(width, height));
      }
  
      /**
       * Add a PropertyChangeListener to the listener list.
       * The listener is registered for all properties.
       * <p><em>Delegates to the underlying StringBean</em>
       * @param listener The PropertyChangeListener to be added.
       */
      public void addPropertyChangeListener(PropertyChangeListener listener)
      {
          super.addPropertyChangeListener(listener);
          getBean().addPropertyChangeListener(listener);
      }
  
      /**
       * Remove a PropertyChangeListener from the listener list.
       * This removes a PropertyChangeListener that was registered for all properties.
       * <p><em>Delegates to the underlying StringBean</em>
       * @param the PropertyChangeListener to be removed.
       */
      public void removePropertyChangeListener(PropertyChangeListener listener)
      {
          super.addPropertyChangeListener(listener);
          getBean().removePropertyChangeListener(listener);
      }
  
      //
      // Properties
      //
  
      /**
       * Return the underlying bean object.
       * Creates a new one if it hasn't been initialized yet.
       * @return The StringBean this bean uses to fetch text.
       */
      public StringBean getBean()
      {
          if (null == mBean)
              mBean = new StringBean();
  
          return (mBean);
      }
  
      /**
       * Getter for property strings.
       * <p><em>Delegates to the underlying StringBean</em>
       * @return Value of property strings.
       */
      public String getStrings()
      {
          return (getBean().getStrings());
      }
  
      /**
       * Getter for property links.
       * <p><em>Delegates to the underlying StringBean</em>
       * @return Value of property links.
       */
      public boolean getLinks()
      {
          return (getBean().getLinks());
      }
  
      /**
       * Setter for property links.
       * <p><em>Delegates to the underlying StringBean</em>
       * @param links New value of property links.
       */
      public void setLinks(boolean links)
      {
          getBean().setLinks(links);
      }
  
      /**
       * Getter for property URL.
       * <p><em>Delegates to the underlying StringBean</em>
       * @return Value of property URL.
       */
      public String getURL()
      {
          return (getBean().getURL());
      }
  
      /**
       * Setter for property URL.
       * <p><em>Delegates to the underlying StringBean</em>
       * @param url New value of property URL.
       */
      public void setURL(String url)
      {
          getBean().setURL(url);
      }
  
      /**
       * Get the current 'replace non breaking spaces' state.
       * @return The <code>true</code> if non-breaking spaces (character '\u00a0',
       * numeric character reference &160; or character entity reference &nbsp;)
       * are to be replaced with normal spaces (character '\u0020').
       */
      public boolean getReplaceNonBreakingSpaces()
      {
          return (getBean().getReplaceNonBreakingSpaces());
      }
  
      /**
       * Set the 'replace non breaking spaces' state.
       * @param replace_space <code>true</code> if non-breaking spaces (character '\u00a0',
       * numeric character reference &160; or character entity reference &nbsp;)
       * are to be replaced with normal spaces (character '\u0020').
       */
      public void setReplaceNonBreakingSpaces(boolean replace_space)
      {
          getBean().setReplaceNonBreakingSpaces(replace_space);
      }
  
      /**
       * Get the current 'collapse whitespace' state.
       * If set to <code>true</code> this emulates the operation of browsers
       * in interpretting text where auser agents should collapse input white
       * space sequences when producing output inter-word space.
       * See HTML specification section 9.1 White space
       * http://www.w3.org/TR/html4/struct/text.html#h-9.1
       * @return <code>true</code> if sequences of whitespace (space '\u0020',
       * tab '\u0009', form feed '\u000C', zero-width space '\u200B',
       * carriage-return '\r' and newline '\n') are to be replaced with a single
       * space.
       */
      public boolean getCollapse()
      {
          return (getBean().getCollapse());
      }
  
      /**
       * Set the current 'collapse whitespace' state.
       * @param collapse_whitespace If <code>true</code>, sequences of whitespace
       * will be reduced to a single space.
       */
      public void setCollapse(boolean collapse_whitespace)
      {
          getBean().setCollapse(collapse_whitespace);
      }
  
      /**
       * Getter for property Connection.
       * @return Value of property Connection.
       */
      public URLConnection getConnection()
      {
          return (getBean().getConnection());
      }
  
      /**
       * Setter for property Connection.
       * @param url New value of property Connection.
       */
      public void setConnection(URLConnection connection)
      {
          getBean().setConnection(connection);
      }
  
      //
      // PropertyChangeListener inteface
      //
  
      /**
       * Responds to changes in the underlying bean's properties.
       * @param event The event triggering this listener method call.
       */
      public void propertyChange(PropertyChangeEvent event)
      {
          if (event.getPropertyName().equals(StringBean.PROP_STRINGS_PROPERTY))
          {
              setText(getBean().getStrings());
              setCaretPosition(0);
          }
      }
  }
  
  
  
  1.1                  jakarta-jmeter/src/htmlparser/org/htmlparser/beans/LinkBean.java
  
  Index: LinkBean.java
  ===================================================================
  /*
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   * if any, must include the following acknowledgment:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowledgment may appear in the software itself,
   * if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   * "Apache JMeter" must not be used to endorse or promote products
   * derived from this software without prior written permission. For
   * written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   * "Apache JMeter", nor may "Apache" appear in their name, without
   * prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   * 
   */
  
  // The developers of JMeter and Apache are greatful to the developers
  // of HTMLParser for giving Apache Software Foundation a non-exclusive
  // license. The performance benefits of HTMLParser are clear and the
  // users of JMeter will benefit from the hard work the HTMLParser
  // team. For detailed information about HTMLParser, the project is
  // hosted on sourceforge at http://htmlparser.sourceforge.net/.
  //
  // HTMLParser was originally created by Somik Raha in 2000. Since then
  // a healthy community of users has formed and helped refine the
  // design so that it is able to tackle the difficult task of parsing
  // dirty HTML. Derrick Oswald is the current lead developer and was kind
  // enough to assist JMeter.
  
  package org.htmlparser.beans;
  
  import java.beans.PropertyChangeListener;
  import java.beans.PropertyChangeSupport;
  import java.io.Serializable;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.net.URLConnection;
  import java.util.Vector;
  
  import org.htmlparser.Node;
  import org.htmlparser.Parser;
  import org.htmlparser.tags.LinkTag;
  import org.htmlparser.util.ParserException;
  import org.htmlparser.visitors.ObjectFindingVisitor;
  
  /**
   * Extract strings from a URL.
   * @author Derrick Oswald
   * Created on December 23, 2002, 5:01 PM
   */
  public class LinkBean extends Object implements Serializable
  {
      /**
       * Property name in event where the URL contents changes.
       */
      public static final String PROP_LINKS_PROPERTY = "Links";
  
      /**
       * Property name in event where the URL changes.
       */
      public static final String PROP_URL_PROPERTY = "URL";
  
      /**
       * Bound property support.
       */
      protected PropertyChangeSupport mPropertySupport;
  
      /**
       * The strings extracted from the URL.
       */
      protected URL[] mLinks;
  
      /**
       * The parser used to extract strings.
       */
      protected Parser mParser;
  
      /** Creates new StringBean */
      public LinkBean()
      {
          mPropertySupport = new PropertyChangeSupport(this);
          mLinks = null;
          mParser = new Parser();
      }
  
      //
      // internals
      //
  
      protected URL[] extractLinks(String url) throws ParserException
      {
          Parser parser;
          Vector vector;
          Node node;
          LinkTag link;
          URL[] ret;
  
          parser = new Parser(url);
          parser.registerScanners();
          ObjectFindingVisitor visitor = new ObjectFindingVisitor(LinkTag.class);
          parser.visitAllNodesWith(visitor);
          Node[] nodes = visitor.getTags();
          vector = new Vector();
          for (int i = 0; i < nodes.length; i++)
              try
              {
                  link = (LinkTag) nodes[i];
                  vector.add(new URL(link.getLink()));
              }
              catch (MalformedURLException murle)
              {
                  //vector.remove (i);
                  //i--;
              }
          ret = new URL[vector.size()];
          vector.copyInto(ret);
  
          return (ret);
      }
  
      /**
       * Determine if two arrays of URL's are the same.
       * @param array1 One array of URL's
       * @param array2 Another array of URL's
       * @return <code>true</code> if the URL's match in number and value,
       * <code>false</code> otherwise.
       */
      protected boolean equivalent(URL[] array1, URL[] array2)
      {
          boolean ret;
  
          ret = false;
          if ((null == array1) && (null == array2))
              ret = true;
          else if ((null != array1) && (null != array2))
              if (array1.length == array2.length)
              {
                  ret = true;
                  for (int i = 0; i < array1.length && ret; i++)
                      if (!(array1[i] == array2[i]))
                          ret = false;
              }
  
          return (ret);
      }
  
      //
      // Property change support.
      //
  
      /**
       * Add a PropertyChangeListener to the listener list.
       * The listener is registered for all properties.
       * @param listener The PropertyChangeListener to be added.
       */
      public void addPropertyChangeListener(PropertyChangeListener listener)
      {
          mPropertySupport.addPropertyChangeListener(listener);
      }
  
      /**
       * Remove a PropertyChangeListener from the listener list.
       * This removes a PropertyChangeListener that was registered for all properties.
       * @param the PropertyChangeListener to be removed.
       */
      public void removePropertyChangeListener(PropertyChangeListener listener)
      {
          mPropertySupport.removePropertyChangeListener(listener);
      }
  
      //
      // Properties
      //
  
      /**
       * Refetch the URL contents.
       */
      private void setLinks()
      {
          String url;
          URL[] urls;
          URL[] oldValue;
  
          url = getURL();
          if (null != url)
              try
              {
                  urls = extractLinks(getURL());
                  if (!equivalent(mLinks, urls))
                  {
                      oldValue = mLinks;
                      mLinks = urls;
                      mPropertySupport.firePropertyChange(
                          PROP_LINKS_PROPERTY,
                          oldValue,
                          mLinks);
                  }
              }
              catch (ParserException hpe)
              {
                  mLinks = null;
              }
      }
  
      /**
       * Getter for property links.
       * @return Value of property links.
       */
      public URL[] getLinks()
      {
          if (null == mLinks)
              try
              {
                  mLinks = extractLinks(getURL());
                  mPropertySupport.firePropertyChange(
                      PROP_LINKS_PROPERTY,
                      null,
                      mLinks);
              }
              catch (ParserException hpe)
              {
                  mLinks = null;
              }
  
          return (mLinks);
      }
  
      /**
       * Getter for property URL.
       * @return Value of property URL.
       */
      public String getURL()
      {
          return (mParser.getURL());
      }
  
      /**
       * Setter for property URL.
       * @param url New value of property URL.
       */
      public void setURL(String url)
      {
          String old;
  
          old = getURL();
          if (((null == old) && (null != url))
              || ((null != old) && !old.equals(url)))
          {
              try
              {
                  mParser.setURL(url);
                  mPropertySupport.firePropertyChange(
                      PROP_URL_PROPERTY,
                      old,
                      getURL());
                  setLinks();
              }
              catch (ParserException hpe)
              {
                  // failed... now what
              }
          }
      }
  
      /**
       * Getter for property Connection.
       * @return Value of property Connection.
       */
      public URLConnection getConnection()
      {
          return (mParser.getConnection());
      }
  
      /**
       * Setter for property Connection.
       * @param url New value of property Connection.
       */
      public void setConnection(URLConnection connection)
      {
          try
          {
              mParser.setConnection(connection);
              setLinks();
          }
          catch (ParserException hpe)
          {
              // failed... now what
          }
      }
  }
  
  
  
  1.1                  jakarta-jmeter/src/htmlparser/org/htmlparser/beans/StringBean.java
  
  Index: StringBean.java
  ===================================================================
  /*
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   * if any, must include the following acknowledgment:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowledgment may appear in the software itself,
   * if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   * "Apache JMeter" must not be used to endorse or promote products
   * derived from this software without prior written permission. For
   * written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   * "Apache JMeter", nor may "Apache" appear in their name, without
   * prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   * 
   */
  
  // The developers of JMeter and Apache are greatful to the developers
  // of HTMLParser for giving Apache Software Foundation a non-exclusive
  // license. The performance benefits of HTMLParser are clear and the
  // users of JMeter will benefit from the hard work the HTMLParser
  // team. For detailed information about HTMLParser, the project is
  // hosted on sourceforge at http://htmlparser.sourceforge.net/.
  //
  // HTMLParser was originally created by Somik Raha in 2000. Since then
  // a healthy community of users has formed and helped refine the
  // design so that it is able to tackle the difficult task of parsing
  // dirty HTML. Derrick Oswald is the current lead developer and was kind
  // enough to assist JMeter.
  
  package org.htmlparser.beans;
  
  import java.beans.PropertyChangeListener;
  import java.beans.PropertyChangeSupport;
  import java.io.Serializable;
  import java.net.URLConnection;
  
  import org.htmlparser.Parser;
  import org.htmlparser.StringNode;
  import org.htmlparser.tags.EndTag;
  import org.htmlparser.tags.LinkTag;
  import org.htmlparser.tags.Tag;
  import org.htmlparser.util.ParserException;
  import org.htmlparser.util.Translate;
  import org.htmlparser.visitors.NodeVisitor;
  
  /**
   * Extract strings from a URL.
   * <p>Text within &lt;SCRIPT&gt;&lt;/SCRIPT&gt; tags is removed.</p>
   * <p>The text within &lt;PRE&gt;&lt;/PRE&gt; tags is not altered.</p>
   * <p>The property <code>Strings</code>, which is the output property is null
   * until a URL is set. So a typical usage is:</p>
   * <pre>
   *     StringBean sb = new StringBean ();
   *     sb.setLinks (false);
   *     sb.setReplaceNonBreakingSpaces (true);
   *     sb.setCollapse (true);
   *     sb.setURL ("http://www.netbeans.org"); // the HTTP is performed here
   *     String s = sb.getStrings ();
   * </pre>
   * @author Derrick Oswald
   * Created on December 23, 2002, 5:01 PM
   */
  public class StringBean extends NodeVisitor implements Serializable
  {
      /**
       * Property name in event where the URL contents changes.
       */
      public static final String PROP_STRINGS_PROPERTY = "Strings";
  
      /**
       * Property name in event where the 'embed links' state changes.
       */
      public static final String PROP_LINKS_PROPERTY = "Links";
  
      /**
       * Property name in event where the URL changes.
       */
      public static final String PROP_URL_PROPERTY = "URL";
  
      /**
       * Property name in event where the 'replace non-breaking spaces' state changes.
       */
      public static final String PROP_REPLACE_SPACE_PROPERTY = "ReplaceSpace";
  
      /**
       * Property name in event where the 'collapse whitespace' state changes.
       */
      public static final String PROP_COLLAPSE_PROPERTY = "Collapse";
  
      /**
       * Property name in event where the connection changes.
       */
      public static final String PROP_CONNECTION_PROPERTY = "Connection";
  
      /**
       * A newline.
       */
      private static final String newline = System.getProperty("line.separator");
  
      /**
       * The length of the newline.
       */
      private static final int newline_size = newline.length();
  
      /**
       * Bound property support.
       */
      protected PropertyChangeSupport mPropertySupport;
  
      /**
       * The parser used to extract strings.
       */
      protected Parser mParser;
  
      /**
       * The strings extracted from the URL.
       */
      protected String mStrings;
  
      /**
       * If <code>true</code> the link URLs are embedded in the text output.
       */
      protected boolean mLinks;
  
      /**
       * If <code>true</code> regular space characters are substituted for
       * non-breaking spaces in the text output.
       */
      protected boolean mReplaceSpace;
  
      /**
       * If <code>true</code> sequences of whitespace characters are replaced with a
       * single space character.
       */
      protected boolean mCollapse;
  
      /**
       * The buffer text is stored in while traversing the HTML.
       */
      protected StringBuffer mBuffer;
  
      /**
       * Set <code>true</code> when traversing a SCRIPT tag.
       */
      protected boolean mIsScript;
  
      /**
       * Set <code>true</code> when traversing a PRE tag.
       */
      protected boolean mIsPre;
  
      /** 
       * Create a StringBean object.
       * Default property values are set to 'do the right thing':
       * <p><code>Links</code> is set <code>false</code> so text appears like a
       * browser would display it, albeit without the colour or underline clues
       * normally associated with a link.</p>
       * <p><code>ReplaceNonBreakingSpaces</code> is set <code>true</code>, so
       * that printing the text works, but the extra information regarding these
       * formatting marks is available if you set it false.</p>
       * <p><code>Collapse</code> is set <code>true</code>, so text appears
       * compact like a browser would display it.</p>
       */
      public StringBean()
      {
          super(true, false);
          mPropertySupport = new PropertyChangeSupport(this);
          mParser = new Parser();
          mStrings = null;
          mLinks = false;
          mReplaceSpace = true;
          mCollapse = true;
      }
  
      //
      // internals
      //
  
      /**
       * Appends a newline to the buffer if there isn't one there already.
       * Except if the buffer is empty.
       * @param buffer The buffer to append to.
       */
      protected void carriage_return()
      {
          int length;
  
          length = mBuffer.length();
          if ((0 != length)
              // why bother appending newlines to the beginning of a buffer
              && ((newline_size <= length) // not enough chars to hold a newline
                  && (!mBuffer
                      .substring(length - newline_size, length)
                      .equals(newline))))
              mBuffer.append(newline);
      }
  
      /**
       * Add the given text collapsing whitespace.
       * Use a little finite state machine:
       * <pre>
       * state 0: whitepace was last emitted character
       * state 1: in whitespace
       * state 2: in word
       * A whitespace character moves us to state 1 and any other character
       * moves us to state 2, except that state 0 stays in state 0 until
       * a non-whitespace and going from whitespace to word we emit a space
       * before the character:
       *    input:     whitespace   other-character
       * state\next
       *    0               0             2
       *    1               1        space then 2
       *    2               1             2
       * </pre>
       * @param buffer The buffer to append to.
       * @param string The string to append.
       */
      protected void collapse(StringBuffer buffer, String string)
      {
          int chars;
          int length;
          int state;
          char character;
  
          chars = string.length();
          if (0 != chars)
          {
              length = buffer.length();
              state =
                  ((0 == length)
                      || (buffer.charAt(length - 1) == ' ')
                      || ((newline_size <= length)
                          && buffer.substring(length - newline_size, length).equals(
                              newline)))
                      ? 0
                      : 1;
              for (int i = 0; i < chars; i++)
              {
                  character = string.charAt(i);
                  switch (character)
                  {
                      // see HTML specification section 9.1 White space
                      // http://www.w3.org/TR/html4/struct/text.html#h-9.1
                      case '\u0020' :
                      case '\u0009' :
                      case '\u000C' :
                      case '\u200B' :
                      case '\r' :
                      case '\n' :
                          if (0 != state)
                              state = 1;
                          break;
                      default :
                          if (1 == state)
                              buffer.append(' ');
                          state = 2;
                          buffer.append(character);
                  }
              }
          }
      }
  
      /**
       * Extract the text from a page.
       * @return The textual contents of the page.
       */
      protected String extractStrings() throws ParserException
      {
          String ret;
  
          mParser.flushScanners();
          mParser.registerScanners();
          mIsPre = false;
          mIsScript = false;
          mBuffer = new StringBuffer(4096);
          mParser.visitAllNodesWith(this);
          ret = mBuffer.toString();
          mBuffer = null;
  
          return (ret);
      }
  
      /**
       * Assign the <code>Strings</code> property, firing the property change.
       * @param strings The new value of the <code>Strings</code> property.
       */
      protected void updateStrings(String strings)
      {
          String oldValue;
  
          if ((null == mStrings) || !mStrings.equals(strings))
          {
              oldValue = mStrings;
              mStrings = strings;
              mPropertySupport.firePropertyChange(
                  PROP_STRINGS_PROPERTY,
                  oldValue,
                  strings);
          }
      }
  
      /**
       * Fetch the URL contents.
       * Only do work if there is a valid parser with it's URL set.
       */
      protected void setStrings()
      {
          if (null != getURL())
              try
              {
                  mParser.flushScanners();
                  mParser.registerScanners();
                  mIsPre = false;
                  mIsScript = false;
                  try
                  {
                      mBuffer = new StringBuffer(4096);
                      mParser.visitAllNodesWith(this);
                      updateStrings(mBuffer.toString());
                  }
                  finally
                  {
                      mBuffer = null;
                  }
              }
              catch (ParserException pe)
              {
                  updateStrings(pe.toString());
              }
      }
  
      /**
       * Refetch the URL contents.
       * Only need to worry if there is already a valid parser and it's
       * been spent fetching the string contents.
       */
      private void resetStrings()
      {
          if (null != mStrings)
              try
              {
                  mParser.setURL(getURL());
                  setStrings();
              }
              catch (ParserException pe)
              {
                  updateStrings(pe.toString());
              }
      }
  
      //
      // Property change support.
      //
  
      /**
       * Add a PropertyChangeListener to the listener list.
       * The listener is registered for all properties.
       * @param listener The PropertyChangeListener to be added.
       */
      public void addPropertyChangeListener(PropertyChangeListener listener)
      {
          mPropertySupport.addPropertyChangeListener(listener);
      }
  
      /**
       * Remove a PropertyChangeListener from the listener list.
       * This removes a PropertyChangeListener that was registered for all properties.
       * @param the PropertyChangeListener to be removed.
       */
      public void removePropertyChangeListener(PropertyChangeListener listener)
      {
          mPropertySupport.removePropertyChangeListener(listener);
      }
  
      //
      // Properties
      //
  
      /**
       * Return the textual contents of the URL.
       * This is the primary output of the bean.
       * @return The user visible (what would be seen in a browser) text from the URL.
       */
      public String getStrings()
      {
          if (null == mStrings)
              setStrings();
  
          return (mStrings);
      }
  
      /**
       * Get the current 'include links' state.
       * @return <code>true</code> if link text is included in the text extracted
       * from the URL, <code>false</code> otherwise.
       */
      public boolean getLinks()
      {
          return (mLinks);
      }
  
      /**
       * Set the 'include links' state.
       * If the setting is changed after the URL has been set, the text from the
       * URL will be reacquired, which is possibly expensive.
       * @param links Use <code>true</code> if link text is to be included in the
       * text extracted from the URL, <code>false</code> otherwise.
       */
      public void setLinks(boolean links)
      {
          boolean oldValue = mLinks;
          if (oldValue != links)
          {
              mLinks = links;
              mPropertySupport.firePropertyChange(
                  PROP_LINKS_PROPERTY,
                  oldValue,
                  links);
              resetStrings();
          }
      }
  
      /**
       * Get the current URL.
       * @return The URL from which text has been extracted, or <code>null</code>
       * if this property has not been set yet.
       */
      public String getURL()
      {
          return ((null != mParser) ? mParser.getURL() : null);
      }
  
      /**
       * Set the URL to extract strings from.
       * The text from the URL will be fetched, which may be expensive, so this
       * property should be set last.
       * @param url The URL that text should be fetched from.
       */
      public void setURL(String url)
      {
          String old;
          URLConnection conn;
  
          old = getURL();
          conn = getConnection();
          if (((null == old) && (null != url))
              || ((null != old) && !old.equals(url)))
          {
              try
              {
                  if (null == mParser)
                      mParser = new Parser(url);
                  else
                      mParser.setURL(url);
                  mPropertySupport.firePropertyChange(
                      PROP_URL_PROPERTY,
                      old,
                      getURL());
                  mPropertySupport.firePropertyChange(
                      PROP_CONNECTION_PROPERTY,
                      conn,
                      mParser.getConnection());
                  setStrings();
              }
              catch (ParserException pe)
              {
                  updateStrings(pe.toString());
              }
          }
      }
  
      /**
       * Get the current 'replace non breaking spaces' state.
       * @return <code>true</code> if non-breaking spaces (character '&#92;u00a0',
       * numeric character reference &amp;#160; or character entity reference &amp;nbsp;)
       * are to be replaced with normal spaces (character '&#92;u0020').
       */
      public boolean getReplaceNonBreakingSpaces()
      {
          return (mReplaceSpace);
      }
  
      /**
       * Set the 'replace non breaking spaces' state.
       * If the setting is changed after the URL has been set, the text from the
       * URL will be reacquired, which is possibly expensive.
       * @param replace_space <code>true</code> if non-breaking spaces (character '&#92;u00a0',
       * numeric character reference &amp;#160; or character entity reference &amp;nbsp;)
       * are to be replaced with normal spaces (character '&#92;u0020').
       */
      public void setReplaceNonBreakingSpaces(boolean replace_space)
      {
          boolean oldValue = mReplaceSpace;
          if (oldValue != replace_space)
          {
              mReplaceSpace = replace_space;
              mPropertySupport.firePropertyChange(
                  PROP_REPLACE_SPACE_PROPERTY,
                  oldValue,
                  replace_space);
              resetStrings();
          }
      }
  
      /**
       * Get the current 'collapse whitespace' state.
       * If set to <code>true</code> this emulates the operation of browsers
       * in interpretting text where <quote>user agents should collapse input white
       * space sequences when producing output inter-word space</quote>.
       * See HTML specification section 9.1 White space
       * <a href="http://www.w3.org/TR/html4/struct/text.html#h-9.1">
       * http://www.w3.org/TR/html4/struct/text.html#h-9.1</a>.
       * @return <code>true</code> if sequences of whitespace (space '&#92;u0020',
       * tab '&#92;u0009', form feed '&#92;u000C', zero-width space '&#92;u200B',
       * carriage-return '\r' and newline '\n') are to be replaced with a single
       * space.
       */
      public boolean getCollapse()
      {
          return (mCollapse);
      }
  
      /**
       * Set the current 'collapse whitespace' state.
       * If the setting is changed after the URL has been set, the text from the
       * URL will be reacquired, which is possibly expensive.
       * @param collapse_whitespace If <code>true</code>, sequences of whitespace
       * will be reduced to a single space.
       */
      public void setCollapse(boolean collapse_whitespace)
      {
          boolean oldValue = mCollapse;
          if (oldValue != collapse_whitespace)
          {
              mCollapse = collapse_whitespace;
              mPropertySupport.firePropertyChange(
                  PROP_COLLAPSE_PROPERTY,
                  oldValue,
                  collapse_whitespace);
              resetStrings();
          }
      }
  
      /**
       * Get the current connection.
       * @return The connection that the parser has or <code>null</code> if it
       * hasn't been set or the parser hasn't been constructed yet.
       */
      public URLConnection getConnection()
      {
          return ((null != mParser) ? mParser.getConnection() : null);
      }
  
      /**
       * Set the parser's connection.
       * The text from the URL will be fetched, which may be expensive, so this
       * property should be set last.
       * @param connection New value of property Connection.
       */
      public void setConnection(URLConnection connection)
      {
          String url;
          URLConnection conn;
          boolean change;
  
          url = getURL();
          conn = getConnection();
          if (((null == conn) && (null != connection))
              || ((null != conn) && !conn.equals(connection)))
          {
              try
              {
                  if (null == mParser)
                      mParser = new Parser(connection);
                  else
                      mParser.setConnection(connection);
                  mPropertySupport.firePropertyChange(
                      PROP_URL_PROPERTY,
                      url,
                      getURL());
                  mPropertySupport.firePropertyChange(
                      PROP_CONNECTION_PROPERTY,
                      conn,
                      mParser.getConnection());
                  setStrings();
              }
              catch (ParserException pe)
              {
                  updateStrings(pe.toString());
              }
          }
      }
  
      //
      // NodeVisitor overrides
      //
  
      /**
       * Appends the link as text between angle brackets to the output.
       * @param link The link to process.
       */
      public void visitLinkTag(LinkTag link)
      {
          if (getLinks())
          {
              mBuffer.append("<");
              mBuffer.append(link.getLink());
              mBuffer.append(">");
          }
      }
  
      /**
       * Appends the text to the output.
       * @param string The text node.
       */
      public void visitStringNode(StringNode string)
      {
          if (!mIsScript)
          {
              String text = string.getText();
              if (!mIsPre)
              {
                  text = Translate.decode(text);
                  if (getReplaceNonBreakingSpaces())
                      text = text.replace('\u00a0', ' ');
                  if (getCollapse())
                      collapse(mBuffer, text);
                  else
                      mBuffer.append(text);
              }
              else
                  mBuffer.append(text);
          }
      }
  
      /**
       * Possibly resets the state of the PRE and SCRIPT flags.
       * @param end The end tag.
       */
      public void visitEndTag(EndTag end)
      {
          String name;
  
          name = end.getTagName();
          if (name.equalsIgnoreCase("PRE"))
              mIsPre = false;
          else if (name.equalsIgnoreCase("SCRIPT"))
              mIsScript = false;
      }
  
      /**
       * Appends a newline to the output if the tag breaks flow, and
       * possibly sets the state of the PRE and SCRIPT flags.
       */
      public void visitTag(Tag tag)
      {
          String name;
  
          name = tag.getTagName();
          if (name.equalsIgnoreCase("PRE"))
              mIsPre = true;
          else if (name.equalsIgnoreCase("SCRIPT"))
              mIsScript = true;
          if (tag.breaksFlow())
              carriage_return();
      }
  
      /**
       * Unit test.
       * @param args Pass arg[0] as the URL to process.
       */
      public static void main(String[] args)
      {
          if (0 >= args.length)
              System.out.println(
                  "Usage: java -classpath htmlparser.jar org.htmlparser.beans.StringBean <http://whatever_url>");
          else
          {
              StringBean sb = new StringBean();
              sb.setLinks(false);
              sb.setReplaceNonBreakingSpaces(true);
              sb.setCollapse(true);
              sb.setURL(args[0]);
              System.out.println(sb.getStrings());
          }
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: jmeter-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jmeter-dev-help@jakarta.apache.org