source: trunk/src/org/expeditee/greenstone/hcibibGUI.java@ 312

Last change on this file since 312 was 312, checked in by ra33, 16 years ago

Added search agents for HCI bib tec

File size: 20.6 KB
Line 
1package org.expeditee.greenstone;
2
3
4import java.awt.*;
5import java.awt.event.*;
6import java.util.Vector;
7import java.util.Collections;
8import java.util.Enumeration;
9import java.util.HashMap;
10import javax.swing.*;
11import javax.swing.event.*;
12import javax.swing.border.*;
13
14public class hcibibGUI implements ItemListener, ActionListener {
15
16 /* You should not need to modify this set of global variables */
17 JFrame mainFrame;
18 Greenstone3Connection gsdl;
19 JCheckBox stemmingCheck;
20 JCheckBox casefoldingCheck;
21 JTextField queryField;
22 JTextField docsToReturnField;
23 JComboBox indexComboBox;
24 JRadioButton homeButton;
25 JRadioButton waikatoButton;
26 JEditorPane resultPane;
27 boolean doCasefolding = true;
28 boolean doStemming = false;
29 boolean getAllMetadata = true;
30 int indexChoice = 1;
31 int locationChoice = 1;
32 String[] indexKeys = {"TX", "TI", "JO", "BO", "CR", "KE"};
33 Vector currentResultSet;
34 /* If you need to, you can introduce further globals to store useful data */
35 /**
36 * dateMap is a hash table. The keys are year values.
37 * the data associated with each key is a Vector of document IDs
38 * therefore, for the current result set you can get the set of years in which the
39 * results were published, and for each year you can get the set of documents published in that year
40 *
41 * If you want to introduce additional mappings (eg document written by authors) you should
42 * introduce additional structures here (HashMap used in the same way as dateMap will probably suffice
43 *
44 */
45 HashMap dateMap = new HashMap();
46
47 /* creates the result window which contains a menu and HTML renderer
48 * you will only need to modify this code to add more items to the View menu
49 * or add additional GUI components to the window (which isn't required for the assignment
50 * To change the initial window size modify the arguments to the setSize() call at end of this method
51 */
52 public void createAndShowResultGUI() {
53 JFrame resultFrame = new JFrame("Query results");
54 JPanel containerPanel = new JPanel();
55 JPanel controlPanel = new JPanel();
56 GridBagConstraints gbc = new GridBagConstraints();
57
58 containerPanel.setLayout(new GridBagLayout());
59 resultFrame.setContentPane(containerPanel);
60
61 containerPanel.setLayout(new GridBagLayout());
62 controlPanel.setLayout(new GridBagLayout());
63
64 JMenuBar menuBar = new JMenuBar();
65 JMenu viewMenu = new JMenu("View");
66 menuBar.add(viewMenu);
67
68
69
70
71 /* add items to the view menu. Insert code here to add more items */
72 JMenuItem viewByDate = new JMenuItem("View by Date");
73 viewByDate.addActionListener(this);
74 viewMenu.add(viewByDate);
75
76 JMenuItem viewByScore = new JMenuItem("View by Score");
77 viewByScore.addActionListener(this);
78 viewMenu.add(viewByScore);
79 /* end of menu item code */
80
81
82
83
84 resultFrame.setJMenuBar(menuBar);
85
86 resultPane = new JEditorPane();
87 resultPane.setContentType("text/html");
88 resultPane.setEditable(false);
89 resultPane.addHyperlinkListener(new HyperlinkListener() {
90
91 public void hyperlinkUpdate(HyperlinkEvent r) {
92 try {
93 if (r.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
94 handleLinkClick(r);
95 }
96 } catch (Exception e) {
97 }
98 }
99 });
100 resultPane.setText("Results will appear here");
101
102 gbc.gridx = 0;
103 gbc.gridy = 0;
104 gbc.weightx = 1.0;
105 gbc.weighty = 0.0;
106 gbc.anchor = GridBagConstraints.LINE_START;
107 gbc.fill = GridBagConstraints.HORIZONTAL;
108 containerPanel.add(controlPanel, gbc);
109
110 gbc.gridy = 1;
111 gbc.weighty = 1.0;
112 gbc.fill = GridBagConstraints.BOTH;
113 containerPanel.add(new JScrollPane(resultPane), gbc);
114
115 resultFrame.pack();
116 resultFrame.setSize(400, 600);
117 resultFrame.setVisible(true);
118 }
119
120 /* the argument to this method is the label of an item selected in the View menu
121 * based on the item selected from the menu the appropriate view method is called
122 * to handle additional view options add further else-if clauses
123 * you will need to implement any further viewByXXXX methods that you call
124 */
125 public void changeView(String menuLabel) {
126 if (menuLabel.compareTo("View by Date") == 0) {
127 viewByDate(dateMap);
128 } else if (menuLabel.compareTo("View by Score") == 0) {
129 viewByScore(currentResultSet);
130 }
131 }
132
133 /* this method is called when any link in the result window is clicked
134 * It expects the link URL to be of the form http://<metadata-tag>#<document-id>
135 * For example http://title#HASH01f33a09ebd2421ae5155b37s55
136 * indicates that the user has clicked on the title link for document with ID HASH01f33a09ebd2421ae5155b37s55
137 *
138 * This enables you to make the application respond to clicks within result items if you wish to modify
139 * the view based on such a user action
140 *
141 * Note that you need to construct these links in code that generates the HTML to be rendered in the result window
142 */
143 public void handleLinkClick(HyperlinkEvent r) {
144 String linkText = r.getURL().toString();
145 linkText = linkText.replaceAll("http://", "");
146 String parts[] = linkText.split("#");
147
148 ResultDocument rd = gsdl.getDocument(parts[1]);
149
150 StringBuffer HTMLcontent = new StringBuffer("<html><body>");
151 HTMLcontent.append("You clicked on the " + parts[0] + " of document " + parts[1] + "<br>");
152 HTMLcontent.append("Document title = " + rd.getTitle());
153 HTMLcontent.append("</body></html>");
154
155 resultPane.setText(HTMLcontent.toString());
156 }
157
158 /* given the Vector of result items (ordered by descending relevance to the query) this method
159 * iterates through them and constructs an HTML document and has it rendered in the result window
160 *
161 * This is the default presentation for results
162
163 * You can modify this method as you wish to change the HTML for the default presentation
164 *
165 * Some useful method calls are illustrated here
166 * - if you have the ID of a document you can get all data stored for it with
167 * ResultDocument rd = gsdl.getDocument(docID);
168 * - a ResultDocument object has a set of methods for getting metadata values for that document
169 * most metadata is a single value, but authors and keywords can have multiple values
170 * and these are stored in a Vector
171 *
172 * The IF condition for 'Title' shows how to construct a link that can be clicked on
173 * and then dealt with by the handleLinkClick() method
174 *
175 */
176 public void viewByScore(Vector results) {
177 StringBuffer resultHTML = new StringBuffer("<html><head>Results</head><body>");
178
179 for (Enumeration e = results.elements(); e.hasMoreElements();) {
180 Result result = (Result) e.nextElement();
181
182 String docID = result.getDocID();
183 int docRank = result.getRank();
184 String docScore = result.getScore();
185
186 ResultDocument rd = gsdl.getDocument(docID);
187
188 resultHTML.append("<p>");
189 resultHTML.append("docID = " + docID + "<br>");
190 resultHTML.append("docRank = " + docRank + " (for this query)<br>");
191 resultHTML.append("docScore = " + docScore + " (for this query)<br>");
192
193 if (rd.metadataExists("Title")) {
194 resultHTML.append("title = <a href='http://title#" + docID + "'>" + rd.getTitle() + "</a><br>");
195 }
196 if (rd.metadataExists("Date")) {
197 resultHTML.append("date = " + rd.getDate() + "<br>");
198 }
199 if (rd.metadataExists("Booktitle")) {
200 resultHTML.append("booktitle = " + rd.getBooktitle() + "<br>");
201 }
202 if (rd.metadataExists("Pages")) {
203 resultHTML.append("pages = " + rd.getPages() + "<br>");
204 }
205 if (rd.metadataExists("Journal")) {
206 resultHTML.append("journal = " + rd.getJournal() + "<br>");
207 }
208 if (rd.metadataExists("Volume")) {
209 resultHTML.append("volume = " + rd.getVolume() + "<br>");
210 }
211 if (rd.metadataExists("Number")) {
212 resultHTML.append("number = " + rd.getNumber() + "<br>");
213 }
214 if (rd.metadataExists("Editor")) {
215 resultHTML.append("editor = " + rd.getEditor() + "<br>");
216 }
217 if (rd.metadataExists("Publisher")) {
218 resultHTML.append("publisher = " + rd.getPublisher() + "<br>");
219 }
220 if (rd.metadataExists("Abstract")) {
221 resultHTML.append("abstract = " + rd.getAbstract() + "<br>");
222 }
223 Vector authors = rd.getAuthors();
224 for (Enumeration a = authors.elements(); a.hasMoreElements();) {
225 String author = (String) a.nextElement();
226 resultHTML.append("author = " + author + "<br>");
227 }
228 Vector keywords = rd.getKeywords();
229 for (Enumeration k = keywords.elements(); k.hasMoreElements();) {
230 String keyword = (String) k.nextElement();
231 resultHTML.append("keyword = " + keyword + "<br>");
232 }
233 resultHTML.append("</p>");
234 }
235 resultHTML.append("</body></html>");
236
237 resultPane.setText(resultHTML.toString());
238 resultPane.setCaretPosition(0);
239 }
240
241 /* This method provides an alternative view of the result set
242 * It uses the dateMap which organises results according to the year in which they were published
243 *
244 * You will need to write a similar method for any additional view that you implement
245 *
246 * You may wish to modify this method to provide a better layout of the output
247 */
248 public void viewByDate(HashMap dateMap) {
249 StringBuffer resultHTML = new StringBuffer("<html><head>Results</head><body>");
250
251 Vector theDates = new Vector(dateMap.keySet());
252 Collections.sort(theDates);
253
254
255 for (Enumeration e = theDates.elements(); e.hasMoreElements();) {
256 String date = (String) e.nextElement();
257 Vector ids = (Vector) dateMap.get(date);
258
259 resultHTML.append("<p>");
260 resultHTML.append("<b>" + date + "</b><br>");
261
262 for (Enumeration i = ids.elements(); i.hasMoreElements();) {
263 String docID = (String) i.nextElement();
264 ResultDocument rd = gsdl.getDocument(docID);
265 resultHTML.append(rd.getTitle() + "<br>");
266 }
267
268 resultHTML.append("</p>");
269 }
270
271 resultHTML.append("</body></html>");
272
273 resultPane.setText(resultHTML.toString());
274 resultPane.setCaretPosition(0);
275 }
276
277 /* this method is called whenever the user presses the RETURN key in the query box
278 *
279 * it first deletes any date->document mappings from the previous query by clearing the dateMap hashtable
280 * if you introduce further mapping structures you will need to clear them here
281 *
282 * a query object is created using the settings in the query window and the query request is
283 * sent to the Greenstone server, which responds with the outcome of the query
284 * the metadata for each result document is then retrieved from the server
285 *
286 * The dateMap hashtable is then initialised
287 *
288 * If you wished to group documents by author you would
289 * - introduce a new HashMap (probably called authorMap )
290 * - write a method called initialiseAuthorMap modelled on initialiseDateMap
291 * which uses a method addToAuthorMap which would be modelled on addToDateMap
292 * - call initialiseDateMap in this method
293 * - write a viewByAuthor method
294 *
295 * the viewByScore method is called to display the default result output
296 * you can change the view method which is called if you wish to
297 */
298 public void doQuery(String queryText) {
299
300 dateMap.clear();
301
302 Query query = createQuery(queryText);
303 QueryOutcome queryOutcome = gsdl.issueQueryToServer(query);
304 currentResultSet = getResultSetMetadata(queryOutcome);
305
306 initialiseDateMap(currentResultSet);
307
308 viewByScore(currentResultSet);
309 }
310
311 /************** YOU SHOULD NOT NEED TO MODIFY ANYTHING PAST THIS POINT *************/
312 public static void main(String[] args) {
313 hcibibGUI gui = new hcibibGUI();
314 }
315
316 public hcibibGUI() {
317 gsdl = new Greenstone3Connection(locationChoice);
318 createAndShowMainGUI();
319 createAndShowResultGUI();
320 }
321
322 public void createAndShowMainGUI() {
323 JPanel containerPanel = new JPanel();
324 JPanel locationPanel = new JPanel();
325 JPanel optionPanel = new JPanel();
326 JPanel queryPanel = new JPanel();
327 GridBagConstraints gbc = new GridBagConstraints();
328
329
330 mainFrame = new JFrame("GUI for Greenstone 3 HCI Bibliography Collection");
331 containerPanel.setLayout(new GridBagLayout());
332 mainFrame.setContentPane(containerPanel);
333
334 locationPanel.setLayout(new GridBagLayout());
335 optionPanel.setLayout(new GridBagLayout());
336 queryPanel.setLayout(new GridBagLayout());
337
338 TitledBorder title;
339 title = BorderFactory.createTitledBorder("Where am I?");
340 locationPanel.setBorder(title);
341 title = BorderFactory.createTitledBorder("Query options");
342 optionPanel.setBorder(title);
343 title = BorderFactory.createTitledBorder("Query");
344 queryPanel.setBorder(title);
345
346 ButtonGroup locationGroup = new ButtonGroup();
347 homeButton = new JRadioButton("home");
348 waikatoButton = new JRadioButton("CS labs");
349 homeButton.addActionListener(this);
350 waikatoButton.addActionListener(this);
351 homeButton.setSelected(true);
352 locationGroup.add(homeButton);
353 locationGroup.add(waikatoButton);
354
355 gbc.gridx = 0;
356 gbc.gridy = 0;
357 gbc.anchor = GridBagConstraints.LINE_START;
358 locationPanel.add(homeButton, gbc);
359 gbc.gridx = 1;
360 gbc.gridy = 0;
361 gbc.anchor = GridBagConstraints.LINE_START;
362 locationPanel.add(waikatoButton, gbc);
363
364 stemmingCheck = new JCheckBox("Stemming");
365 stemmingCheck.setSelected(doStemming);
366 stemmingCheck.addItemListener(this);
367 gbc.gridx = 0;
368 gbc.gridy = 0;
369 gbc.anchor = GridBagConstraints.LINE_START;
370 optionPanel.add(stemmingCheck, gbc);
371
372 casefoldingCheck = new JCheckBox("Casefolding");
373 casefoldingCheck.setSelected(doCasefolding);
374 casefoldingCheck.addItemListener(this);
375 gbc.gridx = 0;
376 gbc.gridy = 1;
377 gbc.anchor = GridBagConstraints.LINE_START;
378 optionPanel.add(casefoldingCheck, gbc);
379
380 JLabel docsToReturnLabel = new JLabel("Max results");
381 gbc.gridx = 1;
382 gbc.gridy = 0;
383 gbc.anchor = GridBagConstraints.LINE_END;
384 optionPanel.add(docsToReturnLabel, gbc);
385
386 docsToReturnField = new JTextField(3);
387 docsToReturnField.setText("10");
388 gbc.gridx = 2;
389 gbc.gridy = 0;
390 gbc.anchor = GridBagConstraints.LINE_START;
391 optionPanel.add(docsToReturnField, gbc);
392
393 JLabel indexLabel = new JLabel("Search in...");
394 gbc.gridx = 0;
395 gbc.gridy = 2;
396 gbc.anchor = GridBagConstraints.LINE_START;
397 optionPanel.add(indexLabel, gbc);
398
399 String[] indexStrings = {"all fields", "document titles", "journal names",
400 "book/conference names", "authors", "keywords"
401 };
402 indexComboBox = new JComboBox(indexStrings);
403 indexComboBox.setSelectedIndex(1);
404 indexComboBox.addActionListener(this);
405 gbc.gridx = 0;
406 gbc.gridy = 3;
407 optionPanel.add(indexComboBox, gbc);
408
409 queryField = new JTextField(30);
410 queryField.addActionListener(new MyActionListener());
411 gbc.gridx = 0;
412 gbc.gridy = 0;
413 gbc.anchor = GridBagConstraints.LINE_START;
414 gbc.fill = GridBagConstraints.HORIZONTAL;
415 queryPanel.add(queryField, gbc);
416
417 gbc.gridx = 0;
418 gbc.gridy = 0;
419 gbc.weightx = 1.0;
420 gbc.weighty = 0.0;
421 gbc.anchor = GridBagConstraints.LINE_START;
422 gbc.fill = GridBagConstraints.HORIZONTAL;
423 containerPanel.add(locationPanel, gbc);
424 gbc.gridy = 1;
425 containerPanel.add(optionPanel, gbc);
426 gbc.gridy = 2;
427 containerPanel.add(queryPanel, gbc);
428
429 mainFrame.pack();
430 mainFrame.setVisible(true);
431 }
432
433 public Query createQuery(String queryText) {
434
435 Query query = new Query();
436
437 // set the query options
438 query.setQueryText(queryText);
439
440 query.setIndex(indexKeys[indexChoice]);
441
442 String docsToReturn = docsToReturnField.getText();
443 if (docsToReturn.compareTo("") == 0) {
444 docsToReturn = "10";
445 }
446 query.setMaxDocsToReturn(docsToReturn);
447
448 if (doStemming) {
449 query.setStemming("1");
450 } else {
451 query.setStemming("0");
452 }
453
454 if (doCasefolding) {
455 query.setCasefolding("1");
456 } else {
457 query.setCasefolding("0");
458 }
459
460 return query;
461 }
462
463 private void getResultMetadata(Result result) {
464 String docID = result.getDocID();
465
466 gsdl.getDocumentMetadataFromServer(docID, "Title");
467 gsdl.getDocumentMetadataFromServer(docID, "Date");
468
469 if (getAllMetadata) {
470 gsdl.getDocumentMetadataFromServer(docID, "Date");
471 gsdl.getDocumentMetadataFromServer(docID, "Booktitle");
472 gsdl.getDocumentMetadataFromServer(docID, "Journal");
473 gsdl.getDocumentMetadataFromServer(docID, "Creator");
474 gsdl.getDocumentMetadataFromServer(docID, "Keywords");
475 gsdl.getDocumentMetadataFromServer(docID, "Publisher");
476 gsdl.getDocumentMetadataFromServer(docID, "Abstract");
477 gsdl.getDocumentMetadataFromServer(docID, "Pages");
478 gsdl.getDocumentMetadataFromServer(docID, "Number");
479 gsdl.getDocumentMetadataFromServer(docID, "Volume");
480 }
481
482 }
483
484 public Vector getResultSetMetadata(QueryOutcome queryOutcome) {
485
486 Vector results = queryOutcome.getResults();
487 for (Enumeration e = results.elements(); e.hasMoreElements();) {
488 Result result = (Result) e.nextElement();
489 getResultMetadata(result);
490 }
491 return results;
492 }
493
494 public void initialiseDateMap(Vector results) {
495 for (Enumeration e = results.elements(); e.hasMoreElements();) {
496 Result result = (Result) e.nextElement();
497
498 String docID = result.getDocID();
499
500 ResultDocument rd = gsdl.getDocument(docID);
501
502 if (rd.metadataExists("Date")) {
503 addToDateMap(docID, rd);
504 }
505 }
506 }
507
508 public void addToDateMap(String docID, ResultDocument rd) {
509 if (dateMap.containsKey(rd.getDate())) {
510 Vector dateVector = (Vector) dateMap.get(rd.getDate());
511 if (!dateVector.contains(docID)) {
512 dateVector.addElement(docID);
513 }
514 dateMap.put(rd.getDate(), dateVector);
515 } else {
516 Vector dateVector = new Vector();
517 dateVector.addElement(docID);
518 dateMap.put(rd.getDate(), dateVector);
519 }
520 }
521
522 public void itemStateChanged(ItemEvent e) {
523 Object sourceItem = e.getItemSelectable();
524
525 if (sourceItem == stemmingCheck) {
526 doStemming = !doStemming;
527 } else if (sourceItem == casefoldingCheck) {
528 doCasefolding = !doCasefolding;
529 }
530 }
531
532 public void actionPerformed(ActionEvent e) {
533 Object sourceItem = e.getSource();
534
535 if (sourceItem == indexComboBox) {
536 indexChoice = indexComboBox.getSelectedIndex();
537 } else if (sourceItem == homeButton || sourceItem == waikatoButton) {
538 if (homeButton.isSelected()) {
539 locationChoice = 1;
540 } else {
541 locationChoice = 0;
542 }
543 gsdl = new Greenstone3Connection(locationChoice);
544 } else if (sourceItem.getClass().getName().compareTo("javax.swing.JMenuItem") == 0) {
545 String menuLabel = ((JMenuItem) sourceItem).getText();
546 changeView(menuLabel);
547 }
548 }
549
550 class MyActionListener implements ActionListener {
551
552 public void actionPerformed(ActionEvent evt) {
553 String queryText = queryField.getText();
554 doQuery(queryText);
555 }
556 }
557}
558
559
Note: See TracBrowser for help on using the repository browser.