Changeset 1625 for trunk/gsdl


Ignore:
Timestamp:
2000-10-27T17:16:16+13:00 (24 years ago)
Author:
paynter
Message:

Much is cghanged. Phind is now about halfway to working with XML. It can
read expansions, but there's a bug in the document information, and summary
information is ignored.

Location:
trunk/gsdl/src/phind/client
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/gsdl/src/phind/client/Phind.java

    r1621 r1625  
    1 /*
    2 
    3 Phind.java
    4 
    5 Version 2.2.1
    6 Gordon Paynter ([email protected])
    7 
    8 
    9 This is the Phind 2 client.  It is a Java applet, you
    10 will need to embed it in a web page with code like the
    11 following, and at thew same time run a phind server
    12 to provide the phrase information.
     1/**********************************************************************
     2 *
     3 * Phind.java -- the Phind java applet
     4 *
     5 * Copyright 1997-2000 Gordon W. Paynter
     6 * Copyright 2000 The New Zealand Digital Library Project
     7 *
     8 * A component of the Greenstone digital library software
     9 * from the New Zealand Digital Library Project at the
     10 * University of Waikato, New Zealand.
     11 *
     12 * This program is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU General Public License as published by
     14 * the Free Software Foundation; either version 2 of the License, or
     15 * (at your option) any later version.
     16 *
     17 * This program is distributed in the hope that it will be useful,
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 * GNU General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU General Public License
     23 * along with this program; if not, write to the Free Software
     24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     25 *
     26 *********************************************************************/
     27
     28
     29/*********************************************************************
     30
     31This applet should be embedded in a web page.  For example:
     32
    1333
    1434<APPLET CODE="Phind.class" WIDTH=500 HEIGHT=600>
     35  <PARAM NAME=phindcgi    VALUE="http://www.nzdl.org/cgi-bin/phindcgi">
     36  <PARAM NAME=library     VALUE="http://www.nzdl.org/cgi-bin/library">
     37  <PARAM NAME=collection  VALUE="fao.org">
    1538  <PARAM NAME=orientation VALUE="vertical">
    16   <PARAM NAME=depth VALUE="2">
    17   <PARAM NAME=background VALUE="on">
    18   <PARAM NAME=fontsize VALUE="12">
    19   <PARAM NAME=collection VALUE="small">
    20   <PARAM NAME=server VALUE="dna.stanford.edu">
    21   <PARAM NAME=port VALUE="3000">
    22   <PARAM NAME=search_url VALUE="">
    23   The Phind java Applet
     39  <PARAM NAME=depth       VALUE="2">
     40  <PARAM NAME=fontsize    VALUE="12">
     41  <PARAM NAME=blocksize   VALUE="10">
     42  The Phind java applet.
    2443</APPLET>
    2544
    26 
    27 Classes:
    28 
    29 Phind is the main applet class, it also handles socket connections.
    30 ResultDisplay is a Panel that sits in the applet and displays
    31     things; displays are connected in a doubly-linked list.
    32 ResultBox holds the results of a query.  Result boxes are shown
    33     to the user through ResultDisplays.  Another doubly-linked list.
    34 ResultCanvas is what a ResultBox's data is drawn on, and does
    35     the painting in ResultCanvas windows.  Also handles clicks.
    36 ResultItem represents a single result object (a phrase or document).
    37 PhindTitle is a canvas used for drawing backgrops in empty Displays.
    38 
    39 
    40 Applet history:
    41 
    42 2.0 The first Applet, see Witten et al (1999) in JODL.
    43 2.1 Interaction with server changed to launch documents.
    44 2.2 Thesaurus-style layouts with window titles.
    45     This version created for the FAO people. 
    46 2.2.1 Dec 1, 1999. Ignore clicks that occur within 1 second to
    47                    prevent lag problems from the FAO.
    48 */
     45The applet comprises several classes:
     46
     471. Phind (this file) is the applet class, loaded by the browser.
     48   It also handles network connections.
     492. ResultDisplay is a Panel that sits in the applet and displays
     50   things; displays are connected in a doubly-linked list.
     513. ResultBox holds the results of a query.  Result boxes are shown
     52   to the user through ResultDisplays.  Another doubly-linked list.
     534. ResultCanvas is what a ResultBox's data is drawn on, and does
     54   the painting in ResultCanvas windows.  Also handles clicks.
     555. ResultItem represents a single result object (a phrase or document).
     566. PhindTitle is a canvas used for drawing backgrops in empty Displays.
     57
     58**********************************************************************/
    4959
    5060
     
    6474import java.awt.TextField;
    6575
     76import java.net.URL;
     77import java.io.DataInputStream;
     78
    6679import java.net.Socket;
    6780import java.net.InetAddress;
     
    7689
    7790public class Phind extends java.applet.Applet {
    78 
    79   // elements of the page
    80   Label titleLabel;
    81   TextField wordField;
    82   Choice libraryMenu, swlMenu, lfcMenu, stemMenu;
    83   Button searchButton;
    84 
    85   Button prevButton, nextButton;
    86 
    87   // Appearance parameters
    88   public boolean showImage;
    89   public boolean vertical;
    90   public int depth;
    91   public int fontSize;
    92   public Image backgroundImage;
    93   public Font plainFont, boldFont;
    94 
    95   // the downloaded data
    96   Panel resultPanel;
    97   PhindTitle title;
    98   ResultDisplay firstDisplay, lastDisplay;
    99 
    100   // the mode of operation
    101   int mode;
    102   final int initMode = 0;
    103   final int idleMode = 1;
    104   final int searchMode = 2;
    105 
    106   // what to search for
    107   int phraseBlockSize = 20;
    108   int stopwordLevel = 1;
    109   int lowFrequencyCutoff = 0;
    110   int stemming = 0;
    111   String collection;
    112 
    113   // where to search
    114   Socket connection;
    115   String server, port;
    116   String search_url;
    117 
    118   // The time at which the last query finished
    119   Date lastQueryEndTime;
    120   // This is stored to ensure a 1 second gap between
    121   // a query returning and a new one beginning.
    122   // It is needed because the FAO folks in Rome have
    123   // a huge lag, and frquently click several times
    124   // while they wait; these clicks are turned into
    125   // new queries, which they await again.
    126   // It is no elegant solution, but it seems like
    127   // the easiest, given that I don't know threads.
    128   // 1. The search button is easy to disable, and is
    129   // disabled when a socket connection is in progress.
    130   // 2. ResutCanvas widgets can'r be similarly disabled
    131   // because the browser hides or wipes them, which
    132   // looks very bad.
    133   // 3. I cannot just ignore clicks on canvasses because
    134   // the browser caches the clicks while the socket connection is
    135   // going on, and then sends them through afterwards, when the
    136   // canvas is accepting clicks again.
    137   // 4. Current sequence of events is to record the time
    138   // the last query ends, then whenever a click happens
    139   // make sure a second has past.  if you double-click the
    140   // the first query is sent, returns, end-tie is set, and
    141   // the second (and any others made during query time)
    142   // is *immediately* processed, but since 1 second
    143   // hasn't past it is ignored.
    144 
    145   // browser details
    146   String localHost;
     91   
     92    // elements of the page
     93    Label titleLabel;
     94    TextField wordField;
     95    Button searchButton, prevButton, nextButton;
     96
     97    // Appearance parameters
     98    public boolean vertical;
     99    public int depth;
     100    public int fontSize;
     101    public Font plainFont, boldFont;
     102
     103    // Do we want a background image in the applet?
     104    public boolean showImage;
     105    public Image backgroundImage;
     106
     107    // Holders for the downloaded data
     108    Panel resultPanel;
     109    PhindTitle title;
     110    ResultDisplay firstDisplay, lastDisplay;
     111
     112    // the mode of operation
     113    int mode;
     114    final int initMode = 0;
     115    final int idleMode = 1;
     116    final int searchMode = 2;
     117
     118    // what to search for
     119    String collection;
     120    int phraseBlockSize;
     121
     122    //int stopwordLevel = 1;
     123    //int lowFrequencyCutoff = 0;
     124    //int stemming = 0;
     125
     126    // where to search
     127    Socket connection;
     128    String library_address, phindcgi_address;
     129    URL library, phindcgi;
     130
     131    String search_url;
     132
     133    // browser details
     134    String localHost;
     135
     136    // The time at which the last query finished
     137    Date lastQueryEndTime;
     138
     139    // lastQueryEndTime is stored to ensure a 1 second gap between a query
     140    // returning and a new one beginning.  It is needed because the FAO
     141    // folks in Rome have a huge lag, and frquently click several times
     142    // while they wait; these clicks are turned into new queries, which
     143    // they await again.  It is no elegant solution, but it seems like the
     144    // easiest, given that I don't know threads.
     145    // 1. The search button is easy to disable, and is disabled when a
     146    //    socket connection is in progress.
     147    // 2. ResutCanvas widgets can'r be similarly disabled because the
     148    //    browser hides or wipes them, which looks very bad.
     149    // 3. I cannot just ignore clicks on canvasses because the browser
     150    //    caches the clicks while the socket connection is going on, and then
     151    //    sends them through afterwards, when the canvas is accepting clicks
     152    //    again.
     153    // 4. Current sequence of events is to record the time the last query
     154    //    ends, then whenever a click happens make sure a second has past.  if
     155    //    you double-click the the first query is sent, returns, end-tie is
     156    //    set, and the second (and any others made during query time) is
     157    //    *immediately* processed, but since 1 second hasn't past it is
     158    //    ignored.
    147159
    148160 
    149 
    150   public String getAppletInfo() {
    151     return "Phind version 2.2 by Gordon Paynter ([email protected]).  Copyright 1997.";
    152   }
    153 
    154   public void init() {
    155 
    156     // default search variable values
    157     mode = initMode;
    158     lastQueryEndTime = new Date();
    159 
    160     // What is this collection called?
    161     collection = new String(getParameter("collection"));
    162     System.out.println("Phind collection: " + collection);
    163 
    164     // What server and port do we conect to?
    165     server = new String(getParameter("server"));
    166     port = new String(getParameter("port"));
    167     System.out.println("Phind server: " + server + ", port: " + port);
    168 
    169     // Is there a search URL for this collection?
    170     search_url = new String(getParameter("search_url"));
    171     System.out.println("Phind search URL: " + search_url);
    172 
    173     // Are the windows arranged vertically or horizontally
    174     if (getParameter("orientation").toLowerCase().startsWith("h")) {
    175       vertical = false;
    176       System.out.println("Phind orientation: horizontal");
    177     } else {
    178       System.out.println("Phind orientation: vertical");
    179       vertical = true;
    180     }
    181 
    182     // How many phind windows are there?
    183     Integer temp;
    184     try {
    185       temp = Integer.valueOf(getParameter("depth"));
    186       depth = temp.intValue();
    187     } catch (Exception e) {
    188       temp = null;
    189       depth = 3;
    190     }
    191     System.out.println("Phind depth: " + depth);
    192 
    193     // How many phrases should we fetch at any given time?
    194     try {
    195       temp = Integer.valueOf(getParameter("blockSize"));
    196        phraseBlockSize = temp.intValue();
    197     } catch (Exception e) {
    198       temp = null;
    199       phraseBlockSize = 10;
    200     }
    201     System.out.println("Phind phrase block size: " + phraseBlockSize);
    202 
    203     // Should we display a background image?
    204     if (getParameter("background").toLowerCase().equals("off")) {
    205       showImage = false;
    206       System.out.println("Phind background: off");
    207     } else {
    208       showImage = true;
    209       System.out.println("Phind background: on");
    210     }
    211 
    212     // How large should the font be?
    213     try {
    214       temp = Integer.valueOf(getParameter("fontsize"));
    215       fontSize = temp.intValue();
    216     } catch (Exception e) {
    217       temp = null;
    218       fontSize = 12;
    219     }
    220     System.out.println("Phind font size: " + fontSize);
    221 
    222 
    223     // browser details
    224     try {
    225       localHost = InetAddress.getLocalHost().toString();
    226     } catch (Exception e) {
    227       localHost = "Can't get client host.";
    228     }
    229     System.out.println("Phind client: " + localHost);
    230     System.out.println("");
    231 
    232 
    233     // The phind applet layout manager
    234     setLayout(new BorderLayout());
    235 
    236     // the Phind title window
    237     if (showImage) backgroundImage = getImage(getCodeBase(), "sequitur.jpg");
    238     title = new PhindTitle(this, true);
    239 
    240     // initialise the user interface
    241     setBackground(Color.white);
    242     plainFont = new Font("Helvetica", Font.PLAIN, fontSize);
    243     boldFont  = new Font("Helvetica", Font.BOLD, fontSize);
    244 
    245     // the main Result area
    246     // the Panel containing the displays is in the center of the display
    247     resultPanel = new Panel();
    248     if (vertical) {
    249       resultPanel.setLayout(new GridLayout(depth,1,0,2));
    250     } else {
    251       System.out.println("horizontal");
    252       resultPanel.setLayout(new GridLayout(1,depth,2,0));
    253     }
    254     add("Center", resultPanel);
    255 
    256     // Create ResultDisplays and place in the interface
    257     ResultDisplay d1, d2 = null;
    258     firstDisplay = new ResultDisplay(this, null);
    259     resultPanel.add(firstDisplay);
    260 
    261     d1 = firstDisplay;
    262     for (int i = 2; i <= depth; i++) {
    263       d2 = new ResultDisplay(this, d1);
    264       resultPanel.add(d2);
    265       d1 = d2;
    266     }
     161    public String getAppletInfo() {
     162    return "Phind by Gordon Paynter ([email protected]). Copyright 1997-2000.";
     163    }
     164
     165    public void init() {
     166
     167    // default search variable values
     168    mode = initMode;
     169    lastQueryEndTime = new Date();
     170
     171    // What is this collection called?
     172    try {
     173        collection = new String(getParameter("collection"));
     174    } catch (Exception e) {
     175        System.err.println("Phind: You must specify a collection.");
     176        stop();
     177    }
     178    System.out.println("Phind collection: " + collection);
     179
     180    // Where do we get the phind data
     181    try {
     182        phindcgi_address = new String(getParameter("phindcgi"));
     183    } catch (Exception e) {
     184        System.err.println("Phind: You must specify a URL for phindcgi.");
     185        stop();
     186    }
     187    System.out.println("Phind phindcgi: " + phindcgi_address);
     188
     189    // Where is the collection served from
     190    try {
     191        library_address = new String(getParameter("library"));
     192    } catch (Exception e) {
     193        System.err.println("Phind: You must specify a URL for library.");
     194        stop();
     195    }
     196    System.out.println("Phind library: " + library_address);
     197
     198    // Is there a search URL for this collection?
     199    try {
     200        search_url = new String(getParameter("search_url"));
     201        System.out.println("Phind search URL: " + search_url);
     202    } catch (Exception e) {
     203        System.out.println("Phind search_url not set.");
     204    }
     205
     206    // Are the windows arranged vertically or horizontally
     207    vertical = true;
     208    try {
     209        if (getParameter("orientation").toLowerCase().startsWith("h")) {
     210        vertical = false;
     211        System.out.println("Phind orientation: horizontal");
     212        }
     213    } catch (Exception e) {
     214        System.out.println("Phind orientation: vertical");
     215    }
     216
     217    // How many phind windows are there?
     218    Integer temp;
     219    try {
     220        temp = Integer.valueOf(getParameter("depth"));
     221        depth = temp.intValue();
     222    } catch (Exception e) {
     223        temp = null;
     224        depth = 3;
     225    }
     226    System.out.println("Phind depth: " + depth);
     227
     228    // How many phrases should we fetch at any given time?
     229    try {
     230        temp = Integer.valueOf(getParameter("blocksize"));
     231        phraseBlockSize = temp.intValue();
     232    } catch (Exception e) {
     233        temp = null;
     234        phraseBlockSize = 10;
     235    }
     236    System.out.println("Phind phrase block size: " + phraseBlockSize);
     237
     238    // Should we display a background image?
     239    showImage = false;
     240    try {
     241        if (getParameter("background").toLowerCase().equals("on")) {
     242        showImage = true;
     243        System.out.println("Phind background: on");
     244        }
     245    } catch (Exception e) {
     246        System.out.println("Phind background: off");
     247    }
     248
     249
     250    // How large should the font be?
     251    try {
     252        temp = Integer.valueOf(getParameter("fontsize"));
     253        fontSize = temp.intValue();
     254    } catch (Exception e) {
     255        temp = null;
     256        fontSize = 12;
     257    }
     258    System.out.println("Phind font size: " + fontSize);
     259
     260    // browser details
     261    try {
     262        localHost = InetAddress.getLocalHost().toString();
     263    } catch (Exception e) {
     264        localHost = "Can't get client host.";
     265    }
     266    System.out.println("Phind client: " + localHost);
     267    System.out.println("");
     268
     269    // The phind applet layout manager
     270    setLayout(new BorderLayout());
     271
     272    // the Phind title window
     273    if (showImage) backgroundImage = getImage(getCodeBase(), "sequitur.jpg");
     274    title = new PhindTitle(this, true);
     275
     276    // initialise the user interface
     277    setBackground(Color.white);
     278    plainFont = new Font("Helvetica", Font.PLAIN, fontSize);
     279    boldFont  = new Font("Helvetica", Font.BOLD, fontSize);
     280
     281    // the main Result area
     282
     283    // the Panel containing the displays is in the center of the display
     284    resultPanel = new Panel();
     285    if (vertical) {
     286        resultPanel.setLayout(new GridLayout(depth,1,0,2));
     287    } else {
     288        System.out.println("horizontal");
     289        resultPanel.setLayout(new GridLayout(1,depth,2,0));
     290    }
     291    add("Center", resultPanel);
     292
     293    // Create ResultDisplays and place in the interface
     294    ResultDisplay d1, d2 = null;
     295    firstDisplay = new ResultDisplay(this, null);
     296    resultPanel.add(firstDisplay);
     297
     298    d1 = firstDisplay;
     299    for (int i = 2; i <= depth; i++) {
     300        d2 = new ResultDisplay(this, d1);
     301        resultPanel.add(d2);
     302        d1 = d2;
     303    }
    267304     
    268     lastDisplay = d2;
    269 
    270 
    271     // The control panel
    272     Panel p1 = new Panel();
    273     add("North", p1);
    274     p1.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
    275 
    276     searchButton = new Button("Search");
    277     searchButton.setFont(boldFont);
    278     p1.add(searchButton);
    279 
    280     Label tempLabel = new Label("  for");
    281     tempLabel.setFont(boldFont);
    282     p1.add(tempLabel);
    283 
    284     wordField = new TextField(12);
    285     wordField.setFont(boldFont);
    286     p1.add(wordField);
    287 
    288     Label temp2 = new Label("          ");
    289     p1.add(temp2);
    290 
    291     prevButton = new Button("Previous");
    292     prevButton.setFont(boldFont);
    293     prevButton.disable();
    294     p1.add(prevButton);
    295 
    296     nextButton = new Button("  Next  ");
    297     nextButton.setFont(boldFont);
    298     nextButton.disable();
    299     p1.add(nextButton);
    300 
    301 
    302     //swlMenu = new Choice();
    303     //swlMenu.addItem("no stopwords");
    304     //swlMenu.addItem("100 stopwords");
    305     //swlMenu.addItem("200 stopwords");
    306     //swlMenu.addItem("300 stopwords");
    307     //swlMenu.addItem("400 stopwords");
    308     //swlMenu.addItem("500 stopwords");
    309     //swlMenu.select(stopwordLevel);
    310 
    311     //lfcMenu = new Choice();
    312     //lfcMenu.addItem("show all phrases");
    313     //lfcMenu.addItem("hide terminal phrases");
    314     //lfcMenu.addItem("phrase frequency > 2");
    315     //lfcMenu.addItem("phrase frequency > 3");
    316     //lfcMenu.addItem("phrase frequency > 4");
    317     //lfcMenu.addItem("phrase frequency > 5");
    318     //lfcMenu.select(lowFrequencyCutoff);
    319 
    320     //stemMenu = new Choice();
    321     //stemMenu.addItem("no stemming");
    322     //stemMenu.addItem("stemming");
    323     //stemMenu.select(stemming);
    324 
    325 
    326     // lets get started then
    327     setStatus("Welcome to Phind.");
    328     mode = idleMode;
    329   }
    330 
    331 
    332   void setStatus(String status) {
    333     showStatus(status);
    334   }
    335 
    336   public boolean action(Event evt, Object arg) {
    337 
    338     if (evt.target == searchButton) {
    339       searchForWord();
    340     } else if (evt.target == wordField) {
    341       searchForWord();
    342     } else if (evt.target == prevButton) {
    343       shiftPrevious();
    344     } else if (evt.target == nextButton) {
    345       shiftNext();
    346     } else {
    347       System.out.println("unknown action: " + evt.toString() + ", object: " + arg.toString());
    348     }
    349     return true;
    350   }
    351 
    352 
    353   // Search for a word
    354   //
    355   // called when the "Search" Button is pressed
    356   void searchForWord() {
    357 
    358     if (mode == idleMode) {
    359 
    360       // transform the word to an appropriate search key
    361       String searchWord = wordField.getText().trim().toLowerCase();
    362       for (int i = 0; i < searchWord.length(); i++) {
    363     if ((searchWord.charAt(i) < 'a') || (searchWord.charAt(i) > 'z')) {
    364       searchWord = searchWord.substring(0, i);
    365     }
    366       }
    367       wordField.setText(searchWord);
    368 
    369       // look up the word
    370       if (searchWord.length() > 1) {
    371     setStatus("searching for \"" + searchWord + "\"");
    372     firstDisplay.emptyContents();
    373     ResultBox result = lookupPhraseOnServer(null, searchWord, searchWord, 2);
    374 
    375     // if there is an error, return
    376     if (result == null) {
    377       setStatus("No results for \"" + searchWord + "\"");
    378       return;
    379     }
    380 
    381     // display the result
    382     result.display = firstDisplay.display(result);
    383     result.resize(result.display.size());
    384     result.paintAll(result.getGraphics());
    385       }
    386 
    387       enablePreviousAndNext();
    388     }
    389   }
     305    lastDisplay = d2;
     306
     307
     308    // The "control panel"
     309    Panel p1 = new Panel();
     310    add("North", p1);
     311    p1.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
     312
     313    searchButton = new Button("Search");
     314    searchButton.setFont(boldFont);
     315    p1.add(searchButton);
     316
     317    Label tempLabel = new Label("  for");
     318    tempLabel.setFont(boldFont);
     319    p1.add(tempLabel);
     320
     321    wordField = new TextField(12);
     322    wordField.setFont(boldFont);
     323    p1.add(wordField);
     324
     325    Label temp2 = new Label("          ");
     326    p1.add(temp2);
     327
     328    prevButton = new Button("Previous");
     329    prevButton.setFont(boldFont);
     330    prevButton.disable();
     331    p1.add(prevButton);
     332
     333    nextButton = new Button("  Next  ");
     334    nextButton.setFont(boldFont);
     335    nextButton.disable();
     336    p1.add(nextButton);
     337
     338    // lets get started then
     339    setStatus("Welcome to Phind.");
     340    mode = idleMode;
     341    }
     342
     343
     344    void setStatus(String status) {
     345    showStatus(status);
     346    }
     347
     348    public boolean action(Event evt, Object arg) {
     349
     350    if (evt.target == searchButton) {
     351        searchForWord();
     352    } else if (evt.target == wordField) {
     353        searchForWord();
     354    } else if (evt.target == prevButton) {
     355        shiftPrevious();
     356    } else if (evt.target == nextButton) {
     357        shiftNext();
     358    } else {
     359        System.out.println("unknown action: " + evt.toString() + ", object: " + arg.toString());
     360    }
     361    return true;
     362    }
     363
     364
     365    // Search for a word
     366    //
     367    // called when the "Search" Button is pressed
     368    void searchForWord() {
     369
     370    if (mode == idleMode) {
     371
     372        // transform the word to an appropriate search key
     373        String searchWord = wordField.getText().trim().toLowerCase();
     374        for (int i = 0; i < searchWord.length(); i++) {
     375        if ((searchWord.charAt(i) < 'a') || (searchWord.charAt(i) > 'z')) {
     376            searchWord = searchWord.substring(0, i);
     377        }
     378        }
     379        wordField.setText(searchWord);
     380
     381        // look up the word
     382        if (searchWord.length() > 1) {
     383        setStatus("searching for \"" + searchWord + "\"");
     384        firstDisplay.emptyContents();
     385        ResultBox result = lookupPhraseOnServer(null, false, searchWord, searchWord, 2);
     386
     387        // if there is an error, return
     388        if (result == null) {
     389            setStatus("No results for \"" + searchWord + "\"");
     390            return;
     391        }
     392
     393        // display the result
     394        result.display = firstDisplay.display(result);
     395        result.resize(result.display.size());
     396        result.paintAll(result.getGraphics());
     397        }
     398
     399        enablePreviousAndNext();
     400    }
     401    }
    390402 
    391403
    392   // Search for a phrase
    393   //
    394   // If querymode is 2, the user has clicked on a phrase.
    395   // If querymode is 3, the user has requested more phrases.
    396   // If querymode is 4, the user has requested more documents.
    397   void searchForPhrase(ResultBox source, String key, String phrase, int queryMode) {
    398 
    399     // System.out.println("searchForPhrase: " + key + " " + phrase + " " + queryMode);
    400 
    401     if (mode == idleMode) {
    402 
    403       // If we are going to replace the next ResultDisplay, then empty it
    404       if (queryMode <= 2) {
    405     if (source.display.next != null) source.display.next.emptyContents();
    406       }
    407 
    408       // look up the word
    409       setStatus("Searching for \"" + phrase + "\"");
    410       ResultBox result = lookupPhraseOnServer(source, key, phrase, queryMode);
    411       if (result == null) {
    412     setStatus("No result for \"" + phrase + "\"");
    413     return;
    414       }
    415 
    416       // If this is not already displayed, display it in the last free spot
    417       if (queryMode <= 2) {
    418     result.display = lastDisplay.display(result);
    419     result.resize(result.display.size());
    420     result.paintAll(result.getGraphics());
    421       }
    422 
    423       enablePreviousAndNext();
    424     }
    425   }
    426 
    427 
    428   // Look up a phrase (or symbol) on the server
    429   //
    430   // Arguments are the source of the query (a ResultBox, or null if the
    431   // query comes from hitting the search button), the key to search for
    432   // (the text of a phrase or a symbol number), the phrase as a string,
    433   // and the query mode.
    434   // Query modes are:
    435   //   0 = get all phrases with LFC,
    436   //   1 = get all URLs with LFC,
    437   //   2 = get first N phrases and URLs,
    438   //   3 = get another N phrases into same window
    439   //   4 = get another N documents into same window
    440 
    441   ResultBox lookupPhraseOnServer(ResultBox source, String key, String phrase, int queryMode) {
     404    // Search for a phrase
     405    //
     406    // If querymode is 2, the user has clicked on a phrase.
     407    // If querymode is 3, the user has requested more phrases.
     408    // If querymode is 4, the user has requested more documents.
     409    void searchForPhrase(ResultBox source, String key, String phrase, int queryMode) {
     410
     411    // System.out.println("searchForPhrase: " + key + " " + phrase + " " + queryMode);
     412
     413    if (mode == idleMode) {
     414
     415        // If we are going to replace the next ResultDisplay, then empty it
     416        if (queryMode <= 2) {
     417        if (source.display.next != null) source.display.next.emptyContents();
     418        }
     419
     420        // look up the word
     421        setStatus("Searching for \"" + phrase + "\"");
     422        ResultBox result = lookupPhraseOnServer(source, true, key, phrase, queryMode);
     423        if (result == null) {
     424        setStatus("No result for \"" + phrase + "\"");
     425        return;
     426        }
     427
     428        // If this is not already displayed, display it in the last free spot
     429        if (queryMode <= 2) {
     430        result.display = lastDisplay.display(result);
     431        result.resize(result.display.size());
     432        result.paintAll(result.getGraphics());
     433        }
     434
     435        enablePreviousAndNext();
     436    }
     437    }
     438
     439
     440    // Look up a phrase (or symbol) on the server
     441    //
     442    // Arguments are the source of the query (a ResultBox, or null if the
     443    // query comes from hitting the search button), the key to search for
     444    // (the text of a phrase or a symbol number), the phrase as a string,
     445    // and the query mode.
     446    // Query modes are:
     447    //   0 = obsolete
     448    //   1 = obsolete
     449    //   2 = get first N phrases and URLs,
     450    //   3 = get another N phrases into same window
     451    //   4 = get another N documents into same window
     452
     453    ResultBox lookupPhraseOnServer(ResultBox source,
     454                   boolean keyKnown, String key, String phrase,
     455                   int queryMode) {
     456        searchButton.disable();
     457    mode = searchMode;
     458    ResultBox r = null;
     459
     460    if (queryMode <= 2) {
     461        r = new ResultBox(this, collection, key, phrase, source);
     462    } else if ((queryMode == 3) || (queryMode == 4)) {
     463        r = source;
     464    }
     465
     466    try {
     467        queryServer(keyKnown, key, queryMode, r);
     468    } catch (Exception e) {
     469        System.out.println("Phind query error: " + e.toString());
     470        setStatus("Query error: " + e.toString());
     471        mode = idleMode;
     472        searchButton.enable();
     473        return null;
     474    }
     475     
     476    // The query is finished
     477    setStatus(r.c.numberOfPhrases + " results containing \"" + phrase + "\"");
     478    mode = idleMode;
     479    searchButton.enable();
     480    lastQueryEndTime = new Date();
     481
     482    return r;
     483    }
     484
     485
     486    // Query the phindcgi program
     487    //
     488    // Send a query (a word or symbol number) to the server
     489    // Open a socket connection to the server, send it a query,
     490    // and pass the result to a ResultBox.
     491
     492    void queryServer(boolean keyKnown, String word, int queryMode, ResultBox area)
     493    throws IOException {
     494
     495    // Set up connections (streams)
     496    //connection = new Socket(server, Integer.parseInt(port));
     497    //OutputStream out = connection.getOutputStream();
     498    //InputStream in = connection.getInputStream();
     499
     500    // Build the query
     501    String query = phindcgi_address + "?x=1&c=" + collection;
     502
     503    if (keyKnown) {
     504        query = query + "&n=" + word;
     505    } else {
     506        query = query + "&p=" + word;
     507    }
     508
     509    // Specify the number of results to return and the first and last results.
     510    if (queryMode <= 2) {
     511        query = query + "&f=0&d=" + phraseBlockSize + "&g=0&e=" + phraseBlockSize;
     512    } else if (queryMode == 3) {
     513        // Add phrases to an existing result set.
     514        query = query + "&f=0&d=" + phraseBlockSize + "&g=0&e=" + phraseBlockSize;
     515        // query = (word + " " + queryMode + " " + phraseBlockSize + " " + area.nextPhraseBlock);
     516        area.nextPhraseBlock++;
     517    } else if (queryMode == 4) {
     518        // Add documents to existing result set.
     519        query = query + "&f=0&d=" + phraseBlockSize + "&g=0&e=" + phraseBlockSize;
     520        // query = (word + " " + queryMode + " " + phraseBlockSize + " " + area.nextDocumentBlock);
     521        area.nextDocumentBlock++;
     522    }
     523
     524
     525    // Send the query to the phindcgi program
     526    System.out.println("sending query: " + query);
     527    try {
     528        phindcgi = new URL(query);
     529        DataInputStream in = new DataInputStream(phindcgi.openStream());
     530        byte[] buffer;
     531        int availableBytes = 0;
     532
     533        while (!area.finished) {
     534        availableBytes = in.available();
     535        if (availableBytes == 0) {
     536            // if i had threads i'd do a wait here for 1 second
     537        } else {
     538            buffer = new byte[availableBytes];
     539            in.read(buffer);
     540            area.parseBytes(buffer);
     541        }
     542        }
     543       
     544        in.close();
     545    } catch (Exception e) {
     546        System.err.println( "Error sending query to phindcgi: " + e);
     547    }
     548    area.repaint();
     549    }
    442550   
    443     searchButton.disable();
    444     mode = searchMode;
    445     ResultBox r = null;
    446 
    447     if (queryMode <= 2) {
    448       r = new ResultBox(this, collection,
    449             key, phrase, stopwordLevel, lowFrequencyCutoff, source);
    450       // area.resetBox();
    451     } else if ((queryMode == 3) || (queryMode == 4)) {
    452       r = source;
    453     }
    454 
    455     try {
    456       queryServer(key, queryMode, r);
    457     } catch (Exception e) {
    458       System.out.println("Phind socket exception error: " + e.toString());
    459       setStatus("Socket error: " + e.toString());
    460       mode = idleMode;
    461       searchButton.enable();
    462       return null;
    463     }
    464      
    465     // The query is finished
    466     setStatus(r.c.numberOfPhrases + " results containing \"" + phrase + "\"");
    467     mode = idleMode;
    468     searchButton.enable();
    469     lastQueryEndTime = new Date();
    470     // System.out.println("Query end time: " + lastQueryEndTime.toString());
    471 
    472     return r;
    473   }
    474 
    475   // Send a query (a word or symbol number) to the server
    476   // Open a socket connection to the server, send it a query,
    477   // and pass the result to a ResultBox.
    478   void queryServer( String word, int queryMode, ResultBox area ) throws IOException {
    479 
    480     // Set up connections (streams)
    481     connection = new Socket(server, Integer.parseInt(port));
    482     OutputStream out = connection.getOutputStream();
    483     InputStream in = connection.getInputStream();
    484 
    485     // Build the query
    486     String query = "";
    487     if (queryMode < 2) {
    488       // Specify the LFC and whether to use stemming
    489       query = (word + " " + queryMode + " " + lowFrequencyCutoff + " " + stemming);
    490     } else if (queryMode == 2) {
    491       // Specify the number of results to return and
    492       // the result set number.
    493       query = (word + " " + queryMode + " " + phraseBlockSize + " 0");
    494     } else if (queryMode == 3) {
    495       // The user is adding another 100 (or so) phrases to an
    496       // existing result set.
    497       query = (word + " " + queryMode + " " + phraseBlockSize + " " + area.nextPhraseBlock);
    498       area.nextPhraseBlock++;
    499     } else if (queryMode == 4) {
    500       // Add documents to existing result set.
    501       query = (word + " " + queryMode + " " + phraseBlockSize + " " + area.nextDocumentBlock);
    502       area.nextDocumentBlock++;
    503     }
    504 
    505     // Add a comment identifying the host to the query
    506     query = (query + " # " + localHost);
    507 
    508 
    509     // System.out.println("sending query: " + query);
    510 
    511     // Send the query
    512     char searchChars[] = query.toCharArray();
    513     byte searchBytes[] = new byte[searchChars.length + 1];
    514     for (int i = 0; i < searchChars.length; i++)
    515       searchBytes[i] = (byte) searchChars[i];
    516     searchBytes[searchChars.length] = ((byte) '\n');
    517     out.write(searchBytes);
    518 
    519     // Read the response
    520     int maxBytes = 1000;
    521     int availableBytes = 0;
    522     byte[] buffer;
    523     boolean reachedDONE = false;
    524 
    525     while (!reachedDONE) {
    526       // System.out.print("reading: " + in.available());
    527       availableBytes = in.available();
    528       if (availableBytes == 0) {
    529     // if i had threads i'd do a wait here for 1 second
    530       } else {
    531     buffer = new byte[availableBytes];
    532     in.read(buffer);
    533     area.parseBytes(buffer);
    534     reachedDONE = area.finished;
    535       }
    536     }
    537 
    538     area.repaint();
    539     connection.close();
    540   }
    541 
    542 
    543   // Previous and Next functionality
    544 
    545   // enable or disable the "Previous" and "Next" buttons
    546   void enablePreviousAndNext() {
    547 
    548     Component c = firstDisplay.current;
    549     if (c.getClass().getName().equals("ResultBox")) {
    550       if (((ResultBox) c).prevBoxExists()) {
    551     prevButton.enable();
    552       } else {
    553     prevButton.disable();
    554       }
    555     }
    556 
    557     c = lastDisplay.current;
    558     if (c.getClass().getName().equals("ResultBox")) {
    559       if (((ResultBox) c).nextBoxExists()) {
    560     nextButton.enable();
    561       } else {
    562     nextButton.disable();
    563       }
    564     }
    565   }
    566 
    567   // Shift to previous box
    568   //
    569   // If the user clicks "Previous" then scroll up.
    570   void shiftPrevious() {
    571 
    572     Component c = firstDisplay.current;
    573     if (c.getClass().getName().equals("ResultBox")) {
    574 
    575       ResultBox b = (ResultBox) c;
    576       if (b.prevBoxExists()) {
    577     b = b.prev;
    578 
    579     // empty all the displays
    580     firstDisplay.emptyContents();
    581 
    582     // add as many result boxes as there are displays
    583     for (int i = 1 ; ((i <= depth) && (b != null)); i++) {
    584       lastDisplay.display(b);
    585       b.resize(b.display.size());
    586       b.paintAll(b.getGraphics());
    587       b = b.next;
    588     }
    589       }
    590     }
    591     enablePreviousAndNext();
    592   }
    593 
    594 
    595   // Shift to next box
    596   //
    597   // If the user clicks "Next" then scroll down if possible
    598   void shiftNext() {
    599 
    600     Component c = lastDisplay.current;
    601     if (c.getClass().getName().equals("ResultBox")) {
    602 
    603       ResultBox b = (ResultBox) c;
    604       if (b.nextBoxExists()) {
    605 
    606     // find the new "first" displayed box
    607         c = firstDisplay.current;
    608     b = (ResultBox) c;
    609     b = b.next;
    610 
    611     // empty all the displays
    612     firstDisplay.emptyContents();
    613 
    614     // add as many result boxes as there are displays
    615     for (int i = 1 ; ((i <= depth) && (b != null)); i++) {
    616       lastDisplay.display(b);
    617       b.resize(b.display.size());
    618       b.paintAll(b.getGraphics());
    619       b = b.next;
    620     }
    621       }
    622     }
    623     enablePreviousAndNext();
    624   }
     551
     552    // Previous and Next button functionality
     553
     554    // enable or disable the "Previous" and "Next" buttons
     555    void enablePreviousAndNext() {
     556
     557    Component c = firstDisplay.current;
     558    if (c.getClass().getName().equals("ResultBox")) {
     559        if (((ResultBox) c).prevBoxExists()) {
     560        prevButton.enable();
     561        } else {
     562        prevButton.disable();
     563        }
     564    }
     565
     566    c = lastDisplay.current;
     567    if (c.getClass().getName().equals("ResultBox")) {
     568        if (((ResultBox) c).nextBoxExists()) {
     569        nextButton.enable();
     570        } else {
     571        nextButton.disable();
     572        }
     573    }
     574    }
     575
     576    // Shift to previous box
     577    //
     578    // If the user clicks "Previous" then scroll up.
     579    void shiftPrevious() {
     580
     581    Component c = firstDisplay.current;
     582    if (c.getClass().getName().equals("ResultBox")) {
     583
     584        ResultBox b = (ResultBox) c;
     585        if (b.prevBoxExists()) {
     586        b = b.prev;
     587
     588        // empty all the displays
     589        firstDisplay.emptyContents();
     590
     591        // add as many result boxes as there are displays
     592        for (int i = 1 ; ((i <= depth) && (b != null)); i++) {
     593            lastDisplay.display(b);
     594            b.resize(b.display.size());
     595            b.paintAll(b.getGraphics());
     596            b = b.next;
     597        }
     598        }
     599    }
     600    enablePreviousAndNext();
     601    }
     602
     603
     604    // Shift to next box
     605    //
     606    // If the user clicks "Next" then scroll down if possible
     607    void shiftNext() {
     608
     609    Component c = lastDisplay.current;
     610    if (c.getClass().getName().equals("ResultBox")) {
     611
     612        ResultBox b = (ResultBox) c;
     613        if (b.nextBoxExists()) {
     614
     615        // find the new "first" displayed box
     616        c = firstDisplay.current;
     617        b = (ResultBox) c;
     618        b = b.next;
     619
     620        // empty all the displays
     621        firstDisplay.emptyContents();
     622
     623        // add as many result boxes as there are displays
     624        for (int i = 1 ; ((i <= depth) && (b != null)); i++) {
     625            lastDisplay.display(b);
     626            b.resize(b.display.size());
     627            b.paintAll(b.getGraphics());
     628            b = b.next;
     629        }
     630        }
     631    }
     632    enablePreviousAndNext();
     633    }
    625634
    626635}
  • trunk/gsdl/src/phind/client/ResultBox.java

    r1621 r1625  
     1/**********************************************************************
     2 *
     3 * ResultBox.java -- a list of phrases in the Phind java interface
     4 *
     5 * Copyright 1997-2000 Gordon W. Paynter
     6 * Copyright 2000 The New Zealand Digital Library Project
     7 *
     8 * A component of the Greenstone digital library software
     9 * from the New Zealand Digital Library Project at the
     10 * University of Waikato, New Zealand.
     11 *
     12 * This program is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU General Public License as published by
     14 * the Free Software Foundation; either version 2 of the License, or
     15 * (at your option) any later version.
     16 *
     17 * This program is distributed in the hope that it will be useful,
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 * GNU General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU General Public License
     23 * along with this program; if not, write to the Free Software
     24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     25 *
     26 *********************************************************************/
     27
     28/*********************************************************************
     29
     30This class is used in the Phind java applet (Phind.java).
     31
     32A ResultBox holds the results of a query to phindcgi.  They deal mostly
     33with the information content of the query, and have methods for parsing the
     34input into phrase and document items.  They have little do with display:
     35ResultBoxes are shown to the user through "ResultDisplay" panels, and are
     36drawn using "ResultCanvas" objects.
     37
     38**********************************************************************/
     39
     40
    141import java.awt.Panel;
    242import java.awt.BorderLayout;
     
    1151import java.util.Vector;
    1252
     53
    1354public class ResultBox extends Panel {
    14 
    15   // Other objects at a higher level than this one
    16   Phind phind;
    17   ResultDisplay display;
    18   ResultBox prev, next;
    19 
    20   // The objects this one contains
    21   ResultCanvas c;
    22   ResultTitle t;
    23   Scrollbar s;
    24   Panel label;
    25 
    26   // Information about the query
    27   String searchKey, searchPhrase;
    28   String searchCollection;
    29   int searchSWL, searchLFC;
    30 
    31   // Information about the result set
    32   int numberOfExpansions;
    33   int expansionsRetrieved;
    34   int numberOfDocuments;
    35   int documentsRetrieved;
    36   int nextPhraseBlock;
    37   int nextDocumentBlock;
    38 
    39   // just why did i add these variables?
    40   int mode;
    41   final int initMode = 0;
    42   public final int emptyMode = 1;
    43   final int loadingMode = 2;
    44   final int finishedMode = 3;
    45 
    46   String buffer;
    47   boolean finished;
    48 
    49 
    50   // Create a ResultBox
    51   // given details of the search that generated it.
    52   ResultBox(Phind p, String collect, String key, String phrase, int swl, int lfc, ResultBox rb) {
    53 
    54     super();
    55     mode = initMode;
    56 
    57     phind = p;
    58     display = null;
    59     next = null;
    60     prev = rb;
    61     if (prev != null) prev.next = this;
    62 
    63     numberOfExpansions = -1;
    64     expansionsRetrieved = 0;
    65     numberOfDocuments = -1;
    66     documentsRetrieved = 0;
    67     nextPhraseBlock = 1;
    68     nextDocumentBlock = 1;
    69 
    70     searchKey = key;
    71     searchPhrase = phrase;
    72     searchCollection = collect;
    73     searchSWL = swl;
    74     searchLFC = lfc;
    75 
    76     setLayout(new BorderLayout());
    77 
    78 
    79     s = new Scrollbar(Scrollbar.VERTICAL);
    80     disableScrollbar();
    81     add("East", s);
    82 
    83     c = new ResultCanvas(this);
    84     add("Center", c);
    85 
    86     t = new ResultTitle(this);
    87     add("North", t);
    88 
    89     buffer = "";
    90     finished = false;
    91     mode = emptyMode;
    92   }
    93 
    94   static String describeContents(String phrase, String c, int swl) {
    95     return( "\"" +phrase + "\" in " + c + ", swl = " + swl + ".");
    96   }
    97 
    98   String describeContents() {
    99     return( describeContents(searchPhrase, searchCollection, searchSWL) );
    100   }
    101 
    102 
    103   // Reset the contents of the box
    104   void resetBox( ) {
    105     buffer = "";
    106     finished = false;
    107     c.resetCanvas();
    108     disableScrollbar();
    109     mode = emptyMode;
    11055   
    111     numberOfExpansions = -1;
    112     expansionsRetrieved = 0;
    113     numberOfDocuments = -1;
    114     documentsRetrieved = 0;
    115   }
    116 
    117   void setStatus( String status ) {
    118     phind.setStatus(status);
    119   }
    120 
    121   void disableScrollbar() {
    122     if (s.isEnabled()) {
    123       s.setValues(0, 1, 0, 1);
    124       s.setLineIncrement(1);
    125       s.setPageIncrement(1);
    126       s.disable();
    127     }
    128   }
    129 
    130   // Are there displays previous to and after this?
    131   public boolean prevBoxExists () {
    132     return (prev != null);
    133   }
    134   public boolean nextBoxExists () {
    135     return (next != null);
    136   }
    137 
    138 
    139   void lookupPhrase(String key, String phrase, int queryMode) {
    140     buffer = "";
    141     finished = false;
    142     phind.searchForPhrase(this, key, phrase, queryMode);
    143     t.repaint();
    144   }
    145 
    146   public boolean handleEvent(Event event) {
    147     //    System.out.println("event: " + event.toString());
    148     if ( (event.target == s) &&
    149      ( (event.id == Event.SCROLL_ABSOLUTE) ||
    150        (event.id == Event.SCROLL_LINE_DOWN) ||
    151        (event.id == Event.SCROLL_LINE_UP) ||
    152        (event.id == Event.SCROLL_PAGE_DOWN) ||
    153        (event.id == Event.SCROLL_PAGE_UP) ) ) {
    154       c.repaint();
    155       return true;
    156     } else {
    157       return super.handleEvent(event);
    158     }
    159   }   
    160 
    161 
    162   // a new section of the byte stream is read
    163   void parseBytes(byte[] bytes) {
    164     mode = loadingMode;
    165 
    166     // update the buffer that holds the bytes read
    167     String input = new String(bytes,0);
    168     buffer = buffer.concat(input);
    169 
    170     // if buffer ends with "DONE" then we are finished reading
    171     finished = buffer.endsWith("DONE\n");
    172 
    173     // Parse each line until there are no more lines to parse
    174     while(parseLine());
    175 
    176     if (finished) {
    177       c.updateMorePhrasesMarker();
    178       c.updateMoreDocumentsMarker();
    179     } else {
    180       // We haven't finished, give some feedback about progress
    181       setStatus("Connected to host, " + c.numberOfPhrases + " results read");
    182     }
    183   }
    184 
    185   // try to sort the buffered bytes into lines and output them
    186   // returns true if a full line of text was extracted
    187   boolean parseLine() {
    188 
    189     // System.out.println("parseLine " + finished + "(" + expansionsRetrieved + ")");
    190    
    191     int eol = buffer.indexOf((int) '\n');
    192     if (eol == -1) {
    193       return false;
    194 
    195     } else if (buffer.charAt(0) == 'D') {
    196       // System.out.println( "parseLine has hit DONE" );
    197       mode = finishedMode;
    198       return false;
    199 
    200     } else {
    201       String item = buffer.substring(0, eol);
    202       buffer = buffer.substring(eol + 1);
    203       if (!addLine(item)) {
    204     System.out.println( "Error calling addline with: " + item );
    205       }
    206       return true;
    207     }
    208   }
    209 
    210   // add a single line of input.
    211   // return true if successful, otherwise false.
    212   boolean addLine( String line ) {
    213 
    214     // System.out.println( "addLine: " + line + "(" + expansionsRetrieved + ")");
    215 
    216     int nextSplit;
    217     String ruleStr = "", freqStr = "", expandStr = "", docfStr = "",
    218       prefix = "", body = "", suffix = "";
    219 
    220     // If there is no space on the line, then there is only one number.
    221     // This number is the number of results; we can expect two such;
    222     // the first is the number of expansions, the second documents
    223     nextSplit = line.indexOf((int) ' ');
    224     if (nextSplit == -1) {
    225       if (numberOfExpansions < 0) {
    226     numberOfExpansions = Integer.valueOf(line).intValue();
    227       } else if (numberOfDocuments < 0) {
    228     numberOfDocuments = Integer.valueOf(line).intValue();
    229       }
    230       return true;
    231     }
    232 
    233     // get the rule number
    234     ruleStr = line.substring(0, nextSplit);
    235     line = line.substring(nextSplit + 1);
    236 
    237     // find the frequency
    238     nextSplit = line.indexOf((int) ' ');
    239     if (nextSplit == -1) {
    240       System.out.println( "Error: can't find a space in:" + line );
    241       return false;
    242     }
    243     freqStr = line.substring(0, nextSplit);
    244     line = line.substring(nextSplit + 1);
     56    // Objects at a "higher" level than this one
     57    Phind phind;
     58    ResultDisplay display;
     59
     60    // Surroundig objects
     61    ResultBox prev, next;
     62
     63    // The components contained by this one.
     64    ResultCanvas c;
     65    ResultTitle t;
     66    Scrollbar s;
     67    Panel label;
     68
     69    // Information about the query
     70    String searchKey, searchPhrase;
     71    String searchCollection;
    24572   
    246     // find the expansion boolean
    247     nextSplit = line.indexOf((int) ' ');
    248     if (nextSplit == -1) {
    249       System.out.println( "Error: can't find second space in: " + line );
    250       return false;
    251     }
    252     expandStr = line.substring(0, nextSplit);
    253     line = line.substring(nextSplit + 1);
    254 
    255     // find the document frequency
    256     nextSplit = line.indexOf((int) ' ');
    257     if (nextSplit == -1) {
    258       System.out.println( "Error: can't find second space in: " + line );
    259       return false;
    260     }
    261     docfStr = line.substring(0, nextSplit);
    262     line = line.substring(nextSplit + 1);
    263 
    264     // find the prefix
    265     nextSplit = line.indexOf((int) '<');
    266     if (nextSplit == -1) {
    267       System.out.println( "Error: can't find a \"<\" in:" + line );
    268       return false;
    269     }
    270     prefix = line.substring(0, nextSplit).trim();
    271     line = line.substring(nextSplit + 1);
    272 
    273     // find the body and suffix
    274     nextSplit = line.indexOf((int) '>');
    275     if (nextSplit == -1) {
    276       System.out.println( "Error: can't find a \">\" in:" + line );
    277       return false;
    278     }
    279     body = line.substring(0, nextSplit).trim();
    280     suffix = line.substring(nextSplit + 1).trim();
    281 
    282     //    System.out.println( "body: " + body + " - " + suffix);
    283 
    284     ResultItem ri = new ResultItem(ruleStr, freqStr, expandStr,
    285                    docfStr, prefix, body, suffix);
    286 
    287     if (c.addResultItem(ri)) {
    288       if (ri.isPhrase()) {
    289     expansionsRetrieved++;
    290       } else {
    291     documentsRetrieved++;
    292       }
    293       return true;
    294     } else {
    295       return false;
    296     }
    297   }
    298 
     73    // Information about the result set
     74    int numberOfExpansions;
     75    int expansionsRetrieved;
     76    int numberOfDocuments;
     77    int documentsRetrieved;
     78    int nextPhraseBlock;
     79    int nextDocumentBlock;
     80   
     81    // just why did i add these variables?
     82    int mode;
     83    final int initMode = 0;
     84    public final int emptyMode = 1;
     85    final int loadingMode = 2;
     86    final int finishedMode = 3;
     87
     88    String buffer;
     89    boolean finished;
     90
     91
     92    // Create a ResultBox
     93    // given details of the search that generated it.
     94    ResultBox(Phind p, String collect, String key, String phrase, ResultBox rb) {
     95
     96    super();
     97    mode = initMode;
     98
     99    phind = p;
     100    display = null;
     101    next = null;
     102    prev = rb;
     103    if (prev != null) prev.next = this;
     104
     105    numberOfExpansions = -1;
     106    expansionsRetrieved = 0;
     107    numberOfDocuments = -1;
     108    documentsRetrieved = 0;
     109    nextPhraseBlock = 1;
     110    nextDocumentBlock = 1;
     111
     112    searchKey = key;
     113    searchPhrase = phrase;
     114    searchCollection = collect;
     115
     116    setLayout(new BorderLayout());
     117
     118
     119    s = new Scrollbar(Scrollbar.VERTICAL);
     120    disableScrollbar();
     121    add("East", s);
     122
     123    c = new ResultCanvas(this);
     124    add("Center", c);
     125
     126    t = new ResultTitle(this);
     127    add("North", t);
     128
     129    buffer = "";
     130    finished = false;
     131    mode = emptyMode;
     132    }
     133
     134    static String describeContents(String phrase, String c) {
     135    return( "\"" +phrase + "\" in " + c + ".");
     136    }
     137
     138    String describeContents() {
     139    return( describeContents(searchPhrase, searchCollection) );
     140    }
     141
     142
     143    // Reset the contents of the box
     144    void resetBox( ) {
     145    buffer = "";
     146    finished = false;
     147    c.resetCanvas();
     148    disableScrollbar();
     149    mode = emptyMode;
     150   
     151    numberOfExpansions = -1;
     152    expansionsRetrieved = 0;
     153    numberOfDocuments = -1;
     154    documentsRetrieved = 0;
     155    }
     156
     157    void setStatus( String status ) {
     158    phind.setStatus(status);
     159    }
     160
     161    void disableScrollbar() {
     162    if (s.isEnabled()) {
     163        s.setValues(0, 1, 0, 1);
     164        s.setLineIncrement(1);
     165        s.setPageIncrement(1);
     166        s.disable();
     167    }
     168    }
     169
     170    // Are there displays previous to and after this?
     171    public boolean prevBoxExists () {
     172    return (prev != null);
     173    }
     174    public boolean nextBoxExists () {
     175    return (next != null);
     176    }
     177
     178
     179    void lookupPhrase(String key, String phrase, int queryMode) {
     180    buffer = "";
     181    finished = false;
     182    phind.searchForPhrase(this, key, phrase, queryMode);
     183    t.repaint();
     184    }
     185
     186    public boolean handleEvent(Event event) {
     187    //    System.out.println("event: " + event.toString());
     188    if ( (event.target == s) &&
     189         ( (event.id == Event.SCROLL_ABSOLUTE) ||
     190           (event.id == Event.SCROLL_LINE_DOWN) ||
     191           (event.id == Event.SCROLL_LINE_UP) ||
     192           (event.id == Event.SCROLL_PAGE_DOWN) ||
     193           (event.id == Event.SCROLL_PAGE_UP) ) ) {
     194        c.repaint();
     195        return true;
     196    } else {
     197        return super.handleEvent(event);
     198    }
     199    }   
     200
     201
     202    // a new section of the byte stream is read
     203    void parseBytes(byte[] bytes) {
     204    mode = loadingMode;
     205
     206    // update the buffer that holds the bytes read
     207    String input;
     208    try {
     209        input = new String(bytes, new String("Latin1"));
     210    } catch (Exception e) {
     211        System.err.println(e);
     212        input = "";
     213    }
     214    buffer = buffer.concat(input);
     215
     216    // if buffer ends with "</phinddata>" then we are finished reading
     217    finished = buffer.endsWith("</phinddata>\n");
     218
     219    // Parse each line until there are no more lines to parse
     220    while(parseLine());
     221
     222    if (finished) {
     223        c.updateMorePhrasesMarker();
     224        c.updateMoreDocumentsMarker();
     225    } else {
     226        // We haven't finished, give some feedback about progress
     227        setStatus("Connected to host, " + c.numberOfPhrases + " results read");
     228    }
     229    }
     230
     231    // Parse a line of XML
     232    //
     233    // This isn't necessarily real XML.  We assume every tag begins and
     234    // ends on one line.  We read one line out of the buffer at a time,
     235    // then "add" them to the box with the addLine method.
     236    //
     237    // Return true if there is a another line here to parse, otherwise false.
     238
     239    boolean parseLine() {
     240
     241    // System.out.println("parseLine " + finished + "(" + expansionsRetrieved + ")");
     242    String item;
     243    int eol = buffer.indexOf((int) '\n');
     244
     245    // If there are no carriage returns, the line is incomplete
     246    if (eol == -1) {
     247        return false;
     248    }
     249
     250    // The <phinddata> tag introduces the dataset
     251    else if (buffer.startsWith("<phinddata ")) {
     252
     253    }
     254
     255    // The <expansionlist> tag
     256    else if (buffer.startsWith("<expansionlist ")) {
     257
     258    }
     259 
     260    // The <expansion> tag
     261    else if (buffer.startsWith("<expansion ")) {
     262        item = buffer.substring(0, eol);
     263        buffer = buffer.substring(eol + 1);
     264        addExpansionTag(item);
     265        return true;
     266    }
     267 
     268    // The <document> tag
     269    else if (buffer.startsWith("<document ")) {
     270        item = buffer.substring(0, eol);
     271        buffer = buffer.substring(eol + 1);
     272        addDocumentTag(item);
     273        return true;
     274    }
     275 
     276    // The <documentlist> tag
     277    else if (buffer.startsWith("<documentlist ")) {
     278
     279    }
     280 
     281    // The </phinddata> tag concludes the dataset
     282    else if (buffer.startsWith("</phinddata>")) {
     283        mode = finishedMode;
     284        return false;
     285    }
     286   
     287    // Ignore the piece we've read
     288    item = buffer.substring(0, eol);
     289    buffer = buffer.substring(eol + 1);
     290    return true;
     291    }
     292   
     293
     294
     295    // Add an expansion tag
     296    //
     297    // Given a string containing an XML expansin tag of the form:
     298    //   <expansion num="3" id="8421" text="PEOPLE and TREES" tf="3" df="3"/>
     299    //   <expansion num="4" id="8696" text="FOREST TREES" tf="3" df="3"/>
     300    // Create a new ResultItem for display
     301    //
     302    // Return true if successful, otherwise false.
     303
     304    boolean addExpansionTag( String line ) {
     305
     306    // System.out.println( "addExpansionTag: " + line + " (" + expansionsRetrieved + ")");
     307
     308    String numStr = "", idStr = "", tfStr = "", dfStr = "", body = "";
     309
     310    // Break the tag down into its component parts
     311    line = line.substring(11);
     312    int nextSplit;
     313        while (line.length() > 0) {
     314        line = line.trim();
     315
     316        // Read the expansion number
     317        if (line.startsWith("num")) {
     318        line = line.substring(5);
     319        nextSplit = line.indexOf((int) '"');
     320        if (nextSplit >= 1) {
     321            numStr = line.substring(0, nextSplit);
     322            line = line.substring(nextSplit + 1);
     323        } else {
     324            System.err.println("ResultBox addExpansionTag: error parsing: " + line);
     325        }
     326        }
     327
     328        // Read the phrase ID
     329        else if (line.startsWith("id")) {
     330        line = line.substring(4);
     331        nextSplit = line.indexOf((int) '"');
     332        if (nextSplit >= 1) {
     333            idStr = line.substring(0, nextSplit);
     334            line = line.substring(nextSplit + 1);
     335        } else {
     336            System.err.println("ResultBox addExpansionTag: error parsing: " + line);
     337        }
     338        }
     339
     340        // Read the text of the phrase
     341        else if (line.startsWith("text")) {
     342        line = line.substring(6);
     343        nextSplit = line.indexOf((int) '"');
     344        if (nextSplit >= 1) {
     345            body = line.substring(0, nextSplit);
     346            line = line.substring(nextSplit + 1);
     347        } else {
     348            System.err.println("ResultBox addExpansionTag: error parsing: " + line);
     349        }
     350        }
     351
     352        // Read the frequency
     353        else if (line.startsWith("tf")) {
     354        line = line.substring(4);
     355        nextSplit = line.indexOf((int) '"');
     356        if (nextSplit >= 1) {
     357            tfStr = line.substring(0, nextSplit);
     358            line = line.substring(nextSplit + 1);
     359        } else {
     360            System.err.println("ResultBox addExpansionTag: error parsing: " + line);
     361        }
     362        }
     363
     364        // Read the document frequency
     365        else if (line.startsWith("df")) {
     366        line = line.substring(4);
     367        nextSplit = line.indexOf((int) '"');
     368        if (nextSplit >= 1) {
     369            dfStr = line.substring(0, nextSplit);
     370            line = line.substring(nextSplit + 1);
     371        } else {
     372            System.err.println("ResultBox addExpansionTag: error parsing: " + line);
     373        }
     374        }
     375
     376        // Read some other tag
     377        else {
     378        nextSplit = line.indexOf((int) ' ');
     379        if (nextSplit >= 1) {
     380            line = line.substring(nextSplit + 1);
     381        } else {
     382            line = "";
     383        }
     384        }
     385    }
     386   
     387    // Create a new ResultItem and add it to the display
     388    ResultItem ri = new ResultItem(idStr, tfStr, dfStr, "", body, "");
     389   
     390    if (c.addResultItem(ri)) {
     391        expansionsRetrieved++;
     392        return true;
     393    }
     394   
     395    return false;
     396    }
     397
     398
     399
     400
     401    // Add an document tag
     402    //
     403    // Given a string containing an XML document tag of the form:
     404    //   <document num="2" hash="HASH424e64b811fdad933be69c" freq="1" title="CONTENS"/>
     405    //   <document num="3" hash="HASH01f08efd8752ad54ca0a99cf" freq="1" title="Tree mixtures"/>
     406    //
     407    // Create a new ResultItem for display
     408    //
     409    // Return true if successful, otherwise false.
     410
     411    boolean addDocumentTag( String line ) {
     412
     413    System.out.println( "addDocumentTag: " + line + " (" + expansionsRetrieved + ")");
     414
     415    String num = "", hash = "", freq = "", title = "";
     416    line = line.substring(9);
     417
     418    // Break the tag down into its component parts
     419    int nextSplit;
     420        while (line.length() > 0) {
     421        line = line.trim();
     422
     423        // Read the expansion number
     424        if (line.startsWith("num")) {
     425        line = line.substring(5);
     426        nextSplit = line.indexOf((int) '"');
     427        if (nextSplit >= 1) {
     428            num = line.substring(0, nextSplit);
     429            line = line.substring(nextSplit + 1);
     430        } else {
     431            System.err.println("ResultBox addExpansionTag: error parsing: " + line);
     432        }
     433        }
     434
     435        // Read the document OID hash
     436        else if (line.startsWith("hash")) {
     437        line = line.substring(6);
     438        nextSplit = line.indexOf((int) '"');
     439        if (nextSplit >= 1) {
     440            hash = line.substring(0, nextSplit);
     441            line = line.substring(nextSplit + 1);
     442        } else {
     443            System.err.println("ResultBox addExpansionTag: error parsing: " + line);
     444        }
     445        }
     446
     447        // Read the document frequency
     448        else if (line.startsWith("freq")) {
     449        line = line.substring(6);
     450        nextSplit = line.indexOf((int) '"');
     451        if (nextSplit >= 1) {
     452            freq = line.substring(0, nextSplit);
     453            line = line.substring(nextSplit + 1);
     454        } else {
     455            System.err.println("ResultBox addExpansionTag: error parsing: " + line);
     456        }
     457        }
     458
     459        // Read the title
     460        else if (line.startsWith("title")) {
     461        line = line.substring(7);
     462        nextSplit = line.indexOf((int) '"');
     463        if (nextSplit >= 1) {
     464            title = line.substring(0, nextSplit);
     465            line = line.substring(nextSplit + 1);
     466        } else {
     467            System.err.println("ResultBox addExpansionTag: error parsing: " + line);
     468        }
     469        }
     470    }
     471   
     472    // Create a new ResultItem and add it to the display
     473    ResultItem ri = new ResultItem(hash, title, freq);
     474   
     475    if (c.addResultItem(ri)) {
     476        documentsRetrieved++;
     477        return true;
     478    }
     479   
     480    return false;
     481    }
    299482}
    300483
     484
     485
     486
  • trunk/gsdl/src/phind/client/ResultItem.java

    r1621 r1625  
    1 // ResultItem.java
     1/**********************************************************************
     2 *
     3 * ResultBox.java -- a list of phrases in the Phind java interface
     4 *
     5 * Copyright 1997-2000 Gordon W. Paynter
     6 * Copyright 2000 The New Zealand Digital Library Project
     7 *
     8 * A component of the Greenstone digital library software
     9 * from the New Zealand Digital Library Project at the
     10 * University of Waikato, New Zealand.
     11 *
     12 * This program is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU General Public License as published by
     14 * the Free Software Foundation; either version 2 of the License, or
     15 * (at your option) any later version.
     16 *
     17 * This program is distributed in the hope that it will be useful,
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 * GNU General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU General Public License
     23 * along with this program; if not, write to the Free Software
     24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     25 *
     26 *********************************************************************/
    227
    3 /*
     28/*********************************************************************
    429
    5 A result item object holds the data describing a single line
    6 returned from a query to the server.  It therefore contains
    7 either information describing a phrase or a URL.
     30This class is used in the Phind java applet (Phind.java).
    831
    9 The ResultCanvas class maintains an array of ResultItems,
    10 and contains code to display them when it is appropriate to
    11 do so.
     32A result item object holds the data describing a single line returned from
     33a query to the server.  It therefore contains either information describing
     34a phrase or a URL.
    1235
    13 */
     36**********************************************************************/
     37
    1438
    1539public class ResultItem {
    1640
    17   // There are four kinds of item
    18   // 1. a phrase
    19   // 2. a document (or URL)
    20   // 3. a "get more phrases" marker
    21   // 4. a "get more documents" marker
    22   final static int phraseItem = 1;
    23   final static int morePhrases = 2;
    24   final static int documentItem = 3;
    25   final static int moreDocuments = 4;
     41    // There are four kinds of item
     42    // 1. a phrase
     43    // 2. a document (or URL)
     44    // 3. a "get more phrases" marker
     45    // 4. a "get more documents" marker
    2646
    27   // What kind is this item:
    28   int kind;
     47    final static int phraseItem = 1;
     48    final static int morePhrases = 2;
     49    final static int documentItem = 3;
     50    final static int moreDocuments = 4;
    2951
    30   // The symbol of this item as a string (rule) and integer
    31   String rule;
    32   int symbol;
     52    // What kind is this item:
     53    int kind;
    3354
    34   // The term frequency of the item
    35   int freq;
     55    // The symbol of this item as a string (rule) and integer
     56    String rule;
     57    int symbol;
    3658
    37   // The document frequency of the item
    38   int documents;
     59    // The term frequency of the item
     60    int freq;
    3961
    40   // Can this item be expanded?
    41   int expansion;
     62    // The document frequency of the item
     63    int documents;
    4264
    43   // The text of the item, split into a prefix, body, and suffix.
    44   // For phrases, the body is the search term and the prefix and suffix
    45   // the surrounding text in the new phrase.
    46   // For URLs the prefix and suffix are ignored.
    47   String prefix;
    48   String body;
    49   String suffix;
     65    // Can this item be expanded?  ---- obsolete?
     66    int expansion;
     67
     68    // The text of the item, split into a prefix, body, and suffix.
     69    // For phrases, the body is the search term and the prefix and suffix
     70    // the surrounding text in the new phrase.
     71    // For URLs the prefix and suffix are ignored.
     72    String prefix;
     73    String body;
     74    String suffix;
    5075
    5176
    52   // Create a ResultItem,
    53   // given all the relevant information as String objects.
    54   ResultItem(String r, String f, String e, String d,
    55          String p, String b, String s) {
     77    // Create a ResultItem for a phrase
     78    ResultItem(String r, String f, String d,
     79           String p, String b, String s) {
    5680
    57     rule = r;
    58     symbol = Integer.valueOf(rule).intValue();
    59     if (symbol < 10000000) {
    60       kind = phraseItem;
    61     } else {
    62       kind = documentItem;
     81    System.out.println("ResultItem (phrase): " + r + " (" + f + ", " + d + ")");
     82   
     83    kind = phraseItem;
     84    rule = r;
     85    symbol = Integer.valueOf(rule).intValue();
     86
     87    freq = Integer.valueOf(f).intValue();
     88    documents = Integer.valueOf(d).intValue();
     89    expansion = 0;
     90
     91    prefix = p;
     92    body = b;
     93    suffix = s;
    6394    }
    6495
    65     freq = Integer.valueOf(f).intValue();
    66     expansion = Integer.valueOf(e).intValue();
    67     documents = Integer.valueOf(d).intValue();
    6896
    69     prefix = p;
    70     body = b;
    71     suffix = s;
    72   }
     97    // Create a ResultItem for a document
     98    ResultItem(String hash, String title, String df) {
     99   
     100    System.out.println("ResultItem (document): " + hash + " (" + df + ")");
     101
     102    kind = documentItem;
     103    rule = hash;
     104    body = title;
     105    documents = Integer.valueOf(df).intValue();
     106   
     107    // not needed for a document
     108    symbol = 0;
     109    freq = 0;
     110    expansion = 0;
     111    prefix = "";
     112    suffix = "";
     113    }
    73114
    74115
    75   // Create a ResultItem,
    76   // given the kind and no other information
    77   ResultItem(int k, String r) {
     116    // Create an empty ResultItem of a given kind
     117    ResultItem(int k, String r) {
    78118
    79     kind = k;
     119    kind = k;
    80120
    81     rule = r;
    82     symbol = -1;
     121    rule = r;
     122    symbol = -1;
    83123
    84     freq = 0;
    85     expansion = 0;
    86     documents = 0;
     124    freq = 0;
     125    expansion = 0;
     126    documents = 0;
    87127
    88     prefix = "";
    89     body = "";
    90     suffix = "";
    91   }
     128    prefix = "";
     129    body = "";
     130    suffix = "";
     131    }
    92132
    93   // Return the full phrase described by the item.
    94   public String toString() {
    95     String result = "";
    96     if (!prefix.equals("")) result = prefix.replace(' ', '+') + "+";
    97     result += body.replace(' ', '+');
    98     if (!suffix.equals("")) result += "+" + suffix.replace(' ', '+');
    99     return(result.trim());
    100   }
     133    // Return the full phrase described by the item.
     134    public String toString() {
     135    String result = "";
     136    if (!prefix.equals("")) result = prefix.replace(' ', '+') + "+";
     137    result += body.replace(' ', '+');
     138    if (!suffix.equals("")) result += "+" + suffix.replace(' ', '+');
     139    return(result.trim());
     140    }
    101141
    102   // Is the item a phrase?
    103   public boolean isPhrase() {
    104     return (kind == phraseItem);
    105   }
     142    // Is the item a phrase?
     143    public boolean isPhrase() {
     144    return (kind == phraseItem);
     145    }
    106146
    107   // Is the item a document?
    108   public boolean isDocument() {
    109     return (kind == documentItem);
    110   }
     147    // Is the item a document?
     148    public boolean isDocument() {
     149    return (kind == documentItem);
     150    }
    111151
    112   public boolean isMorePhrases() {
    113     return (kind == morePhrases);
    114   }
     152    public boolean isMorePhrases() {
     153    return (kind == morePhrases);
     154    }
    115155
    116   public boolean isMoreDocuments() {
    117     return (kind == moreDocuments);
    118   }
     156    public boolean isMoreDocuments() {
     157    return (kind == moreDocuments);
     158    }
    119159
    120160
Note: See TracChangeset for help on using the changeset viewer.