The R Project SVN R

Rev

Rev 3765 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1230 leisch 1
/*==============================================================================
2
 
3
  Project: Simple JAVA Search Engine for Keyword Search
4
 
5
  JAVA Source file for the class SearchEngine
6
 
7
  COPYRIGHT (C), 1998, Thomas Baier
8
  ALL RIGHTS RESERVED.
9
 
10
  $Source: /scratch/CVS-ARCHIVE/R/doc/html/search/SearchEngine.java,v $
11
 
12
  $Revision: 1.1 $
13
 
14
  $Date: 1998/05/15 10:38:10 $
15
 
16
  $Author: leisch $
17
 
18
==============================================================================*/
19
 
20
 
21
/* -------------------------------- Imports --------------------------------- */
22
 
23
import java.applet.*;
24
import java.awt.*;
25
import java.net.*;
26
import java.io.*;
27
import java.util.*;
28
 
29
 
30
/*==============================================================================
31
                          Interface of class SearchEngine
32
==============================================================================*/
33
 
34
/*------------------------------------------------------------------------------
35
  CLASS:    SearchEngine
36
  SUPER:    Applet
37
  CONF. TO: 
38
  PURPOSE:  
39
  NOTES:    
40
 
41
  HISTORY:  98-04-26: created 
42
------------------------------------------------------------------------------*/
43
public class SearchEngine extends Applet
44
{
45
  /*============================================================================
46
                                Public methods
47
  ============================================================================*/
48
 
49
  /*----------------------------------------------------------------------------
50
    INTERFACE: 
51
    PURPOSE:   default constructor
52
 
53
    NOTES:     
54
 
55
    PARAMS:    
56
    THROWS:    
57
    RETURNS:   void
58
 
59
    HISTORY:   98-04-26: created
60
               98-05-03: now reads the index file
61
  ----------------------------------------------------------------------------*/
62
  public SearchEngine ()
63
  {
64
    iIndexTable = null;
65
    iSearchTerm = null;
66
 
67
    Tracer.write ("SearchEngine initializing\n");
68
 
69
    return;
70
  }
71
 
72
 
73
  /*----------------------------------------------------------------------------
74
    INTERFACE: 
75
    PURPOSE:   return general information about the applet
76
 
77
    NOTES:     
78
 
79
    PARAMS:    
80
    THROWS:    
81
    RETURNS:   String: the information
82
 
83
    HISTORY:   98-04-26: created
84
  ----------------------------------------------------------------------------*/
85
  public String getAppletInfo ()
86
  {
87
    return "Name: SearchEngine\r\n" +
88
      "Author: Thomas Baier\r\n" +
89
      "(C) 1998 Thomas Baier, ALL RIGHTS RESERVED";
90
  }
91
 
92
 
93
  /*----------------------------------------------------------------------------
94
    INTERFACE: 
95
    PURPOSE:   perform initialization
96
 
97
    NOTES:     creates the controls
98
 
99
    PARAMS:    
100
    THROWS:    
101
    RETURNS:   void
102
 
103
    HISTORY:   98-04-26: created
104
               98-05-03: now a do-nothing
105
  ----------------------------------------------------------------------------*/
106
  public void init ()
107
  {
108
    resize(640, 240);
109
 
110
    // get the name of the index file
111
    String indexName = getParameter (cIndexKeyword);
112
    String searchTerm = getParameter (cSearchKeyword);
113
 
114
    Tracer.write ("Index file is \"" + indexName + "\"\n");
115
    Tracer.write ("Search term is \"" + searchTerm + "\"\n");
116
 
117
    // use a default index file if none specified
118
    if (indexName == null) {
119
      indexName = cIndexFile;
120
    }
121
 
122
    iSearchTerm = searchTerm;
123
 
124
    /*
125
     * examine the URL to get the search term...
126
     *
127
     * if the URL ends with ?SEARCHTERM=xxxxx we know, xxxxx is the search term
128
     */
129
    {
130
      URL url = getDocumentBase ();
131
      String urlString = url.toString ();
132
      int index = urlString.indexOf ("?" + cSearchKeyword + "=");
133
 
134
      Tracer.write ("URL is \"" + urlString + "\"\n");
135
 
136
      // if found, take the rest as the search string
137
      if (index >= 0) {
138
	iSearchTerm =
139
	  urlString.substring (index + 2 + cSearchKeyword.length ());
140
	Tracer.write ("found search term \"" + iSearchTerm + "\" in URL\n");
141
      }
142
    }
143
 
144
    readIndexFile (indexName);
145
 
146
    return;
147
  }
148
 
149
 
150
  /*----------------------------------------------------------------------------
151
    INTERFACE: 
152
    PURPOSE:   perform "destructor" code
153
 
154
    NOTES:     not required here
155
 
156
    PARAMS:    
157
    THROWS:    
158
    RETURNS:   void
159
 
160
    HISTORY:   98-04-26: created
161
  ----------------------------------------------------------------------------*/
162
  public void destroy ()
163
  {
164
    return;
165
  }
166
 
167
 
168
  /*----------------------------------------------------------------------------
169
    INTERFACE: 
170
    PURPOSE:   perform painting of the applet
171
 
172
    NOTES:     not required for our applet, controls do everything
173
 
174
    PARAMS:    Graphics g: the graphics context to draw on
175
    THROWS:    
176
    RETURNS:   void
177
 
178
    HISTORY:   98-04-26: created
179
  ----------------------------------------------------------------------------*/
180
  public void paint (Graphics g)
181
  {
182
 
183
    return;
184
  }
185
 
186
 
187
  /*----------------------------------------------------------------------------
188
    INTERFACE: 
189
    PURPOSE:   perform startup code everytime visiting the applet
190
 
191
    NOTES:     
192
 
193
    PARAMS:    
194
    THROWS:    
195
    RETURNS:   void
196
 
197
    HISTORY:   98-04-26: created
198
               98-05-10: start the tracer
199
  ----------------------------------------------------------------------------*/
200
  public void start ()
201
  {
202
    Tracer.start ();
203
    return;
204
  }
205
 
206
 
207
  /*----------------------------------------------------------------------------
208
    INTERFACE: 
209
    PURPOSE:   perform cleanup evertime the applet "loses" the focus
210
 
211
    NOTES:     
212
 
213
    PARAMS:    
214
    THROWS:    
215
    RETURNS:   void
216
 
217
    HISTORY:   98-04-26: created
218
               98-05-10: stop the tracer
219
  ----------------------------------------------------------------------------*/
220
  public void stop ()
221
  {
222
    Tracer.stop ();
223
    return;
224
  }
225
 
226
 
227
  /*----------------------------------------------------------------------------
228
    INTERFACE: 
229
    PURPOSE:   perform the search and return the search results as a string
230
 
231
    NOTES:     
232
 
233
    PARAMS:    
234
    THROWS:    
235
    RETURNS:   void
236
 
237
    HISTORY:   98-05-03: created
238
               98-05-08: new format for output
239
	       98-05-09: added trace
240
	       98-05-10: now a front-end for search()
241
  ----------------------------------------------------------------------------*/
242
  public String search (String key)
243
  {
244
    iSearchTerm = key;
245
 
246
    return internalSearch ();
247
  }
248
 
249
 
250
  /*----------------------------------------------------------------------------
251
    INTERFACE: 
252
    PURPOSE:   perform the search (back-end)
253
 
254
    NOTES:     
255
 
256
    PARAMS:    
257
    THROWS:    
258
    RETURNS:   void
259
 
260
    HISTORY:   98-05-10: created
261
  ----------------------------------------------------------------------------*/
262
  public String internalSearch ()
263
  {
264
    Tracer.write ("Search for \"" + iSearchTerm + "\" started");
265
 
266
    Vector foundItems = null;
267
 
268
    if (iSearchTerm != null) {
269
      foundItems = iIndexTable.search (iSearchTerm);
270
    } else {
271
      foundItems = null;
272
    }
273
 
274
    String result = null;
275
 
276
    // if nothing found, return a special string
277
    if (foundItems == null) {
278
      result = "No matches for <b>\"" + 
279
	iSearchTerm +
280
	"\"</b> have been found!<hr>";
281
    } else {
282
      Enumeration cursor = foundItems.elements ();
283
 
284
      result =
285
	"The search string was <b>\"" +
286
	iSearchTerm +
287
	"<b>\"" +
288
	"<hr>" +
289
	"<dl>";
290
 
291
      while (cursor.hasMoreElements ()) {
292
	IndexEntry entry = (IndexEntry) cursor.nextElement ();
293
 
294
	/*
295
	 * the format for every entry is
296
	 *
297
	 * title
298
	 *   description
299
	 */
300
 
301
	result +=
302
	  "<dt><a href=\"" +
303
	  entry.getURL () +
304
	  "\">" +
305
	  entry.getTitle () +
306
	  "</a></dt>\n";
307
	result += "<dd>" + entry.getDescription () + "</dd>\n";
308
      }
309
 
310
      result += "</dl>";
311
    }
312
 
313
    return result;
314
  }
315
 
316
 
317
  /*============================================================================
318
                              Protected methods
319
  ============================================================================*/
320
 
321
  /*============================================================================
322
                               Private methods
323
  ============================================================================*/
324
 
325
  /*----------------------------------------------------------------------------
326
    INTERFACE: 
327
    PURPOSE:   read the index file
328
 
329
    NOTES:     
330
 
331
    PARAMS:    
332
    THROWS:    
333
    RETURNS:   void
334
 
335
    HISTORY:   98-04-26: created
336
               98-05-08: now use an IndexStream
337
	       98-05-10: also use prefix and suffix, build URL from first key
338
  ----------------------------------------------------------------------------*/
339
  private void readIndexFile (String idxFile)
340
  {
341
    // create the index table
342
    iIndexTable = new IndexTable ();
343
 
344
    URL baseURL = getCodeBase ();
345
 
346
    // get the index file and parse its contents
347
    try {
348
      URL idxFileURL = new URL (baseURL,idxFile);
349
 
350
      // get an IndexStream object for ease of parsing
351
      IndexStream idxStream = new IndexStream (idxFileURL);
352
 
353
      // now start parsing...
354
 
355
      /*
356
       * An entry consists of a title, keywords, an URL and a description.
357
       * everything else is ignored. Every entry starts with the keyword
358
       * "Entry" (case is ignored)
359
       *
360
       * must-have entries are "Entry" and "Keywords"
361
       */
362
      String entry = null;
363
      String keywords = null;
364
      String url = null;
365
      String description = "";
366
      String prefix = "";
367
      String suffix = "";
368
 
369
      Value value = idxStream.popEntry ();
370
 
371
      while (value != null) {
372
	// parse the value now
373
	if (value.getKey ().equalsIgnoreCase ("entry")) {
374
	  // if a new entry is about to start, add the current one
375
	  addEntry (entry,keywords,description,url,prefix,suffix);
376
 
377
	  entry = value.getValue ();
378
	  keywords = null;
379
	  url = null;
380
	  description = "";
381
	} else if (value.getKey ().equalsIgnoreCase ("keywords")) {
382
	  keywords = value.getValue ();
383
	} else if (value.getKey ().equalsIgnoreCase ("url")) {
384
	  // use prefix and suffix
385
	  url = prefix + value.getValue () + suffix;
386
	} else if (value.getKey ().equalsIgnoreCase ("description")) {
387
	  description = value.getValue ();
388
	} else if (value.getKey ().equalsIgnoreCase ("prefix")) {
389
	  prefix = value.getValue ();
390
	  Tracer.write ("using new URL prefix \"" + prefix + "\"\n");
391
	} else if (value.getKey ().equalsIgnoreCase ("suffix")) {
392
	  suffix = value.getValue ();
393
	  Tracer.write ("using new URL suffix \"" + suffix + "\"\n");
394
	}
395
	value = idxStream.popEntry ();
396
      }
397
 
398
      // the final entry just read
399
      addEntry (entry,keywords,description,url,prefix,suffix);
400
    } catch (MalformedURLException exc) {
401
      // an error occured while reading...
402
    }
403
 
404
    return;
405
  }
406
 
407
 
408
  /*----------------------------------------------------------------------------
409
    INTERFACE: 
410
    PURPOSE:   
411
 
412
    NOTES:     
413
 
414
    PARAMS:    
415
    THROWS:    
416
    RETURNS:   void
417
 
418
    HISTORY:   98-05-10: created
419
  ----------------------------------------------------------------------------*/
420
  private void addEntry (String entry,String keywords,
421
			 String description,String url,
422
			 String prefix,String suffix)
423
  {
424
    // the entry must be set
425
    if (entry == null) {
426
      return;
427
    }
428
 
429
    // the keywords must be set, else ignore it
430
    if (keywords != null) {
431
      if (url == null) {
432
	// if the URL is empty, construct one following the rule:
433
	// URL = prefix + first keyword + suffix
434
	int endOfFirstKeyword = keywords.indexOf (" ");
435
 
436
	// because we have trimmed the string, the first character must
437
	// not be a blank
438
	if (endOfFirstKeyword >= 0) {
439
	  url = keywords.substring (0,endOfFirstKeyword);
440
	  Tracer.write ("constructing URL, keywords=\"" +
441
			keywords + "\"" +
442
			"using \"" + 
443
			url +
444
			"\" (results in \"" +
445
			prefix + url + suffix + "\")\n");
446
	} else {
447
	  // just a single keyword
448
	  url = keywords;
449
	  Tracer.write ("constructing URL, using keyword \"" + 
450
			url +
451
			"\" (results in \"" +
452
			prefix + url + suffix + "\")\n");
453
	}
454
	// add prefix and suffix
455
	url = prefix + url + suffix;
456
      }
457
      IndexEntry idxEntry =
458
	new IndexEntry (entry,keywords,description,url);
459
      iIndexTable.addElement (idxEntry);
460
    }
461
 
462
    return;
463
  }
464
 
465
 
466
  /*============================================================================
467
                             Instance Variables
468
  ============================================================================*/
469
  private IndexTable iIndexTable;
470
  private String     iSearchTerm;
471
 
472
 
473
  /*============================================================================
474
                                Static Data
475
  ============================================================================*/
476
 
477
  private static final String cIndexFile = "index.txt";
478
  private static final String cIndexKeyword = "INDEXFILE";
479
  private static final String cSearchKeyword = "SEARCHTERM";
480
}
481
 
482
/*==============================================================================
483
 
484
  HISTORY:
485
 
486
  $Log: SearchEngine.java,v $
487
  Revision 1.1  1998/05/15 10:38:10  leisch
488
  New: Search Engine
489
 
490
  Revision 1.4  1998/05/10 22:56:53  baier
491
  internal search function, parameter expansion
492
 
493
  Revision 1.3  1998/05/10 02:44:32  baier
494
  traces, output in HTML via JavaScript, new index generation
495
 
496
  Revision 1.2  1998/04/26 22:36:34  baier
497
  documentation changes
498
 
499
 
500
 
501
  Revision 1.1  1998/04/26 21:32:54  baier
502
  Initial revision
503
 
504
 
505
==============================================================================*/
506
 
507
 
508
// Local Variables:
509
// mode: Java
510
// mode: font-lock
511
// End: