1 | /**
|
---|
2 | *#########################################################################
|
---|
3 | * GS3JavaClient.java - part of the demo-client for Greenstone 3, of the
|
---|
4 | * Greenstone digital library suite from the New Zealand Digital Library
|
---|
5 | * Project at the * University of Waikato, New Zealand.
|
---|
6 | * <BR><BR>
|
---|
7 | * Copyright (C) 2008 New Zealand Digital Library Project
|
---|
8 | * <BR><BR>
|
---|
9 | * This program is free software; you can redistribute it and/or modify
|
---|
10 | * it under the terms of the GNU General Public License as published by
|
---|
11 | * the Free Software Foundation; either version 2 of the License, or
|
---|
12 | * (at your option) any later version.
|
---|
13 | * <BR><BR>
|
---|
14 | * This program is distributed in the hope that it will be useful,
|
---|
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
17 | * GNU General Public License for more details.
|
---|
18 | *########################################################################
|
---|
19 | */
|
---|
20 |
|
---|
21 | package org.greenstone.gs3client;
|
---|
22 |
|
---|
23 | //By importing this *static* inner class of CollectionData, can refer
|
---|
24 | //to it by its unqualified name 'ServiceData'. (Learnt this from
|
---|
25 | //http://today.java.net/pub/a/today/2006/03/23/multi-split-pane.html)
|
---|
26 | import org.apache.log4j.Logger;
|
---|
27 | import org.apache.log4j.PropertyConfigurator;
|
---|
28 | import org.greenstone.gs3client.BrowseDisplay.ClassifierData;
|
---|
29 |
|
---|
30 | import org.greenstone.gs3client.data.BrowseResponseData;
|
---|
31 | import org.greenstone.gs3client.data.CollectionData;
|
---|
32 | import org.greenstone.gs3client.data.DocumentNodeData;
|
---|
33 | import org.greenstone.gs3client.data.ClassifierNodeData;
|
---|
34 | import org.greenstone.gs3client.data.NodeData;
|
---|
35 | import org.greenstone.gs3client.data.ParseUtil;
|
---|
36 | import org.greenstone.gs3client.data.QueryResponseData;
|
---|
37 | import org.greenstone.gs3client.data.ResponseData;
|
---|
38 | import org.greenstone.gs3client.data.CollectionData.ServiceData;
|
---|
39 | import org.greenstone.gs3client.dlservices.DigitalLibraryServicesAPIA;
|
---|
40 | import org.greenstone.gs3client.dlservices.FedoraServicesAPIA;
|
---|
41 | import org.greenstone.gs3client.dlservices.GS3ServicesAPIA;
|
---|
42 |
|
---|
43 | import javax.swing.*;
|
---|
44 | import java.awt.BorderLayout;
|
---|
45 | import java.awt.GridLayout;
|
---|
46 | import java.awt.FlowLayout;
|
---|
47 | import java.awt.event.ActionListener;
|
---|
48 | import java.awt.event.ActionEvent;
|
---|
49 | import java.awt.Container;
|
---|
50 | import java.awt.Toolkit; // for making this JFrame client fullsize
|
---|
51 |
|
---|
52 | import java.net.Authenticator;
|
---|
53 | import java.net.PasswordAuthentication;
|
---|
54 |
|
---|
55 | import org.w3c.dom.Document;
|
---|
56 | import org.w3c.dom.Element;
|
---|
57 | import org.w3c.dom.NodeList;
|
---|
58 |
|
---|
59 | import java.util.Vector;
|
---|
60 | import java.util.HashMap;
|
---|
61 |
|
---|
62 | import java.io.StringReader;
|
---|
63 | import javax.xml.parsers.DocumentBuilderFactory;
|
---|
64 | import javax.xml.parsers.DocumentBuilder;
|
---|
65 | import org.xml.sax.InputSource;
|
---|
66 |
|
---|
67 | import org.greenstone.gsdl3.util.GSXML;
|
---|
68 | import java.awt.Cursor;
|
---|
69 |
|
---|
70 | /*
|
---|
71 | To make this class compile with Java 5/Java 1.5 need to rename the file
|
---|
72 | xalan.jar.tmp (located in $GS3_HOME/web/WEB-INF/lib) to xalan.jar
|
---|
73 | Without doing that, it will complain (unless compiled with Java 1.4.2).
|
---|
74 |
|
---|
75 | RUNTIME Configuration of this class:
|
---|
76 | - this client needs the jar files:
|
---|
77 | log4j, xercesImpl, mail, lucene, javagdbm,
|
---|
78 | And possibly: xml-apis, activation, axis, mg, mgpp
|
---|
79 | - VM arguments: -Djava.library.path=/research/ak19/greenstone3/lib/jni
|
---|
80 |
|
---|
81 | COMPILE Configuration of this class:
|
---|
82 | - BUILD PATH needs the jar files:
|
---|
83 | gsdl3 (or just the class GSXML), jaxrpc, axis
|
---|
84 | */
|
---|
85 | /**
|
---|
86 | * The main Javaclient class. Creates the main window containing:
|
---|
87 | * - the radio button group for making either Greenstone 3 or Fedora the active DL.
|
---|
88 | * - the comboboxes for selecting the collection and the service therein
|
---|
89 | * - three panes - for executing queries, viewing search results and browsing.
|
---|
90 | * @author ak19
|
---|
91 | */
|
---|
92 | public class GS3JavaClient extends JFrame implements ActionListener {
|
---|
93 | // static final long serialVersionUID = 1; //eclipse keeps warning
|
---|
94 | /** The Logger for this class */
|
---|
95 | static Logger LOG = Logger.getLogger(GS3JavaClient.class);
|
---|
96 |
|
---|
97 | /** The value of the SEARCHING activity */
|
---|
98 | public static int SEARCHING = 0;
|
---|
99 | /** The value of the BROWSING activity */
|
---|
100 | public static int BROWSING = 1;
|
---|
101 | /** we want to display a drop-down box for the services available,
|
---|
102 | * but only Services that can be executed (searching and browsing) */
|
---|
103 | protected static final boolean executableServicesOnly = true;
|
---|
104 |
|
---|
105 | /** To keep track of whether we are searching or browsing.
|
---|
106 | * Value of activity can be SEARCHING OR BROWSING */
|
---|
107 | protected int activity = 0; //
|
---|
108 |
|
---|
109 | /** Reference to a digital library instance (Greenstone 3 or Fedora) that
|
---|
110 | * allows this client to execute services offered by the digital library */
|
---|
111 | protected DigitalLibraryServicesAPIA dlAPIA = null;
|
---|
112 | /** Reference to the object that interacts with Greenstone3's web services */
|
---|
113 | protected GS3ServicesAPIA greenstoneDL = null;
|
---|
114 | /** Reference to the object that interacts with the FedoraGS3.jar component */
|
---|
115 | protected FedoraServicesAPIA fedoraDL = null;
|
---|
116 |
|
---|
117 | /** Object that stores the data of a query response XML message */
|
---|
118 | protected QueryResponseData queryResponseObj = null;
|
---|
119 |
|
---|
120 | /** Object that stores the data of a browse response XML message
|
---|
121 | * (response for classification hierarchies) */
|
---|
122 | protected BrowseResponseData browseResponseObject = null;
|
---|
123 |
|
---|
124 | /** Preferred language of display items in responses.
|
---|
125 | * "" or "en" for English */
|
---|
126 | protected String lang = "";
|
---|
127 |
|
---|
128 | /** The currently selected collection */
|
---|
129 | protected String colName = "";
|
---|
130 | /** The currently selected service */
|
---|
131 | protected String serviceName = "";
|
---|
132 |
|
---|
133 | /* The always-visible GUI objects of this main window */
|
---|
134 | protected JComboBox dlChooser = null;
|
---|
135 | protected JTextField proxyhostField = null;
|
---|
136 | protected JTextField proxyportField = null;
|
---|
137 | protected JTextField nonProxyHostNamesField = null;
|
---|
138 | protected JButton setProxySettings = null;
|
---|
139 |
|
---|
140 | protected JComboBox serviceBox = null;
|
---|
141 | protected JComboBox collBox = null;
|
---|
142 | protected JButton collInfoButton = null;
|
---|
143 | protected JButton searchButton = null;
|
---|
144 | protected JTabbedPane tabbedPane = null;
|
---|
145 |
|
---|
146 | protected static final int SELECT = 0;
|
---|
147 | protected static final int GREENSTONE = 1;
|
---|
148 | protected static final int FEDORA = 2;
|
---|
149 | protected static final String[] dlOptions = {"select", "greenstone", "fedora"};
|
---|
150 |
|
---|
151 | /* Components of the query tab */
|
---|
152 | protected QueryForm queryPanel = null;
|
---|
153 | protected JTextField collectionNameField = null;
|
---|
154 |
|
---|
155 | /* Components of the search tab */
|
---|
156 | protected SearchResultsDisplay searchResultsDisplay = null;
|
---|
157 | protected JPanel searchPanel = null;
|
---|
158 | protected JTextArea searchSummary = null;
|
---|
159 |
|
---|
160 | /* Components of the browse tab */
|
---|
161 | protected BrowseDisplay browsePanel = null;
|
---|
162 |
|
---|
163 | /** @return the language of the display items */
|
---|
164 | public String getLanguage() { return lang; }
|
---|
165 | /** Set the preferred language of the display items
|
---|
166 | * @param lang - the preferred language for display values */
|
---|
167 | public void setLanguage(String lang) { this.lang = lang; }
|
---|
168 |
|
---|
169 | /** Inner class that handles authentication for any sites (urls, etc.)
|
---|
170 | * that require it. A dialog pops up to request username and password
|
---|
171 | * details from the user for each site's realm that needs authentication.
|
---|
172 | */
|
---|
173 | static class PasswordAuthenticator extends Authenticator {
|
---|
174 | protected PasswordAuthentication getPasswordAuthentication() {
|
---|
175 | JTextField username = new JTextField();
|
---|
176 | JTextField password = new JPasswordField();
|
---|
177 | JPanel panel = new JPanel(new GridLayout(2,2));
|
---|
178 | panel.add(new JLabel("User Name"));
|
---|
179 | panel.add(username);
|
---|
180 | panel.add(new JLabel("Password") );
|
---|
181 | panel.add(password);
|
---|
182 | int option = JOptionPane.showConfirmDialog(null, new Object[] {
|
---|
183 | "Site: "+getRequestingHost(),
|
---|
184 | "Realm: "+getRequestingPrompt(), panel},
|
---|
185 | "Enter Network Password",
|
---|
186 | JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
|
---|
187 | if ( option == JOptionPane.OK_OPTION ) {
|
---|
188 | return new PasswordAuthentication(
|
---|
189 | username.getText(), password.getText().toCharArray());
|
---|
190 | } else {
|
---|
191 | return null;
|
---|
192 | }
|
---|
193 | }
|
---|
194 | }
|
---|
195 |
|
---|
196 | /** Default constructor that creates and initialises this main
|
---|
197 | * window and its internal GUI components */
|
---|
198 | public GS3JavaClient() {
|
---|
199 | super();
|
---|
200 | this.setTitle("Greenstone 3 web services demo-client");
|
---|
201 |
|
---|
202 | // digital library panel lets the user choose the digital library
|
---|
203 | // repository to access and to set the proxy settings
|
---|
204 | JPanel dlPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
---|
205 | dlChooser = new JComboBox(dlOptions);
|
---|
206 | dlPanel.add(new JLabel("Use digital library:"));
|
---|
207 | dlPanel.add(dlChooser);
|
---|
208 | dlChooser.addActionListener(this);
|
---|
209 | dlPanel.setBorder(BorderFactory.createTitledBorder(
|
---|
210 | "Digital library settings"));
|
---|
211 |
|
---|
212 | this.proxyhostField = new JTextField(15);
|
---|
213 | this.proxyportField = new JTextField(4);
|
---|
214 | this.nonProxyHostNamesField = new JTextField(20);
|
---|
215 | this.setProxySettings = new JButton("Set");
|
---|
216 | nonProxyHostNamesField.setToolTipText("The hosts for which no proxies are required "
|
---|
217 | + "(separate hosts with |, * wildcard allowed)");
|
---|
218 | JPanel topProxyPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
---|
219 | topProxyPanel.add(new JLabel("Proxy host:"));
|
---|
220 | topProxyPanel.add(proxyhostField);
|
---|
221 | topProxyPanel.add(new JLabel("Proxy port:"));
|
---|
222 | topProxyPanel.add(proxyportField);
|
---|
223 | JPanel bottomProxyPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
---|
224 | bottomProxyPanel.add(new JLabel("No proxy for:"));
|
---|
225 | bottomProxyPanel.add(nonProxyHostNamesField);
|
---|
226 | bottomProxyPanel.add(setProxySettings);
|
---|
227 | setProxySettings.addActionListener(this);
|
---|
228 | JPanel proxyPanel = new JPanel(new BorderLayout());
|
---|
229 | proxyPanel.add(topProxyPanel, BorderLayout.CENTER);
|
---|
230 | proxyPanel.add(bottomProxyPanel, BorderLayout.SOUTH);
|
---|
231 | proxyPanel.setBorder(BorderFactory.createTitledBorder(
|
---|
232 | "Connection settings"));
|
---|
233 |
|
---|
234 | // Add the dlPanel and proxyPanel next to each other at the top
|
---|
235 | JPanel topPanel = new JPanel(new BorderLayout());
|
---|
236 | topPanel.add(dlPanel, BorderLayout.CENTER);
|
---|
237 | topPanel.add(proxyPanel, BorderLayout.EAST);
|
---|
238 |
|
---|
239 | // Setting up the GUI of this client
|
---|
240 | // create a JComboBox, and an item in it for each collection
|
---|
241 | collBox = new JComboBox();
|
---|
242 | serviceBox = new JComboBox();
|
---|
243 |
|
---|
244 | JPanel collPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
---|
245 | collPanel.add(new JLabel("Choose collection:"));
|
---|
246 | collPanel.add(collBox);
|
---|
247 | // displayName
|
---|
248 | collPanel.add(new JLabel("Full name:"));
|
---|
249 | collectionNameField = new JTextField(18);
|
---|
250 | collectionNameField.setEditable(false);
|
---|
251 | collectionNameField.setCaretPosition(0);
|
---|
252 | collPanel.add(collectionNameField);
|
---|
253 | // detailed information button, shows collection's description
|
---|
254 | collInfoButton = new JButton("Info");
|
---|
255 | collInfoButton.addActionListener(this);
|
---|
256 | collPanel.add(collInfoButton);
|
---|
257 |
|
---|
258 | JPanel servicePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
---|
259 | servicePanel.add(new JLabel("Available services:"));
|
---|
260 | servicePanel.add(serviceBox);
|
---|
261 |
|
---|
262 | JPanel collServicesPanel = new JPanel(new BorderLayout());
|
---|
263 | collServicesPanel.add(collPanel, BorderLayout.NORTH);
|
---|
264 | collServicesPanel.add(servicePanel, BorderLayout.SOUTH);
|
---|
265 |
|
---|
266 | tabbedPane = new JTabbedPane(); // tabs on top
|
---|
267 | queryPanel = new QueryForm(this);
|
---|
268 | tabbedPane.add("Query", queryPanel);
|
---|
269 | searchResultsDisplay = new SearchResultsDisplay(this);
|
---|
270 | searchResultsDisplay.setOpaque(true); //necessary for JTree
|
---|
271 |
|
---|
272 | JScrollPane searchView = new JScrollPane(searchResultsDisplay);
|
---|
273 | searchSummary = new JTextArea();
|
---|
274 | searchSummary.setEditable(false);
|
---|
275 |
|
---|
276 | searchPanel = new JPanel(new BorderLayout());
|
---|
277 | searchPanel.add(searchView, BorderLayout.CENTER);
|
---|
278 | searchPanel.add(searchSummary, BorderLayout.NORTH);
|
---|
279 | tabbedPane.add("Search Results", searchPanel);
|
---|
280 |
|
---|
281 | JPanel activityPanel = new JPanel(new BorderLayout());
|
---|
282 | activityPanel.add(collServicesPanel, BorderLayout.NORTH);
|
---|
283 | activityPanel.add(tabbedPane, BorderLayout.CENTER);
|
---|
284 |
|
---|
285 | Container c = this.getContentPane();
|
---|
286 | c.setLayout(new BorderLayout()); // new BoxLayout(c, BoxLayout.Y_AXIS));
|
---|
287 | c.add(topPanel, BorderLayout.NORTH);
|
---|
288 | c.add(activityPanel, BorderLayout.CENTER);
|
---|
289 |
|
---|
290 | // browse panel
|
---|
291 | browsePanel = new BrowseDisplay(this);
|
---|
292 | tabbedPane.add("Browse", browsePanel);
|
---|
293 |
|
---|
294 | // add actionlisteners
|
---|
295 | collBox.addActionListener(this);
|
---|
296 | serviceBox.addActionListener(this);
|
---|
297 |
|
---|
298 | // GUI DONE, now instantiate the DATA and DIGITAL LIBRARY objects
|
---|
299 | // instantiate the objects that deal with storing query response data
|
---|
300 | // and browse response data
|
---|
301 | queryResponseObj = new QueryResponseData();
|
---|
302 | browseResponseObject = new BrowseResponseData();
|
---|
303 |
|
---|
304 | // The java.net.Authenticator can be used to send user credentials
|
---|
305 | // when needed. When no username/password are provided then a popup
|
---|
306 | // is shown to ask for the credentials. *Only* when a site/realm
|
---|
307 | // requires password and username does the Authenticator show the
|
---|
308 | // dialog. For example, the dialog will appear when pwd & username
|
---|
309 | // are needed for proxy authorisation.
|
---|
310 | Authenticator.setDefault(new PasswordAuthenticator());
|
---|
311 |
|
---|
312 | changeDL(null); // no dl selected
|
---|
313 |
|
---|
314 | // Set the selection colours that will be uniform for all DLs
|
---|
315 | UIManager.put("Tree.textBackground", ColourCombo.transparent);
|
---|
316 | // Instead of the white tree text background, set it to transparent
|
---|
317 | UIManager.put("Tree.selectionBackground", ColourCombo.yellow);
|
---|
318 | UIManager.put("TabbedPane.selected", ColourCombo.yellow);
|
---|
319 | UIManager.put("TabbedPane.selected", ColourCombo.yellow);
|
---|
320 | UIManager.put("ComboBox.selectionBackground", ColourCombo.yellow);
|
---|
321 | UIManager.put("List.selectionBackground", ColourCombo.yellow);
|
---|
322 | UIManager.put("TextArea.selectionBackground", ColourCombo.yellow);
|
---|
323 | UIManager.put("TextField.selectionBackground", ColourCombo.yellow);
|
---|
324 | // force the UI to load these new UIManager defaults
|
---|
325 | javax.swing.SwingUtilities.updateComponentTreeUI(this);
|
---|
326 | // We can't change the UIManager defaults (properly) throughout GUI
|
---|
327 | // display-time, only upon creation and first display. This is
|
---|
328 | // because updateComponentTreeUI() has no effect once components
|
---|
329 | // have been displayed. For this reason, the various changeUIColor()
|
---|
330 | // methods and class ColourCombo have been written.
|
---|
331 | }
|
---|
332 |
|
---|
333 | /** Attempts to establish a connection to GS3 Web services and instantiate
|
---|
334 | * a GS3ServicesAPIA object and store it in the member variable greenstoneDL.
|
---|
335 | * If it was unsuccessful, then this variable remains at null and an error
|
---|
336 | * message is displayed. */
|
---|
337 | protected boolean createGreenstoneDLConnection()
|
---|
338 | {
|
---|
339 | // store the old choice of dl, if there was any
|
---|
340 | int oldSetting = (dlAPIA == null) ? SELECT : FEDORA;
|
---|
341 | // try instantiating a GS3 dl handle
|
---|
342 | try {
|
---|
343 | greenstoneDL = new GS3ServicesAPIA();
|
---|
344 | return true; // success
|
---|
345 | } catch(DigitalLibraryServicesAPIA.CancelException e){
|
---|
346 | // The user pressed cancel in the gs3 services instantiation dialog
|
---|
347 | // Set the dl drop-down list option back to whatever it was
|
---|
348 | } catch(Exception e) {
|
---|
349 | // still unable to instantiate greenstone, but show
|
---|
350 | // the error for what went wrong
|
---|
351 | JOptionPane.showMessageDialog(
|
---|
352 | null,
|
---|
353 | "Error connecting to Greenstone 3 web services.\n"
|
---|
354 | + "When attempting to process its wsdl file,\n"
|
---|
355 | + "encountered the problem:\n"
|
---|
356 | + e,
|
---|
357 | "Fatal error instantiating GS3WebServicesInterface. Exiting...",
|
---|
358 | JOptionPane.ERROR_MESSAGE
|
---|
359 | );
|
---|
360 | //e.printStackTrace(System.err);
|
---|
361 | LOG.error("Error connecting to Greenstone 3 web services:\n" + e);
|
---|
362 | }
|
---|
363 | // We'd be here if an exception occurred. Need to back to the old dl
|
---|
364 | // settings
|
---|
365 | dlChooser.setSelectedIndex(oldSetting);
|
---|
366 | return false;
|
---|
367 | }
|
---|
368 |
|
---|
369 | /** Attempts to establish a connection to FedoraGS3.jar and instantiate
|
---|
370 | * a FedoraServicesAPIA object and store it in the member variable fedoraDL.
|
---|
371 | * If it was unsuccessful, then this variable remains at null and an error
|
---|
372 | * message is displayed. */
|
---|
373 | protected boolean createFedoraDLConnection()
|
---|
374 | {
|
---|
375 | // store the old choice of dl, if there was any
|
---|
376 | int oldSetting = oldSetting = (dlAPIA == null) ? SELECT : GREENSTONE;
|
---|
377 | // Try to instantiate a Fedora dl handle
|
---|
378 | try {
|
---|
379 | fedoraDL = new FedoraServicesAPIA();
|
---|
380 | return true; // success
|
---|
381 | } catch(
|
---|
382 | org.greenstone.fedora.services.FedoraGS3Exception.CancelledException e)
|
---|
383 | {
|
---|
384 | // The user pressed cancel in the fedora services instantiation dlg
|
---|
385 | // Set the dl drop-down list option back to whatever it was
|
---|
386 | } catch(Exception e) {
|
---|
387 | JOptionPane.showMessageDialog(
|
---|
388 | null,
|
---|
389 | "Error instantiating the interface to the Fedora Repository\n"+ e,
|
---|
390 | "Unable to connect to Fedora's digital library services.",
|
---|
391 | JOptionPane.ERROR_MESSAGE
|
---|
392 | );
|
---|
393 | //e.printStackTrace(System.err);
|
---|
394 | LOG.error(
|
---|
395 | "Error instantiating the interface to the Fedora Repository:\n"+ e);
|
---|
396 | }
|
---|
397 | // We'd be here if an exception occurred. Need to go back to the old dl
|
---|
398 | // settings
|
---|
399 | dlChooser.setSelectedIndex(oldSetting);
|
---|
400 | return false;
|
---|
401 | }
|
---|
402 |
|
---|
403 | /** Method that is called when the user chooses to change the active
|
---|
404 | * digital library (between Greenstone3 and Fedora).
|
---|
405 | * @param dl is the new active digital library (the
|
---|
406 | * DigitalLibraryServicesAPIA object to change to). */
|
---|
407 | protected void changeDL(DigitalLibraryServicesAPIA dl) {
|
---|
408 | // change the colour of the interface
|
---|
409 | this.changeUIColour(dlChooser.getSelectedIndex());
|
---|
410 |
|
---|
411 | // clear up remnants of previously selected digital library's
|
---|
412 | // processing
|
---|
413 | browsePanel.clear();
|
---|
414 | searchResultsDisplay.clear();
|
---|
415 | this.searchSummary.setText("");
|
---|
416 | browseResponseObject.clear();
|
---|
417 | queryResponseObj.clear();
|
---|
418 |
|
---|
419 | // set current digital library to selected one
|
---|
420 | dlAPIA = dl;
|
---|
421 |
|
---|
422 | if(dlAPIA == null) {
|
---|
423 | // clear some panels so the user can't do anything
|
---|
424 | this.queryPanel.clear();
|
---|
425 | collBox.removeAllItems();
|
---|
426 | collBox.setEnabled(false);
|
---|
427 | serviceBox.removeAllItems();
|
---|
428 | serviceBox.setEnabled(false);
|
---|
429 | this.collectionNameField.setText("");
|
---|
430 | this.collInfoButton.setEnabled(false);
|
---|
431 | return;
|
---|
432 | }
|
---|
433 |
|
---|
434 | // start retrieving the information related to the chosen dl
|
---|
435 | String response = dlAPIA.describe();
|
---|
436 | if(response == null) {
|
---|
437 | LOG.error("Error: no response from dlAPIA.describe() of "
|
---|
438 | + dlAPIA.getDisplayName());
|
---|
439 | System.exit(1);
|
---|
440 | }
|
---|
441 |
|
---|
442 | Element responseXML = getResponseAsDOM(
|
---|
443 | "DESCRIBE RESPONSE:\n", response);
|
---|
444 |
|
---|
445 | // Get the collectionList element of the response
|
---|
446 | // from the default messageRouter-describe:
|
---|
447 | Element collectionList = ParseUtil.getFirstDescElementCalled(
|
---|
448 | responseXML, // (<message>, "collectionList")
|
---|
449 | GSXML.COLLECTION_ELEM+GSXML.LIST_MODIFIER
|
---|
450 | );
|
---|
451 | if(collectionList == null)
|
---|
452 | LOG.error("collectionList is null!");
|
---|
453 |
|
---|
454 | // Next, create a CollectionData object for each collection using
|
---|
455 | // its name
|
---|
456 | CollectionData[] collData = null;
|
---|
457 | Vector v = ParseUtil.getAllChildElementsCalled(collectionList,
|
---|
458 | GSXML.COLLECTION_ELEM); // (<collectionList>, "collection")
|
---|
459 | if(v == null)
|
---|
460 | LOG.error("collections are null!");
|
---|
461 |
|
---|
462 | if(v != null) {
|
---|
463 | StringBuffer buf = new StringBuffer("Collections:\n");
|
---|
464 | collData = new CollectionData[v.size()];
|
---|
465 | for(int i = 0; i < v.size(); i++){
|
---|
466 | collData[i] = new CollectionData((Element)v.get(i));
|
---|
467 | buf.append(collData[i].name + ", ");
|
---|
468 | }
|
---|
469 | }
|
---|
470 |
|
---|
471 | // Now send a describe request to each collection
|
---|
472 | // And set the fields for each collData using the response
|
---|
473 | for(int i = 0; i < collData.length; i++){
|
---|
474 | response = dlAPIA.describeCollection(collData[i].name);
|
---|
475 | responseXML = getResponseAsDOM(
|
---|
476 | "describeCollection "+collData[i].name+":", response);
|
---|
477 | Element collectionTag = ParseUtil.getFirstDescElementCalled(
|
---|
478 | responseXML, GSXML.COLLECTION_ELEM);
|
---|
479 |
|
---|
480 | // set the other fields of the CollectionData object using
|
---|
481 | // the collectionTag of the response from Collection-describe:
|
---|
482 | collData[i].setFields(collectionTag);
|
---|
483 | }
|
---|
484 |
|
---|
485 | if(collData == null) {
|
---|
486 | LOG.debug("No collections in the chosen repository");
|
---|
487 | return;
|
---|
488 | } else {
|
---|
489 | this.collInfoButton.setEnabled(true);
|
---|
490 | collBox.setEnabled(true);
|
---|
491 | serviceBox.setEnabled(true);
|
---|
492 | }
|
---|
493 |
|
---|
494 | // fill in the combobox containing the collections and the one
|
---|
495 | // containing the services
|
---|
496 | collBox.removeAllItems();
|
---|
497 | for(int i = 0; i < collData.length; i++)
|
---|
498 | collBox.addItem(collData[i]);
|
---|
499 | collBox.setSelectedItem(collData[0]);
|
---|
500 |
|
---|
501 | this.serviceBox.removeAllItems();
|
---|
502 | ServiceData[] serviceData = collData[0].getServiceList(
|
---|
503 | executableServicesOnly);
|
---|
504 | for(int i = 0; i < serviceData.length; i++)
|
---|
505 | serviceBox.addItem(serviceData[i]);
|
---|
506 | serviceBox.setSelectedIndex(0); // whichever might be the first
|
---|
507 | }
|
---|
508 |
|
---|
509 | /** Given an XML response string, returns the root document (element)
|
---|
510 | * representing its DOM form.
|
---|
511 | * @param response - the XML response string to be converted into
|
---|
512 | * its DOM form
|
---|
513 | * @return the response as an XML DOM Element */
|
---|
514 | protected Element getResponseAsDOM(String debugPrefix, String response) {
|
---|
515 | if(response == null) // will not be the case, because an empty
|
---|
516 | return null; // response message will be sent instead
|
---|
517 |
|
---|
518 | // First let's print out the response to the LOG
|
---|
519 | // Note that the response is XML and will start on new line already
|
---|
520 | LOG.debug(debugPrefix + response);
|
---|
521 | // The following line when uncommented will output all response
|
---|
522 | // msgs coming back from the web services
|
---|
523 | //System.out.println(debugPrefix + response);
|
---|
524 |
|
---|
525 | // At present, assuming response is okay - later need to first look
|
---|
526 | // for element <error> and process this meaningfully before returning
|
---|
527 | // XML DOM version of response. Example error:
|
---|
528 | // <message>
|
---|
529 | // <response from="infomine/TextQuery" type="process">
|
---|
530 | // <documentNodeList />
|
---|
531 | // <error type="other">IOException during connection to http://infominehelper.ucr.edu/cgi-bin/canned_search?theme=gsdl3&query=water&fields=kw,au,su,ti,de,fu,&no_of_records_per_page=10&start_page_no=1: java.net.ConnectException: Connection refused</error>
|
---|
532 | // </response>
|
---|
533 | // </message>
|
---|
534 |
|
---|
535 | Element message = null;
|
---|
536 | try{
|
---|
537 | // turn the String xml response into a DOM tree:
|
---|
538 | DocumentBuilder builder
|
---|
539 | = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
---|
540 | Document doc
|
---|
541 | = builder.parse(new InputSource(new StringReader(response)));
|
---|
542 | message = doc.getDocumentElement();
|
---|
543 | } catch(Exception e){
|
---|
544 | if(response == null) {
|
---|
545 | response = "";
|
---|
546 | }
|
---|
547 | JOptionPane.showMessageDialog(this,
|
---|
548 | "An error occurred while trying to parse the response:\n"
|
---|
549 | + response
|
---|
550 | + "\nException message:\n" + e.getMessage(),
|
---|
551 | "Parse error", JOptionPane.ERROR_MESSAGE);
|
---|
552 | e.printStackTrace();
|
---|
553 | }
|
---|
554 |
|
---|
555 | NodeList errorList = message.getElementsByTagName(GSXML.ERROR_ELEM);
|
---|
556 | if(errorList.getLength() == 0)
|
---|
557 | return message;
|
---|
558 |
|
---|
559 | // else we have one (or more?) error(s):
|
---|
560 | Element error = (Element)errorList.item(0);
|
---|
561 | String errorMessage = ParseUtil.getBodyTextValue(error);
|
---|
562 | String errorType = error.getAttribute("type");
|
---|
563 |
|
---|
564 | // no need to display error message if it was a query that was
|
---|
565 | // just executed and no results were found
|
---|
566 | if(//errorType.equals(GSXML.ERROR_TYPE_SYNTAX) &&
|
---|
567 | errorMessage.toLowerCase().indexOf("no documentnode found") != -1)
|
---|
568 | {
|
---|
569 | // if we're in here, we know that a search/query was performed
|
---|
570 | // That means we are dealing with the searchResultsDisplay
|
---|
571 | // and can clear it.
|
---|
572 | this.searchResultsDisplay.clear();
|
---|
573 | this.searchSummary.setText("");
|
---|
574 | }
|
---|
575 | else { // display error message
|
---|
576 | // number of letters per line
|
---|
577 | final int numLetters = 40;
|
---|
578 | String[] words = errorMessage.split(" "); //get the individual words
|
---|
579 | String line = words[0];
|
---|
580 | errorMessage = "";
|
---|
581 | // go through all the words and build up lines where none is
|
---|
582 | // longer than the specified number of letters
|
---|
583 | for(int i = 1; i < words.length; i++) { // append the word
|
---|
584 | // and a space to the same line unless the line is too long
|
---|
585 | if(numLetters > line.length() + words[i].length()) {
|
---|
586 | if(line.equals(""))
|
---|
587 | line = words[i];
|
---|
588 | else line = line + " " + words[i];
|
---|
589 |
|
---|
590 | // check if line is full after adding new word
|
---|
591 | if(line.length() == numLetters) { // finish the line
|
---|
592 | errorMessage = errorMessage + line + "\n";
|
---|
593 | line = "";
|
---|
594 | }
|
---|
595 | } // else the word has to go on the next line
|
---|
596 | else { //finish the line and move on:
|
---|
597 | errorMessage = errorMessage + line + "\n";
|
---|
598 | line = words[i];
|
---|
599 | }
|
---|
600 | }
|
---|
601 | LOG.debug("errorMessage:\n" + errorMessage);
|
---|
602 |
|
---|
603 | JOptionPane.showMessageDialog(this, errorMessage, "Error: "+errorType,
|
---|
604 | JOptionPane.ERROR_MESSAGE);
|
---|
605 | }
|
---|
606 | return message;
|
---|
607 | }
|
---|
608 |
|
---|
609 | /** Event handler for actionEvents such as a change in the active digital
|
---|
610 | * library, a collection being selected in the dropdown box or the collection
|
---|
611 | * -Info button being pressed, or a service being selected in the service
|
---|
612 | * dropdown box (browsing or searching). */
|
---|
613 | public void actionPerformed(ActionEvent e) {
|
---|
614 | if(e.getSource() == dlChooser) {
|
---|
615 | // We need to change to a Wait cursor while we do the switch
|
---|
616 | Container c = this.getContentPane();
|
---|
617 | c.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
---|
618 |
|
---|
619 | boolean success = true;
|
---|
620 | // Change the dlAPIA handle to the chosen digital library,
|
---|
621 | // instantiating DigitalLibraryServicesAPIA objects when necessary:
|
---|
622 | // if they haven't yet been created
|
---|
623 | switch(dlChooser.getSelectedIndex())
|
---|
624 | {
|
---|
625 | case GREENSTONE:
|
---|
626 | if(this.greenstoneDL == null) {
|
---|
627 | success = createGreenstoneDLConnection();
|
---|
628 | }
|
---|
629 | // no need to do anything if the user chose
|
---|
630 | // the same DL again
|
---|
631 | if(success && dlAPIA!=this.greenstoneDL) {
|
---|
632 | // current DL not already set to greenstoneDL
|
---|
633 | // so set it
|
---|
634 | this.changeDL(greenstoneDL);
|
---|
635 | }
|
---|
636 | break;
|
---|
637 | case FEDORA:
|
---|
638 | if(this.fedoraDL == null) {
|
---|
639 | success = createFedoraDLConnection();
|
---|
640 | }
|
---|
641 | // no need to do anything if the user chose
|
---|
642 | // the same DL again
|
---|
643 | if(success && dlAPIA!=this.fedoraDL) {
|
---|
644 | // current DL not already set to fedoraDL
|
---|
645 | // so set it
|
---|
646 | this.changeDL(fedoraDL);
|
---|
647 | }
|
---|
648 | break;
|
---|
649 | case SELECT:
|
---|
650 | default:
|
---|
651 | this.changeDL(null); // no dl, so default colours
|
---|
652 | break;
|
---|
653 | }
|
---|
654 | // set the cursor back
|
---|
655 | c.setCursor(Cursor.getDefaultCursor());
|
---|
656 | } else if(e.getSource() == collBox) {
|
---|
657 | CollectionData collDataEl
|
---|
658 | = (CollectionData)collBox.getSelectedItem();
|
---|
659 |
|
---|
660 | if(collDataEl == null) // need to check for this here, because
|
---|
661 | return; // removing all items from collBox fires actionPerformed
|
---|
662 |
|
---|
663 | // display the collection's full name
|
---|
664 | this.collectionNameField.setText(collDataEl.getDisplayName());
|
---|
665 | this.collectionNameField.setCaretPosition(0);
|
---|
666 |
|
---|
667 | // display the services in the selected collection
|
---|
668 | serviceBox.removeAllItems();
|
---|
669 | ServiceData[] servicelist = collDataEl.getServiceList(
|
---|
670 | executableServicesOnly);
|
---|
671 | for(int i = 0; i < servicelist.length; i++)
|
---|
672 | serviceBox.addItem(servicelist[i]);
|
---|
673 |
|
---|
674 | } else if(e.getSource() == serviceBox) {
|
---|
675 | ServiceData selService = (ServiceData)serviceBox.getSelectedItem();
|
---|
676 | if(selService == null || selService.type == null)
|
---|
677 | return; // nothing valid chosen
|
---|
678 |
|
---|
679 | if(selService.type.equals(GSXML.SERVICE_TYPE_QUERY)) {
|
---|
680 | // Make sure we can't accidentally work with already deallocated
|
---|
681 | // data objects in the browsePanel
|
---|
682 | browsePanel.clear();
|
---|
683 | searchSummary.setText(""); // empty any text in the search summary
|
---|
684 |
|
---|
685 | this.activity = SEARCHING; // ensures the components are
|
---|
686 | // displayed and shown again, whereas a call to repaint()
|
---|
687 | // did not do the trick
|
---|
688 |
|
---|
689 | tabbedPane.setSelectedComponent(this.queryPanel);
|
---|
690 |
|
---|
691 | // send off a describe request to the service
|
---|
692 | // in that collection
|
---|
693 | CollectionData selColl
|
---|
694 | = (CollectionData)collBox.getSelectedItem();
|
---|
695 | colName = selColl.name;
|
---|
696 | serviceName = selService.name;
|
---|
697 |
|
---|
698 | String response = dlAPIA.describeCollectionService(
|
---|
699 | colName, serviceName);
|
---|
700 | Element serviceResponseXML = getResponseAsDOM(
|
---|
701 | "DescribeCollectionService "+colName+"/"+serviceName,
|
---|
702 | response);
|
---|
703 |
|
---|
704 | // generate the appropriate query form as per how the
|
---|
705 | // query has described itself
|
---|
706 | queryPanel.formFromQueryServiceDescribe(serviceResponseXML);
|
---|
707 | } else if(selService.type.equals(GSXML.SERVICE_TYPE_BROWSE)) {
|
---|
708 | LOG.debug("Browse option chosen");
|
---|
709 | this.searchResultsDisplay.clear();
|
---|
710 | this.searchSummary.setText("");
|
---|
711 | this.queryPanel.clear(); // can't do any searching either
|
---|
712 | this.activity = BROWSING;
|
---|
713 | tabbedPane.setSelectedComponent(this.browsePanel);
|
---|
714 |
|
---|
715 | CollectionData selColl
|
---|
716 | = (CollectionData)collBox.getSelectedItem();
|
---|
717 | colName = selColl.name;
|
---|
718 | serviceName = selService.name;
|
---|
719 |
|
---|
720 | // first send a request for the browse service's metadata
|
---|
721 | // see manual pp.37 and 48
|
---|
722 | String response = dlAPIA.describeCollectionService(
|
---|
723 | colName, serviceName);
|
---|
724 | Element responseMsg = getResponseAsDOM(
|
---|
725 | colName+"/"+serviceName+":", response);
|
---|
726 | browsePanel.displayBrowseOptions(responseMsg);
|
---|
727 | } else { // clicked on non-query, non-browse option, remove form
|
---|
728 | queryPanel.clear();
|
---|
729 | }
|
---|
730 | } else if(e.getSource() == collInfoButton){
|
---|
731 | CollectionData collDataEl
|
---|
732 | = (CollectionData)collBox.getSelectedItem();
|
---|
733 |
|
---|
734 | // Create the HTML viewing pane.
|
---|
735 | JEditorPane information = new JEditorPane();
|
---|
736 | information.setEditable(false);
|
---|
737 | information.setContentType("text/html");
|
---|
738 | information.setText(collDataEl.info());
|
---|
739 |
|
---|
740 | // Display the dialog with the information in a scrollpane
|
---|
741 | JDialog dialog = new JDialog(this, collDataEl.toString());
|
---|
742 | dialog.getContentPane().add(new JScrollPane(information));
|
---|
743 | dialog.setDefaultCloseOperation(DISPOSE_ON_CLOSE); // not EXIT!
|
---|
744 | dialog.pack();
|
---|
745 | dialog.setSize(400, 300);
|
---|
746 | dialog.setVisible(true);
|
---|
747 | }
|
---|
748 | else if(e.getSource() == setProxySettings) { // proxy settings button
|
---|
749 | // Sthe proxy settings as given in the fields
|
---|
750 | String proxyHost = this.proxyhostField.getText();
|
---|
751 | String proxyPort = this.proxyportField.getText();
|
---|
752 | if(proxyHost.equals("") && proxyPort.equals("")) {
|
---|
753 | return;
|
---|
754 | } else {
|
---|
755 | // Handle proxy settings
|
---|
756 | // (don't need to write to propertiesFile, since proxy
|
---|
757 | // settings are System properties)
|
---|
758 | java.util.Properties systemSettings = System.getProperties();
|
---|
759 | systemSettings.put("http.proxyHost", proxyHost);
|
---|
760 | systemSettings.put("http.proxyPort", proxyPort);
|
---|
761 | // give the hosts for which no proxies are required:
|
---|
762 | systemSettings.put("http.nonProxyHosts",
|
---|
763 | this.nonProxyHostNamesField.getText());
|
---|
764 | System.setProperties(systemSettings);
|
---|
765 | }
|
---|
766 | }
|
---|
767 | }
|
---|
768 |
|
---|
769 | /** Called by the instance of the QueryForm class when the user has
|
---|
770 | * pressed the queryPanel's search button to execute a query. Based on
|
---|
771 | * the user-entered values (stored in the parameter HashMap) this
|
---|
772 | * method will call Greenstone to process the query.
|
---|
773 | * @param nameValParamsMap - the query form control names with the values
|
---|
774 | * the user has entered for them. Example, the pair (fqv, the query string),
|
---|
775 | * where fqv is the form control name for the query term. */
|
---|
776 | public void performSearch(HashMap nameValParamsMap) {
|
---|
777 | //Container c = this.getContentPane();
|
---|
778 | //c.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
---|
779 | this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
---|
780 |
|
---|
781 | // (1) Now let's process this query request - passing the
|
---|
782 | // currently selected collection and service:
|
---|
783 | String responseXML = dlAPIA.query(
|
---|
784 | colName, serviceName, nameValParamsMap);
|
---|
785 |
|
---|
786 | // (2) The search results: document identifiers are returned,
|
---|
787 | // use these to construct a QueryResponseData object
|
---|
788 | Element responseMessage
|
---|
789 | = getResponseAsDOM("Search response:", responseXML);
|
---|
790 | queryResponseObj.setResponseData(responseMessage);
|
---|
791 | LOG.debug(queryResponseObj);
|
---|
792 |
|
---|
793 | DocumentNodeData[] doclist = queryResponseObj.getDocumentNodeList();
|
---|
794 |
|
---|
795 | // (3) To retrieve Title metadata, need to call with "Title"!!!!
|
---|
796 | // (1st letter in caps)
|
---|
797 | // Retrieving just metadata name=Title for ALL docs (=all docIDs)
|
---|
798 | String metaResponseXML = dlAPIA.retrieveTitleMetadata(this.colName,
|
---|
799 | queryResponseObj.getDocumentNodeIDs());
|
---|
800 | Element metaResponse
|
---|
801 | = getResponseAsDOM("Meta response:", metaResponseXML);
|
---|
802 | queryResponseObj.setMetadataForDocuments(metaResponse);
|
---|
803 |
|
---|
804 | // doclist should now have been updated with title metadata for
|
---|
805 | // each doc (docNode)
|
---|
806 | //for(int i = 0; i < doclist.length; i++)
|
---|
807 | //LOG.debug(doclist[i].show());
|
---|
808 |
|
---|
809 | // (4) Display this in the search results TreeView
|
---|
810 | tabbedPane.setSelectedComponent(searchPanel);
|
---|
811 | searchResultsDisplay.setResults(doclist);
|
---|
812 | searchSummary.setText(queryResponseObj.toString());
|
---|
813 | searchResultsDisplay.validate();
|
---|
814 | this.searchPanel.validate();
|
---|
815 | this.searchPanel.repaint();
|
---|
816 |
|
---|
817 | // set the cursor back
|
---|
818 | //c.setCursor(Cursor.getDefaultCursor());
|
---|
819 | this.setCursor(Cursor.getDefaultCursor());
|
---|
820 | }
|
---|
821 |
|
---|
822 |
|
---|
823 | /* SEARCH RELATED METHODS */
|
---|
824 | /** Performs a docMetadataRetrieve message request for the docNode
|
---|
825 | * iff the metadata for that docNode is not already set.
|
---|
826 | * @param docNode is the DocumentNodeData object for which all the
|
---|
827 | * metadata is to be retrieved. */
|
---|
828 | public void retrieveAllMetadataFor(DocumentNodeData docNode) {
|
---|
829 | // Lazy retrieval: only retrieve metadata of docNode when required
|
---|
830 | // and if metadata not already set
|
---|
831 | if(docNode.getMetadataList() == null
|
---|
832 | || docNode.getMetadataList().size() <= 1)
|
---|
833 | { // not set yet or only title set,
|
---|
834 | // so do a docMetadataRetrieve for the docNode (all
|
---|
835 | // metadata fields retrieved):
|
---|
836 | String metaResponseXML = dlAPIA.retrieveDocumentMetadata(
|
---|
837 | this.colName, new String[] { docNode.nodeID });
|
---|
838 | Element metaResponse
|
---|
839 | = getResponseAsDOM("Meta response", metaResponseXML);
|
---|
840 |
|
---|
841 | // Set the metadata for the docNode
|
---|
842 | if(this.activity == SEARCHING)
|
---|
843 | queryResponseObj.setMetadataForDocuments(metaResponse);
|
---|
844 | else if(this.activity == BROWSING)
|
---|
845 | browseResponseObject.setMetadataForDocuments(metaResponse);
|
---|
846 | } //else docNode's list of metadata already set
|
---|
847 | }
|
---|
848 |
|
---|
849 | /** Performs a docMetadataRetrieve message request for the docNode
|
---|
850 | * iff the nodeContent for that docNode is not already set.
|
---|
851 | * @param docNode is the DocumentNodeData object for which the content
|
---|
852 | * is to be retrieved. */
|
---|
853 | public void retrieveContentFor(DocumentNodeData docNode) {
|
---|
854 | // Lazy retrieval: only retrieve content when required.
|
---|
855 | // If it is not yet set, then we do the retrieval, else
|
---|
856 | // our work here is done
|
---|
857 | if(docNode.getContent() == null) { // not set yet, so
|
---|
858 | // retrieve the content for the docNode
|
---|
859 | String contentResponseXML = dlAPIA.retrieveDocumentContent(
|
---|
860 | this.colName, new String[] { docNode.nodeID });
|
---|
861 | Element contentResponse = getResponseAsDOM(
|
---|
862 | "Content response:", contentResponseXML);
|
---|
863 | // probably when infomine is down
|
---|
864 | // Set the content for the docNode
|
---|
865 | if(this.activity==SEARCHING)
|
---|
866 | queryResponseObj.setContentForDocs(contentResponse);
|
---|
867 | else if(this.activity==BROWSING)
|
---|
868 | browseResponseObject.setContentForDocs(contentResponse);
|
---|
869 | }
|
---|
870 | }
|
---|
871 |
|
---|
872 | /** Performs a structureRetrieve and title metadata retrieve message-
|
---|
873 | * request for the docNode, but only iff the structure and title for
|
---|
874 | * that docNode is not already set.
|
---|
875 | * @param docNode is the DocumentNodeData object for which the title
|
---|
876 | * is to be retrieved along with the titles of all its descendants. */
|
---|
877 | public void retrieveTitledStructureFor(DocumentNodeData docNode) {
|
---|
878 | DocumentNodeData root = docNode.getRoot();
|
---|
879 | if(root == null) { //then its structure has not yet been set
|
---|
880 | // do a structure retrieve for this document:
|
---|
881 | String structureResponseXML = dlAPIA.retrieveDocumentStructure(
|
---|
882 | this.colName, new String[] { docNode.nodeID });
|
---|
883 | Element structureResponse = getResponseAsDOM(
|
---|
884 | "STRUCTURE: ", structureResponseXML);
|
---|
885 |
|
---|
886 | // Get the nodeStructure of this docNode, find its root and
|
---|
887 | // from there set all the descendents
|
---|
888 | // Instead of the following 2 statements can also do:
|
---|
889 | // queryResponseObj.setStructureForDocs(structureResponse);
|
---|
890 |
|
---|
891 | Element nodeStructure = ParseUtil.getFirstDescElementCalled(
|
---|
892 | structureResponse, GSXML.NODE_STRUCTURE_ELEM);
|
---|
893 |
|
---|
894 | // now we set the root and its descendents using whatever
|
---|
895 | ResponseData responseObject = browseResponseObject;
|
---|
896 | // true if(this.activity == BROWSING)
|
---|
897 | if(this.activity == SEARCHING)
|
---|
898 | responseObject = queryResponseObj;
|
---|
899 |
|
---|
900 | root = docNode.setDescendentsOfRootNode(nodeStructure,
|
---|
901 | responseObject.getIDToNodeMapping());
|
---|
902 |
|
---|
903 | // Now get only the DocumentNodeData elements in the root's
|
---|
904 | // descendents whose titles have not yet been set
|
---|
905 | String[] setTitleForTheseNodeIDs = root.getDescNodeIDsAsList(true);
|
---|
906 | // Will be null if all titles already set! But this should not be
|
---|
907 | // the case if we have just set the descendents of the root node
|
---|
908 | if(setTitleForTheseNodeIDs != null) {
|
---|
909 | // Retrieve the title metadata for these and set their titles
|
---|
910 | // with the response:
|
---|
911 | String titleMetaResponseXML = dlAPIA.retrieveTitleMetadata(
|
---|
912 | this.colName, setTitleForTheseNodeIDs);
|
---|
913 | Element titleMetaResponse = getResponseAsDOM(
|
---|
914 | "titleMetaResponseXML:", titleMetaResponseXML);
|
---|
915 |
|
---|
916 | // Use whatever responseObject is active to set the metadata
|
---|
917 | responseObject.setMetadataForDocuments(titleMetaResponse);
|
---|
918 | }
|
---|
919 | }
|
---|
920 | }
|
---|
921 |
|
---|
922 | /* BROWSE RELATED METHODS */
|
---|
923 | /** Given a ClassifierData object indicating what browsing category
|
---|
924 | * was chosen, this method will retrieve all its descendants in the
|
---|
925 | * hierarchy. Only the top-level descendents (children) of the
|
---|
926 | * classification will be set initially.
|
---|
927 | * @param classifier is the ClassifierData object whose children are
|
---|
928 | * to be retrieved. */
|
---|
929 | public void doBrowse(ClassifierData classifier) {
|
---|
930 | String response = dlAPIA.retrieveBrowseStructure(
|
---|
931 | this.colName, this.serviceName, classifier.name);
|
---|
932 |
|
---|
933 | browseResponseObject.clear();
|
---|
934 | Element responseMsgTag = this.getResponseAsDOM(
|
---|
935 | "browseResponse:", response);
|
---|
936 | browseResponseObject.setResponseData(responseMsgTag); //classifier.name
|
---|
937 |
|
---|
938 | LOG.debug(browseResponseObject.show());
|
---|
939 |
|
---|
940 | this.browsePanel.displayBrowseResults(browseResponseObject,
|
---|
941 | classifier.displayName);
|
---|
942 | this.browsePanel.validate();
|
---|
943 | }
|
---|
944 |
|
---|
945 | /** Given a ClassifierNodeData object for browsing, this method will
|
---|
946 | * set the classNode's children (previously retrieved) and retrieve
|
---|
947 | * all the children's metadata including the title.
|
---|
948 | * @param classNode is the ClassifierNodeData object whose title is to
|
---|
949 | * be retrieved along with the titles for its children. */
|
---|
950 | public void retrieveTitledStructureFor(ClassifierNodeData classNode) {
|
---|
951 | // we will only be setting the children in this method and retrieving
|
---|
952 | // the names for them, as it concerns a classifierNodeData (and not
|
---|
953 | // a documentNodeData).
|
---|
954 |
|
---|
955 | classNode.setChildren(browseResponseObject.getIDToNodeMapping());
|
---|
956 |
|
---|
957 | //String rootID = browseResponseObject.getRootClassifier().nodeID;
|
---|
958 |
|
---|
959 | NodeData[] children = classNode.getChildren();
|
---|
960 | Vector docNodeChildren = new Vector(children.length);
|
---|
961 | Vector classNodeChildren = new Vector(children.length);
|
---|
962 | //String nodeIDs[] = new String[children.length];
|
---|
963 | for(int i = 0; i < children.length; i++) {
|
---|
964 | // don't bother setting the metadata if it was
|
---|
965 | // already set (check for empty metadata
|
---|
966 | if(children[i].getMetadataList() == null) {
|
---|
967 | if(children[i] instanceof ClassifierNodeData)
|
---|
968 | classNodeChildren.add(children[i]);
|
---|
969 | else if(children[i] instanceof DocumentNodeData)
|
---|
970 | docNodeChildren.add(children[i]);
|
---|
971 | }
|
---|
972 | }
|
---|
973 | String[] nodeIDs = null;
|
---|
974 |
|
---|
975 | // First set the metadata for any classifiers:
|
---|
976 | if(classNodeChildren.size() > 0) {
|
---|
977 | nodeIDs = new String[classNodeChildren.size()];
|
---|
978 | for(int i = 0; i < nodeIDs.length; i++)
|
---|
979 | nodeIDs[i] = ((NodeData)classNodeChildren.get(i)).nodeID;
|
---|
980 |
|
---|
981 | // let's just retrieve all the metadata - need to display it
|
---|
982 | // soon anyway
|
---|
983 | String response = dlAPIA.retrieveBrowseMetadata(this.colName,
|
---|
984 | this.serviceName, nodeIDs);
|
---|
985 | Element responseXML = this.getResponseAsDOM(
|
---|
986 | "MetadataRetrieve response: ", response);
|
---|
987 | browseResponseObject.setMetadataForClassifiers(responseXML);
|
---|
988 |
|
---|
989 | for(int i = 0; i < nodeIDs.length; i++)
|
---|
990 | LOG.debug("Title: "
|
---|
991 | + ((NodeData)classNodeChildren.get(i)).getTitle());
|
---|
992 | }
|
---|
993 |
|
---|
994 | nodeIDs = null;
|
---|
995 | // Now set the metadata for any documentNodes for which metadata
|
---|
996 | // has not been set yet
|
---|
997 | if(docNodeChildren.size() > 0) {
|
---|
998 | nodeIDs = new String[docNodeChildren.size()];
|
---|
999 | for(int i = 0; i < nodeIDs.length; i++)
|
---|
1000 | nodeIDs[i] = ((NodeData)docNodeChildren.get(i)).nodeID;
|
---|
1001 |
|
---|
1002 | // let's just retrieve all the metadata - need to display it
|
---|
1003 | // soon anyway
|
---|
1004 | String response = dlAPIA.retrieveDocumentMetadata(
|
---|
1005 | this.colName, nodeIDs);
|
---|
1006 | Element responseXML = this.getResponseAsDOM(
|
---|
1007 | "MetadataRetrieve response: ", response);
|
---|
1008 | browseResponseObject.setMetadataForDocuments(responseXML);
|
---|
1009 |
|
---|
1010 | for(int i = 0; i < nodeIDs.length; i++)
|
---|
1011 | LOG.debug("Title: "
|
---|
1012 | + ((NodeData)docNodeChildren.get(i)).getTitle());
|
---|
1013 | }
|
---|
1014 | }
|
---|
1015 |
|
---|
1016 | /** @return the baseURL of the active digital library interface object */
|
---|
1017 | public String getBaseURL() {
|
---|
1018 | return this.dlAPIA.getAssocFileBaseURL();
|
---|
1019 | }
|
---|
1020 |
|
---|
1021 | /** @return the filepath of the documentNode in the active digital library */
|
---|
1022 | public String getFilePath(DocumentNodeData docNode) {
|
---|
1023 | return this.dlAPIA.getAssocFileBaseURL(docNode);
|
---|
1024 | }
|
---|
1025 |
|
---|
1026 | /**
|
---|
1027 | * Changes the background colours of the client's user interface
|
---|
1028 | * based on what the active digital library is.
|
---|
1029 | * See files greenstone3/gli/classes/xml/config.xml and
|
---|
1030 | * greenstone3/gli/src/org/greenstone/gatherer/Configuration.java
|
---|
1031 | * @param DL indicates whether the active digital library is Greenstone or
|
---|
1032 | * Fedora (or neither, in which case the GUI defaults to the usual grey).
|
---|
1033 | * @see <a href="http://www.java2s.com/Code/Java/Swing-JFC/UIManagerresourcestotweakthelookofapplications.htm">Java UIManager tutorial</a>
|
---|
1034 | */
|
---|
1035 | public void changeUIColour(int DL)
|
---|
1036 | {
|
---|
1037 | ColourCombo.setColour(DL);
|
---|
1038 | ColourCombo.changeColor(this.collBox);
|
---|
1039 | ColourCombo.changeColor(this.collectionNameField);
|
---|
1040 | ColourCombo.changeColor(this.serviceBox);
|
---|
1041 |
|
---|
1042 | // change anonymous super panels' colours:
|
---|
1043 | ColourCombo.changeAncestorColor(this.collBox);
|
---|
1044 | ColourCombo.changeAncestorColor(this.serviceBox);
|
---|
1045 |
|
---|
1046 | // change tab pane panels and their colouring
|
---|
1047 | this.queryPanel.changeUIColour();
|
---|
1048 | this.browsePanel.changeUIColour();
|
---|
1049 | this.searchResultsDisplay.changeUIColour();
|
---|
1050 | }
|
---|
1051 |
|
---|
1052 | /** The main method of the GS3 java-client application. It instantiates
|
---|
1053 | * an instance of the GS3JavaClient main window and makes it visible. */
|
---|
1054 | public static void main(String[] args) {
|
---|
1055 | // set it up for logging
|
---|
1056 | final String logPropsFile = "log4j.properties";
|
---|
1057 | PropertyConfigurator.configure(logPropsFile);
|
---|
1058 |
|
---|
1059 | GS3JavaClient client = new GS3JavaClient();
|
---|
1060 | client.pack();
|
---|
1061 | // make the main window fullscreen
|
---|
1062 | client.setSize(Toolkit.getDefaultToolkit().getScreenSize());
|
---|
1063 | client.setVisible(true);
|
---|
1064 | client.setDefaultCloseOperation(EXIT_ON_CLOSE);
|
---|
1065 | }
|
---|
1066 | } |
---|