source: other-projects/trunk/gs3-webservices-democlient/src/GS3Fedora/org/greenstone/fedora/services/FedoraGS3Connection.java@ 15437

Last change on this file since 15437 was 15437, checked in by ak19, 16 years ago

Introduced GSearchConnection member indexName set in its constructor by FedoraGS3Connection

File size: 91.1 KB
Line 
1/**
2 *#########################################################################
3 * FedoraGS3Connection.java - works with the demo-client for Greenstone 3,
4 * of the Greenstone digital library suite from the New Zealand Digital
5 * Library 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
21package org.greenstone.fedora.services;
22
23
24import java.io.StringReader;
25
26import org.apache.log4j.Logger;
27import org.greenstone.fedora.services.FedoraGS3Exception.AuthenticationFailedException;
28import org.greenstone.fedora.services.FedoraGS3Exception.CancelledException;
29import org.greenstone.fedora.services.FedoraGS3Exception.FedoraGS3RunException;
30import org.greenstone.fedora.services.FedoraGS3Exception.NotAFedoraServerException;
31import org.greenstone.gsdl3.util.GSXML;
32import org.w3c.dom.Document;
33import org.w3c.dom.Element;
34import org.w3c.dom.Attr;
35import org.w3c.dom.Text;
36import org.w3c.dom.NodeList;
37import org.w3c.dom.Node;
38import org.xml.sax.InputSource;
39
40import java.io.File;
41import java.util.HashMap;
42import java.util.Properties;
43import java.util.Map;
44
45import javax.swing.JOptionPane;
46
47import org.xml.sax.SAXException;
48import java.io.UnsupportedEncodingException;
49import java.io.IOException;
50import javax.net.ssl.SSLHandshakeException;
51import java.net.ConnectException;
52import java.net.MalformedURLException;
53import java.rmi.RemoteException;
54import javax.xml.parsers.ParserConfigurationException;
55import javax.xml.transform.TransformerException;
56
57/**
58 * Class that extends FedoraConnection in order to be able to use
59 * Fedora's web services to retrieve the specific datastreams of
60 * Greenstone documents stored in Fedora's repository. This class
61 * provides methods that convert those datastreams into Greenstone3
62 * XML response messages which are returned.
63 * @author ak19
64*/
65public class FedoraGS3Connection
66 extends FedoraConnection implements FedoraToGS3Interface,
67 FedoraToGS3Interface.Constants
68{
69 /** The logging instance for this class */
70 private static final Logger LOG = Logger.getLogger(
71 FedoraGS3Connection.class.getName());
72
73 /** The last part of the gSearchWSDL URL. The first part is
74 * the same as the fedora server's base url. */
75 protected static final String gSearchWSDLSuffix
76 = "gsearch/services/FgsOperations?wsdl";
77
78 /** Complete list of services that are supported our FedoraGS3 would
79 * support if everything goes well. If a connection to FedoraGSearch
80 * cannot be established, the query services will no longer be
81 * available. The actual services supported are given by member
82 * variable serviceNames. */
83 protected static final String[] SERVICES = {
84 "DocumentContentRetrieve", "DocumentMetadataRetrieve",
85 "DocumentStructureRetrieve",
86 "TextQuery", "FieldQuery",
87 "ClassifierBrowse", "ClassifierBrowseMetadataRetrieve"
88 };
89
90 /** List of services actually supported by our FedoraGS3 repository
91 * after construction. If FedoraGenericSearch can't be connected to,
92 * then query services will not be offered */
93 protected String[] serviceNames;
94
95 /** constant CHILDREN indicates that a DocumentStructureRetrieve is to
96 * return only the child nodes of a section, not any further descendants */
97 protected static final int CHILDREN = 0;
98
99 /** constant DESCENDANTS indicates that a DocumentStructureRetrieve is to
100 * return all descendants of a section */
101 protected static final int DESCENDANTS = 1;
102
103 /** The object used to connect to FedoraGenericSearch, which is used
104 * for doing full-text searching */
105 protected GSearchConnection fedoraGSearch;
106
107 /** The url for the wsdl file of FedoraGSearch's web services
108 * by default this will be the Fedora server's base URL
109 * concatenated to "gsearch/services/FgsOperations?wsdl" */
110 protected String gSearchWSDLURL;
111
112 /** The name of the index that FedoraGSearch will index the GS3
113 * documents into. If no name is specified in the properties file,
114 * this will default to FedoraIndex. */
115 protected String gSearchIndexName;
116
117 /** 5 argument constructor is the same as that of superclass FedoraConnection:
118 * @param protocol can be either http or https
119 * @param host is the host where the fedora server is listening
120 * @param port is the port where the fedora server is listening
121 * @param fedoraServerUsername is the username for administrative
122 * authentication required to access the fedora server.
123 * @param fedoraServerPassword is the password for administrative
124 * authentication required to access the fedora server. If no password was set
125 * when installing Fedora, leave the field "".
126 * Instantiates a FedoraGS3Connection object which connects to Fedora's
127 * web services through stub classes and tries to connect to FedoraGSearch's
128 * web services through the default WSDL location for it
129 * ("gsearch/services/FgsOperations?wsdl"). If another url is to be used,
130 * call setGSearchWSDLURL(url) after the constructor instead.
131 */
132 public FedoraGS3Connection(String protocol, String host, int port,
133 String fedoraServerUsername, String fedoraServerPassword)
134 throws ParserConfigurationException, MalformedURLException,
135 SSLHandshakeException, RemoteException, AuthenticationFailedException,
136 NotAFedoraServerException, ConnectException, Exception
137 {
138 super(protocol, host, port, fedoraServerUsername, fedoraServerPassword);
139 // super() will call setInitialisationProperties(properties)
140 // And that will try to instantiate the GSearchConnection.
141 }
142
143 /** No-argument constructor which is the same as that of superclass
144 * FedoraConnection: it displays a small dialog requesting input for the
145 * host, port, administrative password and username of the fedora server.
146 * If no password was set on the fedora repository when installing it,
147 * the user can leave the password field blank. */
148 public FedoraGS3Connection()
149 throws ParserConfigurationException, MalformedURLException,
150 CancelledException, ConnectException, RemoteException,
151 SSLHandshakeException, Exception
152 {
153 super();
154 // super() will call setInitialisationProperties(properties)
155 // And that will try to instantiate the GSearchConnection.
156 }
157
158 /** Single-argument constructor which is the same as that of superclass
159 * FedoraConnection: it takes the name of the properties file where
160 * connection initialisation values may already be provided and then
161 * displays a small dialog requesting input for the host, port,
162 * administrative password and username of the fedora server showing
163 * the values in the properties file as default. If the necessary
164 * initialisation are not present in the file, they corresponding fields
165 * in the dialog will be blank.
166 * If no password was set on the fedora repository when installing it,
167 * the user can leave the password field blank. */
168 public FedoraGS3Connection(File propertiesFilename)
169 throws ParserConfigurationException, MalformedURLException,
170 CancelledException, ConnectException, RemoteException,
171 SSLHandshakeException, Exception
172 {
173 super(propertiesFilename);
174 // super() will call setInitialisationProperties(properties)
175 // And that will try to instantiate the GSearchConnection.
176 }
177
178 /** The superclass constructor calls this method passing any preset
179 * properties loaded from a propertiesFile. This method is overridden
180 * here in order to instantiate the gSearchConnection based on the
181 * - gSearchWSDLURL (If one was not provided in the properties file,
182 * gSearchWSDLURL defaults to something of the form
183 * "http://localhost:8080/fedoragsearch/services/FgsOperations?wsdl"
184 * where http://localhost:8080/fedora is the baseURL of fedora and
185 * "gsearch/services/FgsOperations?wsdl" is the default gSearchWSDLSuffix.)
186 * - name of the index into which the GS3 documents have been indexed
187 * and which FedoraGenericSearch should use to perform searches. If none is
188 * given in the properties file, then the index name defaults "FedoraIndex".
189 * @param properties is the Properties Map loaded from a properties file
190 * (if there was any) which specifies such things as host and port of the
191 * FedoraServer, but can also specify the property "gsearch.wsdlURL".
192 * At the end of this method, properties' "gsearch.wsdlURL" will be set
193 * to whatever the final value of this.gSearchWSDLURL is, and
194 * "gsearch.indexName" will be set to to whatever the final value of
195 * this.gSearchIndexName is.
196 */
197 protected void setInitialisationProperties(Properties properties)
198 throws ParserConfigurationException, MalformedURLException,
199 CancelledException, ConnectException, RemoteException,
200 SSLHandshakeException, Exception
201 {
202 super.setInitialisationProperties(properties);
203 // gsearchWSDL URL, if not specified, defaults to something of the form:
204 // "http://localhost:8080/fedoragsearch/services/FgsOperations?wsdl"
205 // where http://localhost:8080/fedora is the baseURL of fedora
206 this.gSearchWSDLURL = properties.getProperty(
207 "gsearch.wsdlURL", this.baseURL+gSearchWSDLSuffix);
208 // Set the property to whatever this.gSearchWSDLURL is now,
209 // so that it will be written out to the properties file again
210 properties.setProperty("gsearch.wsdlURL", this.gSearchWSDLURL);
211
212 // Similarly for the name of the index FedoraGenericSearch should use
213 // when performing searches for GS3 docs stored in Fedora's repository.
214 this.gSearchIndexName = properties.getProperty(
215 "gsearch.indexName", "FedoraIndex"); // default to FedoraIndex
216 properties.setProperty("gsearch.indexName", this.gSearchIndexName);
217 // Create a connection to FedoraGSearch's web services:
218 initSearchFunctionality();
219 }
220
221 /** Init method that instantiates a GSearchConnection object used
222 * to work with the separate FedoraGSearch web services.
223 * The url of the WSDL for FedoraGSearch's web services is worked out
224 * from the baseURL of the Fedora server.
225 */
226 protected void initSearchFunctionality()
227 {
228 try {
229 this.fedoraGSearch = null;
230 this.fedoraGSearch = new GSearchConnection(
231 gSearchWSDLURL, gSearchIndexName);
232 this.serviceNames = SERVICES;
233 } catch(Exception e){
234 LOG.error("Cannot connect to FedoraGSearch's web services at "
235 + gSearchWSDLURL + "\nQuery services will not be available.");
236 // If an exception occurs, something has gone wrong when
237 // trying to connect to FedoraGSearch's web services. This
238 // means, we can't offer query services, as that's provided
239 // by FedoraGSearch
240 serviceNames = null;
241 int countOfNonQueryServices = 0;
242 for(int i = 0; i < SERVICES.length; i++) {
243 // do not count query services
244 if(!SERVICES[i].toLowerCase().contains("query")) {
245 countOfNonQueryServices++;
246 }
247 }
248 // Services now supported are everything except Query services
249 serviceNames = new String[countOfNonQueryServices];
250 int j = 0;
251 for(int i = 0; i < SERVICES.length; i++) {
252 if(!SERVICES[i].toLowerCase().contains("query")) {
253 serviceNames[j] = SERVICES[i];
254 j++; // valid serviceName, so increment serviceName counter
255 }
256
257 }
258 }
259 }
260
261 /** @return the gSearchWSDLURL, the url of the WSDL for the
262 * FedoraGSearch web services */
263 public String getGSearchWSDLURL() { return gSearchWSDLURL; }
264
265 /** Sets the member variable gSearchWSDLURL that specify the location of
266 * the WSDL file of FedoraGSearch's web services. Then it attempts
267 * to instantiate a connection to those web services.
268 * @param url is the new url of the GSearch web services WSDL file */
269 public void setGSearchWSDLURL(String url) {
270 this.gSearchWSDLURL = url;
271 initSearchFunctionality();
272 }
273
274 /** @return the gSearchIndexName, the name of the index Fedora Generic
275 * Search will search in (where GS3 docs have been indexed into). */
276 public String getGSearchIndexName() { return gSearchIndexName; }
277
278 /** Sets the member variable gSearchIndexName that specifies the name
279 * of the index containing indexed GS3 documents. Then it attempts
280 * to instantiate a connection to the Fedora GSearch web services using
281 * this changed value for indexName.
282 * @param indexName is the new name of the index containing indexed GS3
283 * docs that GSearch should search in. */
284 public void setGSearchIndexName(String indexName) {
285 this.gSearchIndexName = indexName;
286 initSearchFunctionality();
287 }
288
289 /** @return the array of the services actually supported by FedoraGS3 */
290 protected String[] getServiceNames() { return this.serviceNames;}
291
292 /**
293 * For finding out if the sectionNumber is given as part of the docID.
294 * @param docID is the String that contains the docPID and may also
295 * contain the section number.
296 * @return true if the document identifier docID contains a section-
297 * number, and false if it consists solely of the docPID.
298 * That is, true is returned if
299 * <pre>docID = "greenstone:colName-&lt;docPID&gt;-&lt;sectionNum&gt;"</pre>
300 * and false is returned if
301 * <pre>docID = "greenstone:colName-&lt;docPID&gt;"</pre>
302 * */
303 protected boolean containsSectionNumber(String docID) {
304 // if there are two hyphens in the docID, then there are sections
305 // (and the section number is appended at end of docID)
306 // docID = "greenstone:colName-<docPID>-<sectionNum>"
307 return (docID.lastIndexOf(HYPHEN) != docID.indexOf(HYPHEN));
308 }
309
310 /** This method will extract the docPID from docID and return it.
311 * (If a sectionNumber is suffixed to the docID, the docPID which is
312 * the prefix is returned; otherwise the docID is the docPID and is
313 * returned)
314 * @param docID is the String that contains the docPID and may also
315 * contain the section number.
316 * @return only the docPID portion of the docID.
317 */
318 protected String getDocPIDFromDocID(String docID) {
319 if(containsSectionNumber(docID))
320 return docID.substring(0, docID.lastIndexOf(HYPHEN));
321 // else (if there's no sectionNumber), docID is the docPID
322 return docID;
323 }
324
325 /** This method will return the section Number, if there's any
326 * suffixed to the docID. Otherwise it will return the empty string
327 * @param docID is the String that contains the docPID and may also
328 * contain the section number.
329 * @return only the sectionID portion of the docID - if any, else "".
330 */
331 protected String getSectionIDFromDocID(String docID) {
332 if(containsSectionNumber(docID))
333 return docID.substring(
334 docID.lastIndexOf(HYPHEN)+1, docID.length());
335 return "";
336 }
337
338 /** Given a list of collectionIDs, returns a GS3 DocumentMetadataRetrieve
339 * response message that gives the metadata for each collection identified
340 * @param collIDs is an array of fedora pids identifying collections in the
341 * fedora repository
342 * @return a GS3 DocumentMetadataRetrieve response message containing the
343 * EX metadata for all the requested collections */
344 public String getCollectionMetadata(String[] collIDs) {
345 return getMetadata(collIDs);
346 }
347
348 /** Given a list of document identifiers, a GS3 DocumentMetadataRetrieve
349 * response message is returned containing the metadata for each document.
350 * @param docIDs is an array of document identifiers (docID can either be
351 * &lt;pid&gt;s items (documents) in the fedora repository, or
352 * "&lt;pid&gt;-sectionNumber".
353 * @return a GS3 DocumentMetadataRetrieve response message containing the
354 * EX, DC, DLS metadata for all the requested documents */
355 public String getDocumentMetadata(String[] docIDs) {
356 return getMetadata(docIDs);
357 }
358
359 /** Given a collectionID, returns a GS3 DocumentMetadataRetrieve
360 * response message that gives the metadata for the collection identified
361 * @param collID is a fedora pid identifying a collection in its repository
362 * @return a GS3 DocumentMetadataRetrieve response message containing the
363 * EX metadata for the requested collection */
364 public String getCollectionMetadata(String collID) {
365 return getMetadata(new String[] {collID});
366 }
367
368 /** Given a document identifier, returns a GS3 DocumentMetadataRetrieve
369 * response message containing the metadata for the document.
370 * @param docID is a document identifier (docID can either be a &lt;pid&gt;
371 * of an item (document) in the fedora repository, or it can be
372 * "&lt;pid&gt;-sectionNumber".
373 * @return a GS3 DocumentMetadataRetrieve response message containing the
374 * EX, DC, DLS metadata for the requested document */
375 public String getDocumentMetadata(String docID) {
376 return getMetadata(new String[] {docID});
377 }
378
379 /** @return a greenstone DocumentMetadataRetrieve response for the
380 * documents or collections indicated by the docIDsOrCollIDs.
381 * @param docIDsOrCollIDs is an array of identifiers which may be either the
382 * fedora pids for collections, or otherwise may be a document identifier.
383 * In the last case, the document ID may consist of either
384 * "documentPID-sectionNumber" or may just be just fedora documentPID */
385 public String getMetadata(String[] docIDsOrCollIDs)
386 {
387 Document doc = builder.newDocument();
388 FedoraGS3RunException ex = null;
389
390 Element docNodeList = doc.createElement(
391 GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
392
393 try{
394 for(int i = 0; i < docIDsOrCollIDs.length; i++) {
395 // create the <documentNode> containing the metadata
396 // for each document docID
397 Element docNode = getMetadata(doc, docIDsOrCollIDs[i]);
398 docNodeList.appendChild(docNode);
399 }
400 } catch(Exception e) {
401 ex = new FedoraGS3RunException(e);
402 ex.setSpecifics("EX (and/or DC, DLS) metadata datastream");
403 }
404
405 Element responseMsg = createResponseMessage(doc, docNodeList, ex,
406 GSXML.REQUEST_TYPE_PROCESS, "DocumentMetadataRetrieve");
407 try{
408 return FedoraCommons.elementToFormattedString(responseMsg);
409 } catch(TransformerException e) {
410 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg
411 + " " + e;
412 }
413 }
414
415 /** Method that takes a new DOM document, as well as an identifier of either
416 * a collection or document (which may be a fedora pid for the collection
417 * or document, or may be the documentPid-sectionNumber for a document) and
418 * returns a documentNode element for it:
419 * &lt;documentNode&gt;&lt;metadataList&gt;
420 * &lt;metadata name=""&gt;value&lt;/metadata&gt;
421 * ...
422 * &lt;/metadataList&gt;&lt;/documentNode&gt;
423 * @return documentNode containing the metadata for the collection or
424 * document given by parameter ID
425 * @param id denotes a collection pid, a document pid or a docID of the
426 * form "documentpid-sectionNumber" */
427 protected Element getMetadata(Document doc, String id)
428 throws RemoteException, UnsupportedEncodingException,
429 SAXException, IOException
430 {
431 // We're going to create the documentNode nested inside the following
432 // documentNodeList:
433 // <documentNodeList>
434 // <documentNode nodeID=""><metadataList>
435 // <metadata name="">value</metadata>
436 // </metadataList></documentNode>
437 // <documentNode>...</documentNode>
438 // </documentNodeList>
439 // <documentNodeList>
440
441 // <documentNode nodeID="docID"> - the docNode on which a structure
442 // retrieve is being performed
443 Element docNode = doc.createElement(GSXML.DOC_NODE_ELEM);
444 Attr attribute = doc.createAttribute(GSXML.NODE_ID_ATT);
445 attribute.setValue(id);
446 docNode.setAttributeNode(attribute);
447
448 // <metadataList>
449 Element metadataList = doc.createElement(
450 GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
451
452 String ex = "";
453 String dc = "";
454 String dls = "";
455 if(id.endsWith(_COLLECTION)) { // docID refers to a collection
456 // Obtain the "EX" datastream (extracted metadata) for the collection
457 ex = this.getEX(id);
458 }
459 else { // docID refers to a document
460 // work out the document's fedora PID and section ID, and then
461 // obtain the EX (extracted metadata) and DC datastreams for the doc
462
463 // Note that EX/DC for pid="greenstone:<colname>-docPID-1"
464 // is the same as for pid="greenstone:<colname>-docPID"
465 // That is, <Section id="1"> refers to the toplevel document docPID
466 // If requested for top-level document, there may also be DLS meta
467 String sectionID = getSectionIDFromDocID(id);
468 String docPID = getDocPIDFromDocID(id);
469 if(sectionID.equals("") || sectionID.equals("1")) {
470 //metadata of toplevel document is requested
471 ex = this.getEX(docPID); // slightly faster than doing
472 //getSectionEXMetadata(docID, "1")
473 dc = this.getDC(docPID);
474 dls = this.getDLS(docPID);
475 }
476 else {
477 ex = getSectionEXMetadata(docPID, sectionID);
478 dc = getSectionDCMetadata(docPID, sectionID);
479 }
480 }
481
482 // Adding in metadata sets in alphabetical order
483 // DC metadata for a top-level document is different from EX, DLS:
484 // only the element's namespace prefix is "dc", the rest of a tagname
485 // is unknown.
486 if(!dc.equals("")) {
487 addMetadataWithNamespacedTagNames(doc, metadataList,
488 dc, DC);
489 }
490
491 // Check if we were supposed to process dls and dc metadata
492 // as well. We only ever do this for top-level documents,
493 // in which case, dls and dc will be non-empty strings
494 if(!dls.equals("")) {
495 addMetadataWithFixedTagName(doc, metadataList, dls, DLS);
496 }
497
498 // we definitely have an EX metadatastream for each
499 // collection object, top-level document object,
500 // and document section item
501 addMetadataWithFixedTagName(doc, metadataList, ex, EX);
502
503 // now the metadataList has been built up
504 docNode.appendChild(metadataList);
505
506 return docNode; // return <documentNode> containing the metadata
507 }
508
509 /** This method retrieves all the metadata elements in the metaDataStream
510 * parameter of the form &lt;"metadataSetNS:metadata"&gt;"value"&lt;/metadata&gt; where
511 * metadataSetNS is the namespace of each tag, and creates a new element of
512 * the form &lt;metadata name="metadataSetNS:metadata"&gt;"value"&lt;/metadata&gt; for
513 * each. Each of these are then appended to the metadataList parameter.
514 * @param doc is the Document object using which the new metadata Elements
515 * are to be constructed
516 * @param metadataList is the &lt;metadataList&gt; Element to which the new
517 * metadata Elements are to be appended as children.
518 * @param metaDatastream the metadata datastream in string form (e.g. the
519 * Dublin Core metadata stored in the Fedora repository).
520 * @param metadataSet is the constant datastream identifier, e.g. "DC".
521 * At present this method only applies to the DC metadata as that's the only
522 * one where each tagname is different except for the constant dc: namespace.
523 */
524 protected void addMetadataWithNamespacedTagNames(Document doc,
525 Element metadataList, String metaDatastream, String metadataSet)
526 throws SAXException, IOException
527 {
528 Document src = builder.parse(
529 new InputSource(new StringReader(metaDatastream)));
530
531 // The following doesn't work for some reason: to retrieve all elements
532 // whose namespace prefix starts with "dc", we pass "*" for localName
533 //NodeList dcMetaTags = src.getElementsByTagNameNS(DC.toLowerCase(), "*");
534
535 // Longer way: get the children of the root document
536 NodeList children = src.getDocumentElement().getChildNodes();
537
538 for(int i = 0; i < children.getLength(); i++) {
539 String nodeName = children.item(i).getNodeName();
540 // check that the nodename starts with the "dc" namespace,
541 // which simultaneously ensures that the node's an element:
542 if(nodeName.startsWith(DC.toLowerCase())) {
543 // need to have a period for Greenstone instead of Fedora's colon
544 nodeName = nodeName.replace(COLON, PERIOD);
545 Element metatag = (Element)children.item(i);
546 String value = FedoraCommons.getValue(metatag);
547 // <dc:tagname>value</dc:tagname>
548 // we're going to put use this in our metadata element as
549 // <metadata name="dc:tagname">value</metadata>
550
551 // create metadata of (name, value) pairs in target DOM (doc)
552 Element metadata = doc.createElement(GSXML.METADATA_ELEM);
553 Attr attribute = doc.createAttribute(GSXML.NAME_ATT);
554 attribute.setValue(nodeName);
555 metadata.setAttributeNode(attribute);
556 Text content = doc.createTextNode(value);
557 metadata.appendChild(content);
558 metadataList.appendChild(metadata);
559 }
560 }
561 }
562
563 /** This method retrieves all the metadata elements in the metaDataStream
564 * of the form &lt;"namespace:"metadata name="metadataName"&gt;value&lt;/metadata&gt;
565 * where "namespace" is the namespace prefix of each tag, and metadataName
566 * is the name of the metadata (like author, title). For each element
567 * it creates a corresponding new element of the form
568 * &lt;metadata name="namespace:metadataName"&gt;value&lt;/metadata&gt;. Each of these
569 * are then appended to the metadataList parameter.
570 * @param doc is the Document object using which the new metadata Elements
571 * are to be constructed
572 * @param metadataList is the &lt;metadataList&gt; Element to which the new
573 * metadata Elements are to be appended as children.
574 * @param metaDatastream the metadata datastream in string form (e.g. the
575 * EX/Greenstone extracted metadata or DLS metadata stored in the Fedora
576 * repository).
577 * @param metadataSet is the constant datastream identifier,
578 * e.g. "DLS" or "EX".
579 * At present this method applies to the DLS and EX metadata as they have
580 * constant tagnames throughout.
581 */
582 protected void addMetadataWithFixedTagName(Document doc,
583 Element metadataList, String metaDatastream, String metadataSet)
584 throws SAXException, IOException
585 {
586 // Namespace prefix can be "ex:" or "dls:"
587 String namespacePrefix = "";
588 if(!metadataSet.equals(EX)) {
589 // need to have a period for Greenstone instead of Fedora's colon
590 namespacePrefix = metadataSet.toLowerCase() + PERIOD;
591 }
592
593 Document src = builder.parse(
594 new InputSource(new StringReader(metaDatastream)));
595 NodeList metaTags = src.getElementsByTagName(
596 metadataSet.toLowerCase()+COLON+METADATA);
597 // Looking for tagnames: <ex:metadata> or <dls:metadata>
598
599 for(int i = 0; i < metaTags.getLength(); i++) {
600 Element metatag = (Element)metaTags.item(i);
601
602 // extract the metadata of (name, value) pairs from src DOM
603 // look for <metadata name="name">value</metadata>
604 String name = metatag.hasAttribute(NAME) ?
605 metatag.getAttribute(NAME) : "";
606 // sometimes, there are several metadata for the same name, in this
607 // case, look for a qualifier and append its value to the name to
608 // distinguish it uniquely:
609 if(metatag.hasAttribute(QUALIFIER)) {
610 name = name + HYPHEN + metatag.getAttribute(QUALIFIER);
611 }
612 String value = FedoraCommons.getValue(metatag);
613
614 // create metadata of (name, value) pairs in target DOM (doc)
615 Element metadata = doc.createElement(GSXML.METADATA_ELEM);
616 Attr attribute = doc.createAttribute(GSXML.NAME_ATT);
617 attribute.setValue(namespacePrefix + name);
618 // prefix with namespace, if any
619 metadata.setAttributeNode(attribute);
620 Text content = doc.createTextNode(value);
621 metadata.appendChild(content);
622
623 metadataList.appendChild(metadata);
624 }
625 }
626
627 /** Given a document identifier, returns a GS3 DocumentMetadataRetrieve
628 * response message containing ONLY the Title metadata for the document.
629 * @param docID is a document identifier (docID can either be a &lt;pid&gt;
630 * of an item (document) in the fedora repository, or it can be
631 * "&lt;pid&gt;-sectionNumber".
632 * @return a GS3 DocumentMetadataRetrieve response message containing the
633 * Title metadata for the requested document */
634 public String getTitleMetadata(String docID) {
635 return getTitleMetadata(new String[] { docID });
636 }
637
638 /** Given a document identifier, returns a GS3 DocumentMetadataRetrieve
639 * response message containing ONLY the Title metadata for the documents.
640 * @param docIDs is a list of document identifiers (where docID can either be
641 * a &lt;pid&gt; of an item (document) in the fedora repository, or it can be
642 * "&lt;pid&gt;-sectionNumber".
643 * @return a GS3 DocumentMetadataRetrieve response message containing the
644 * Title metadata for all the requested documents */
645 public String getTitleMetadata(String[] docIDs) {
646 // Must create message of the following form:
647 // <documentNodeList><documentNode nodeID="docID">
648 // <metadataList><metadata name="Title">sometitle</metadata>
649 // </metadataList></documentNode>
650
651 Document doc = builder.newDocument();
652 FedoraGS3RunException ex = null;
653
654 Element docNodeList = doc.createElement(
655 GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
656 try{
657 for(int i = 0; i < docIDs.length; i++) {
658 Element docNode = getTitleMetadata(doc, docIDs[i]);
659 docNodeList.appendChild(docNode);
660 }
661 }catch(Exception e) {
662 ex = new FedoraGS3RunException(e);
663 ex.setSpecifics("EX metadata datastream");
664 }
665
666 Element responseMsg = createResponseMessage(doc, docNodeList, ex,
667 GSXML.REQUEST_TYPE_PROCESS, "DocumentMetadataRetrieve");
668 try{
669 return FedoraCommons.elementToFormattedString(responseMsg);
670 } catch(TransformerException e) {
671 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg
672 + " " + e;
673 }
674 }
675
676 /** Method that takes a new DOM document, as well as an identifier of either
677 * a document or document section and returns a documentNode element containing
678 * the title metadata for it:
679 * &lt;documentNode nodeID="docID"&gt;&lt;metadataList&gt;
680 * &lt;metadata name="Title"&gt;sometitle&lt;/metadata&gt;
681 * &lt;/metadataList&gt;&lt;/documentNode&gt;
682 * @return documentNode containing the metadata for the collection or
683 * document given by parameter ID
684 * @param docID denotes the id of a document or a document section, so id
685 * is either a document-pid or it's of the form documentpid-sectionNumber */
686 protected Element getTitleMetadata(Document doc, String docID)
687 throws RemoteException, UnsupportedEncodingException,
688 SAXException, IOException
689 {
690 // Returns a docNode element of the following form:
691 // <documentNode nodeID="docID">
692 // <metadataList><metadata name="Title">sometitle</metadata></metadataList>
693 // </documentNode>
694
695 // <documentNode nodeID="docID">
696 Element docNode = doc.createElement(GSXML.DOC_NODE_ELEM);
697 Attr attribute = doc.createAttribute(GSXML.NODE_ID_ATT);
698 attribute.setValue(docID);
699 docNode.setAttributeNode(attribute);
700
701 // <metadataList>
702 Element metaList = doc.createElement(
703 GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
704 // <metadata name="Title">
705 Element metadata = doc.createElement(GSXML.METADATA_ELEM);
706 // if we connect it all up (append children), we can immediately add
707 // the name attribute into the metadata element:
708 metaList.appendChild(metadata);
709 docNode.appendChild(metaList);
710 metadata.setAttribute(GSXML.NAME_ATT, TITLE); // immediately add attribute
711
712 String title = "";
713 String sectionID = getSectionIDFromDocID(docID);
714 String docPID = getDocPIDFromDocID(docID);
715
716 // check if title of toplevel document is requested
717 if(sectionID.equals(""))
718 title = this.getDocTitle(docPID);
719 else { // title of document section
720 title = this.getSectionTitle(docPID, sectionID);
721 }
722
723 metadata.appendChild(doc.createTextNode(title));
724
725 return docNode;
726 }
727
728
729 /** @return the documentStructure of the document or section given by docID.
730 * The structure is returned in the XML format of a Greenstone3
731 * DocumentStructureRetrieve response message. This method returns the entire
732 * subSection of the docID (that is, all descendants included).
733 * @param docID the identifier for the document whose structure is required.
734 * This is of the format "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;"
735 * OR "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;-&lt;sectioNumber&gt;"
736 * where "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;-1" is the same as
737 * "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;" and will return the
738 * same response */
739 public String getDocumentStructure(String docID) {
740 return getStructure(new String[]{docID}, DESCENDANTS);
741 }
742
743 /** @return a view of the structure of the document or section given by docID
744 * which contains only the section and its direct children. This structure is
745 * returned in the XML format of a Greenstone3 DocumentStructureRetrieve
746 * response message.
747 * @param docID the identifier for the document whose structure is required.
748 * This is of the format "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;"
749 * OR "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;-&lt;sectioNumber&gt;"
750 * where "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;-1" is the same as
751 * "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;" and will return the
752 * same response */
753 public String getChildren(String docID) {
754 return getStructure(new String[]{docID}, CHILDREN);
755 }
756
757 /** @return the documentStructure of the documents or sections given by docIDs.
758 * The structure is returned in the XML format of a Greenstone3
759 * DocumentStructureRetrieve response message. This method returns the entire
760 * subSection of each docID (that is, all descendants included).
761 * @param docIDs is an array of identifiers for the documents whose structures
762 * are required.
763 * This is of the format "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;"
764 * OR "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;-&lt;sectioNumber&gt;"
765 * where "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;-1" is the same as
766 * "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;" and will return the
767 * same response */
768 public String getDocumentStructure(String[] docIDs) {
769 return getStructure(docIDs, DESCENDANTS);
770 }
771
772 /** @return the documentStructure of the documents or sections given by docIDs
773 * but only the sections and their children (not any further descendants).
774 * The structure is returned in the XML format of a Greenstone3
775 * DocumentStructureRetrieve response message.
776 * @param docIDs the identifiers for the documents whose structures are
777 * required. The docids are of the format "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;"
778 * OR "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;-&lt;sectioNumber&gt;"
779 * where "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;-1" is the same as
780 * "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;" and will return the
781 * same response */
782 public String getChildren(String[] docIDs) {
783 return getStructure(docIDs, CHILDREN);
784 }
785
786 /**
787 * Returns a greenstone3 DocumentStructureRetrieve XML response message
788 * containing the document structures for the given docIDs.
789 * Similar to FedoraConnection.getTOC(), but instead of fedora formatted XML,
790 * greenstone formatted XML is returned. The requested section of the table
791 * of contents (TOC) for a document is converted into the greenstone3 xml
792 * format that is returned upon DocumentStructureRetrieve requests.
793 * @param docIDs the documentIDs for which the section's structure is returned;
794 * where a docID is either a fedora pid &lt;docPID&gt; or &lt;docPID&gt;-&lt;sectionNumber&gt;.
795 * @param levels - either CHILDREN or DESCENDANTS.
796 * CHILDREN returns only the first-level descendants (children) of the
797 * requested document sections indicated by docIDs.
798 * DESCENDANTS returns all descendants of all the document-sections denoted by
799 * docIDs.
800 * @return a greenstone3 DocumentStructureRetrieve XML response message in
801 * String format with the structure of the docIDs requested.
802 */
803 protected String getStructure(String[] docIDs, int levels)
804 {
805 Document doc = builder.newDocument();
806 FedoraGS3RunException ex = null;
807 // <documentNodeList>
808 Element docNodeList = doc.createElement(
809 GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
810
811 try{
812 // append the <documentNodes> for the docIDs
813 // to the docNodeList
814 getStructureElement(docNodeList, docIDs, levels);
815 } catch(Exception e) {
816 ex = new FedoraGS3RunException(e);
817 ex.setSpecifics("(requested portion of) TOC datastream");
818 }
819 // insert our <documentNodeList> into a GS3 response message
820 Element responseMsg = createResponseMessage(doc, docNodeList, ex,
821 GSXML.REQUEST_TYPE_PROCESS, "DocumentStructureRetrieve");
822 try{
823 return FedoraCommons.elementToFormattedString(responseMsg);
824 } catch(TransformerException e) {
825 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg
826 + " " + e;
827 }
828 }
829
830 /** Given a &lt;documentNodeList&gt; portion of a greenstone3
831 * DocumentStructureRetrieve XML response message, this method will populate
832 * it with the &lt;documentNodes&gt; that represent the structure of the given docIDs.
833 * @param docNodeList is a &lt;documentNodeList&gt; to which &lt;documentNodes&gt; of
834 * the doc structures are appended.
835 * @param docIDs the documentIDs for which the section's structure is returned;
836 * where a docID is either a fedora pid &lt;docPID&gt; or &lt;docPID&gt;-&lt;sectionNumber&gt;.
837 * @param levels - either CHILDREN or DESCENDANTS.
838 * CHILDREN returns only the first-level descendants (children) of the
839 * requested document sections indicated by docIDs.
840 * DESCENDANTS returns all descendants of all the document-sections denoted by
841 * docIDs.
842 */
843 protected void getStructureElement(Element docNodeList,
844 String[] docIDs, int levels)
845 throws RemoteException, UnsupportedEncodingException, SAXException,
846 IOException
847 {
848 // process each docID
849 for(int i = 0; i < docIDs.length; i++) {
850 // work out the document's fedora PID and section ID
851 String sectionID = getSectionIDFromDocID(docIDs[i]);
852 String docPID = getDocPIDFromDocID(docIDs[i]);
853
854 // get the required section, along with children or descendants
855 Element srcDocElement = null;
856 if(levels == CHILDREN) // get the requested section with its children
857 srcDocElement = this.getChildrenOfSectionXML(docPID, sectionID);
858 else // levels == DESCENDANTS, get the section with all its descendants
859 srcDocElement = this.getSubsectionXML(docPID, sectionID);
860
861 // copy-and-convert that structure into a structure format for GS3
862 Element docNode = getStructure(docNodeList.getOwnerDocument(),
863 docIDs[i], docPID, srcDocElement);
864
865 // add it to our list of documentNodes
866 docNodeList.appendChild(docNode);
867 }
868 }
869
870 /**
871 * Takes the portion of the XML document outlining the structure of the
872 * document (section)--in the format this is stored in Fedora--and returns
873 * Greenstone 3 DOM XML format for outlining document structure.
874 * @return a &lt;documentNode&gt; element that contains a greenstone3
875 * DocumentStructureRetrieve XML corresponding to the parameter Element section
876 * (which is in fedora XML), for the document indicated by docID.
877 * @param requestingDocID is the identifier of the document for which the
878 * structure was requested. It's this document's children or descendants that
879 * will be returned. Note that this is not always the same as (clear from)
880 * parameter docID.
881 * @param docID is the documentID for which the section's structure is
882 * returned where docID = "docPID-sectionNumber".
883 * @param section - the fedora section XML that is being mirrored in
884 * greenstone3 format.
885 */
886 protected Element getStructure(Document doc, String requestingDocID,
887 String docID, Element section)
888 {
889 // we want to mirror the section's DOM (given in fedora XML) in
890 // greenstone3's XML for a DocumentStructureRetrieve response.
891
892 // <documentNode nodeID="docID"> - the docNode on which a structure retrieve
893 // is being performed
894 Element docNode = doc.createElement(GSXML.DOC_NODE_ELEM);
895 Attr attribute = doc.createAttribute(GSXML.NODE_ID_ATT);
896 attribute.setValue(requestingDocID); //requestingDocID.replace(HYPHEN+SECTION, "")
897 docNode.setAttributeNode(attribute);
898
899 // <nodeStructure>
900 Element nodeStructure = doc.createElement(GSXML.NODE_STRUCTURE_ELEM);
901
902 // <documentNode nodeID="docID" docType="hierarchy" nodeType="root">
903 Element rootNode = createDocNodeFromSubsection(doc, section, docID);
904
905 // fills in the subtree of the rootNode in our nodeStructure element
906 createDocStructure(doc, section, rootNode, docID);
907 //where section represents the root section
908
909 nodeStructure.appendChild(rootNode);
910 docNode.appendChild(nodeStructure);
911 return docNode;
912 }
913
914 /** Recursive method that creates a documentStructure mirroring parameter
915 * section, starting from parameter parent down to all descendants
916 * @param section is the XML &lt;Section&gt; in the fedora repository's TOC
917 * for the docPID whose substructure is to be mirrored
918 * @param parent is the XML documentNode in the greenstone repository whose
919 * descendants created by this method will correspond to the descendants of
920 * parameter section.
921 * @param doc is the document containing the parent;
922 * @param docPID is the prefix of all nodeIDs in the parent's structure
923 */
924 protected void createDocStructure(
925 Document doc, Element section, Element parent, String docPID)
926 {
927 // get the section's children (if any)
928 NodeList children = section.getChildNodes();
929 for(int i = 0; i < children.getLength(); i++) {
930 Node n = children.item(i);
931
932 if(n.getNodeName().equals(SECTION_ELEMENT)) {
933 //then we know it's an element AND that its tagname is "Section"
934 Element subsection = (Element)n;
935 Element child = createDocNodeFromSubsection(doc, subsection, docPID);
936 parent.appendChild(child);
937
938 // recursion call on newly found child-element and subsection
939 createDocStructure(doc, subsection, child, docPID);
940 }
941 }
942 }
943
944 /** Given a particular subsection element, this method creates a
945 * Greenstone3 DocumentNode element that mirrors it.
946 * @param doc is the document that will contain the created DocumentNode
947 * @param docID is the prefix of all nodeIDs in the parent's structure
948 * @param subSection is the XML &lt;Section&gt; in the fedora repository's
949 * TOC for the docPID which will be mirrored in the greenstone XML
950 * documentNode that will be returned.
951 * @return a greenstone &lt;documentNode&gt; that represents the fedora TOC's
952 * &lt;Section&gt; element passed as parameter subSection. */
953 protected Element createDocNodeFromSubsection(
954 Document doc, Element subSection, String docID)
955 {
956 Element docNode = doc.createElement(GSXML.DOC_NODE_ELEM);
957 Attr docType = doc.createAttribute(GSXML.DOC_TYPE_ATT);
958 docType.setValue(GSXML.DOC_TYPE_HIERARCHY);
959 docNode.setAttributeNode(docType);
960
961 Attr nodeID = doc.createAttribute(GSXML.NODE_ID_ATT);
962 String sectionID = subSection.hasAttribute(ID) ?
963 subSection.getAttribute(ID) : "";
964 nodeID.setValue(docID + HYPHEN + sectionID);
965 docNode.setAttributeNode(nodeID);
966
967 Attr nodeType = doc.createAttribute(GSXML.NODE_TYPE_ATT);
968 if(sectionID.equals("1")) { // root case
969 nodeType.setValue(GSXML.NODE_TYPE_ROOT);
970 // reset the attribute without the section number
971 docNode.setAttribute(GSXML.NODE_ID_ATT, docID);
972 }
973 else if(subSection.getElementsByTagName(SECTION_ELEMENT).getLength() > 0)
974 // this section has further <Section> children, so it's an internal node
975 nodeType.setValue(GSXML.NODE_TYPE_INTERNAL);
976 else if(subSection.hasAttribute(TYPE))
977 nodeType.setValue(GSXML.NODE_TYPE_INTERNAL);
978 else // leaf
979 nodeType.setValue(GSXML.NODE_TYPE_LEAF);
980 docNode.setAttributeNode(nodeType);
981 return docNode;
982 }
983
984
985 /** Given an identifier that is either a docPID or a concatenation of
986 * docPID+sectionID, this method works out the fedora assigned docPID and
987 * sectionID and then calls getContentBody(docPID, sectionID) with those.
988 * @param docID is expected to be of the form
989 * "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;-&lt;sectionNumber&gt;" or
990 * "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;"
991 * If it is "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;", then the content for
992 * "greenstone:&lt;collectionName&gt;-1" ("greenstone:&lt;collectionName&gt;-Section1")
993 * is returned! */
994 public String getContent(String docID) {
995 return this.getContent(new String[]{docID});
996 }
997
998 /** Given an identifier that is a concatenation of docID+sectionID, this
999 * method works out the fedora assigned docPID and sectionID and then calls
1000 * getContentBody(docPID, sectionID) with those.
1001 * @param docIDs is an array of document identifiers of the form
1002 * "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;-&lt;sectionNumber&gt;"
1003 * If it is "greenstone:&lt;collectionName&gt;-&lt;docPID&gt;", then the content for
1004 * "greenstone:&lt;collectionName&gt;-Section1" is returned! */
1005 public String getContent(String[] docIDs) {
1006 Document doc = builder.newDocument();
1007 FedoraGS3RunException ex = null;
1008
1009 //<documentNodeList>
1010 Element docNodeList = doc.createElement(
1011 GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
1012
1013 try{
1014 for(int i = 0; i < docIDs.length; i++) {
1015 // get the sectionID and docPID from the docID
1016 String sectionID = this.removePrefix(
1017 getSectionIDFromDocID(docIDs[i]), SECTION);
1018 String docPID = getDocPIDFromDocID(docIDs[i]);
1019 if(sectionID.equals("")) // if no section is specified, get
1020 sectionID = "1"; // get the content for Section id="1"
1021
1022 // Get the contents for the requested section of document docPID
1023 String sectionContent = this.getContentBody(docPID, sectionID);
1024
1025 // set the nodeID attribute
1026 Element docNode = doc.createElement(GSXML.DOC_NODE_ELEM);
1027 Attr nodeId = doc.createAttribute(GSXML.NODE_ID_ATT);
1028
1029 nodeId.setValue(docIDs[i]); // just set the docID which will contain
1030 // the docPID (and sectionID if already present)
1031
1032 docNode.setAttributeNode(nodeId);
1033 // set the text content to what was retrieved
1034 Element nodeContent = doc.createElement(GSXML.NODE_CONTENT_ELEM);
1035 Text textNode = doc.createTextNode(sectionContent);
1036
1037 nodeContent.appendChild(textNode);
1038 docNode.appendChild(nodeContent);
1039 //add the documentNode to the docNodeList
1040 docNodeList.appendChild(docNode);
1041 }
1042 } catch(Exception e) {
1043 ex = new FedoraGS3RunException(e);
1044 ex.setSpecifics("requested doc Section datastream");
1045 }
1046 Element responseMsg = createResponseMessage(doc, docNodeList, ex,
1047 GSXML.REQUEST_TYPE_PROCESS, "DocumentContentRetrieve");
1048 try{
1049 return FedoraCommons.elementToFormattedString(responseMsg);
1050 } catch(TransformerException e) {
1051 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg
1052 + " " + e;
1053 }
1054 }
1055
1056 /** Gets the contents of a textNode from a section.
1057 * @return the text content of a section.
1058 * @param docPID the pid of the document from which a section's text is to
1059 * be retrieved.
1060 * @param sectionID is the section identifier of the document denoted by
1061 * docPID whose text is to be returned.
1062 */
1063 protected String getContentBody(String docPID, String sectionID)
1064 throws RemoteException, UnsupportedEncodingException,
1065 SAXException, IOException
1066 {
1067 String section = this.getSection(docPID, sectionID);
1068
1069 // the content is nested inside a <Section> element,
1070 // we extract it from there:
1071 InputSource source = new InputSource(new StringReader(section));
1072 Document doc = builder.parse(source);
1073
1074 // The document Element is the <Section> we want.
1075 // Get its text contents:
1076 section = FedoraCommons.getValue(doc.getDocumentElement());
1077
1078 // we are going to remove all occurrences of "_httpdocimg_/"
1079 // that precede associated filenames, because that's a GS3
1080 // defined macro for resolving relative urls. It won't help
1081 // with documents stored in fedora.
1082 section = section.replaceAll(GS3FilePathMacro+"/", "");
1083 return section;
1084 }
1085
1086 /** Here we create the greenstone's response message element:
1087 * &lt;message&lg;&lt;response&gt;&lt;content&gt;&lt;/response&gt;&lt;/message&gt;
1088 * @return a greenstone response-message element.
1089 * @param doc - the Document object which should me used to create the
1090 * &lt;message&gt; and &lt;response&gt; elements
1091 * @param content - the element that is to be nested inside &lt;response&gt;
1092 * @param ex - any exception that occurred when trying to create
1093 * the content parameter
1094 * @param responseType - the value for the type attribute of &lt;response&gt;,
1095 * such as "describe", "retrieve", "browse", "query"...
1096 * @param originator - indiates the collectionName or service (like
1097 * DocumentContentRetrieve) from where this response message originates
1098 */
1099 protected Element createResponseMessage(Document doc, Element content,
1100 Exception ex, String responseType, String originator)
1101 {
1102 Element response = doc.createElement(GSXML.RESPONSE_ELEM);
1103 // from = "FedoraGS3"
1104 Attr attribute = doc.createAttribute(GSXML.FROM_ATT);
1105 String from = originator.equals("") ? FEDORA_GS3
1106 : FEDORA_GS3+"/"+originator;
1107
1108 attribute.setValue(from);
1109 response.setAttributeNode(attribute);
1110
1111 // type = "describe" or "process" - whatever's given in requestType:
1112 attribute = doc.createAttribute(GSXML.TYPE_ATT);
1113 attribute.setValue(responseType);
1114 response.setAttributeNode(attribute);
1115
1116 if(content != null)
1117 response.appendChild(content);
1118
1119 // we'll create an error element for RemoteExceptions (web service problems)
1120 // and UnsupportedEncodingExceptions and
1121 if(ex != null) {
1122 Element error = doc.createElement(GSXML.ERROR_ELEM);
1123 error.appendChild(doc.createTextNode(ex.getMessage()));
1124 // now append the error to the <response> element (after
1125 // the content element whatever that was)
1126 response.appendChild(error);
1127 }
1128
1129 Element message = doc.createElement(GSXML.MESSAGE_ELEM);
1130 message.appendChild(response);
1131 doc.appendChild(message);
1132 return message;
1133 }
1134
1135 /** @return a &lt;serviceList&gt; Element as defined by GS3: containing all the
1136 * services (denoted by &lt;service&gt; elements) that are supported by FedoraGS3.
1137 * At present these are: DocumentContentRetrieve, DocumentMetadataRetrieve,
1138 * DocumentStructureRetrieve, TextQuery, FieldQuery, ClassifierBrowse,
1139 * ClassifierBrowseMetadataRetrieve (as indicated by member var serviceNames).
1140 * @param doc - the Document object which should me used to create the
1141 * &lt;serviceList&gt; element */
1142 protected Element createServiceList(Document doc)
1143 {
1144 Element serviceList = doc.createElement(
1145 GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER);
1146
1147 for(int i = 0; i < serviceNames.length; i++) {
1148 // create the <service name="serviceName[i]" type="servicetype" />
1149 Element service = doc.createElement(GSXML.SERVICE_ELEM);
1150
1151 Attr attribute = doc.createAttribute(GSXML.NAME_ATT);
1152 attribute.setValue(serviceNames[i]);
1153 service.setAttributeNode(attribute);
1154
1155 attribute = doc.createAttribute(GSXML.TYPE_ATT);
1156 if(serviceNames[i].equals("ClassifierBrowse")) //browseTitlesByLetter
1157 attribute.setValue(GSXML.SERVICE_TYPE_BROWSE);
1158 else if(serviceNames[i].contains("Query")) // search services
1159 attribute.setValue(GSXML.SERVICE_TYPE_QUERY);
1160 else
1161 attribute.setValue(GSXML.SERVICE_TYPE_RETRIEVE);
1162 service.setAttributeNode(attribute);
1163
1164 // add the service element to the serviceList element
1165 // <serviceList><service /></serviceList>
1166 serviceList.appendChild(service);
1167 }
1168 return serviceList;
1169 }
1170
1171 /** @return a GS3 response message for a describe services request:
1172 * indicating the list of services supported by the Fedora-Greenstone
1173 * interface. These are DocumentContentRetrieve, DocumentMetadataRetrieve,
1174 * DocumentStructureRetrieve, ClassifierBrowse, TextQuery, FieldQuery,
1175 * ClassifierBrowseMetadataRetrieve - as indicated by member variable
1176 * serviceNames. */
1177 public String getServiceList()
1178 {
1179 Document doc = builder.newDocument();
1180 Element serviceList = createServiceList(doc);
1181 // make <serviceList> the body of the responseMessage:
1182 // <message><response><serviceList></response></message>
1183 Element responseMsg = createResponseMessage(doc, serviceList, null,
1184 GSXML.REQUEST_TYPE_DESCRIBE, "");
1185 try {
1186 return FedoraCommons.elementToFormattedString(responseMsg);
1187 }catch(TransformerException e) {
1188 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg
1189 + " " + e;
1190 }
1191 }
1192
1193 /** @return a GS3 describe response message listing the collections and
1194 * collection-specific metadata stored in the Fedora-Greenstone repository. */
1195 public String getCollectionList()
1196 {
1197 Document doc = builder.newDocument();
1198 FedoraGS3RunException ex = null; // any RemoteException
1199
1200 // create the <collectionList /> element
1201 Element collectionList = doc.createElement(
1202 GSXML.COLLECTION_ELEM+GSXML.LIST_MODIFIER);
1203 try{
1204 String[] collectionNames = this.getCollectionNames(
1205 this.getCollections()); // this line could throw RemoteException
1206 for(int i = 0; i < collectionNames.length; i++) {
1207 // create the <collection name="somename" /> element
1208 Element collection = doc.createElement(GSXML.COLLECTION_ELEM);
1209 Attr attribute = doc.createAttribute(GSXML.NAME_ATT);
1210 attribute.setValue(collectionNames[i]);
1211 collection.setAttributeNode(attribute);
1212
1213 // append the <collection> element as child of <collectionList>
1214 collectionList.appendChild(collection);
1215
1216 //if(collection.hasAttribute(GSXML.NAME_ATT))
1217 //LOG.debug(collection.getAttribute(GSXML.NAME_ATT));
1218 }
1219 } catch(RemoteException e) { // if this happens, perhaps it's because it
1220 // can't find Greenstone collections in fedora repository?
1221 ex = new FedoraGS3RunException(e);
1222 ex.setSpecifics(
1223 "greenstone collections in fedora repository");
1224 }
1225
1226 // make <collectionList> the body of the responseMessage:
1227 // <message><response><collectionList></response></message>
1228 Element responseMsg = createResponseMessage(doc, collectionList, ex,
1229 GSXML.REQUEST_TYPE_DESCRIBE, "");
1230 try{
1231 return FedoraCommons.elementToFormattedString(responseMsg);
1232 }catch(TransformerException e) {
1233 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg
1234 + " " + e;
1235 }
1236 }
1237
1238 /** @return a GS3 describe response message for a collection in the
1239 * Fedora-Greenstone repository.
1240 * @param collectionName - the name of the collection that is to be described.
1241 * It will be converted to a fedora collection pid, which is of the form
1242 * "greenstone:&lt;collectionName&gt;-collection". */
1243 public String describeCollection(String collectionName)
1244 {
1245 Document doc = builder.newDocument();
1246 FedoraGS3RunException ex = null;
1247
1248 Element collection = doc.createElement(GSXML.COLLECTION_ELEM);
1249 Attr attribute = doc.createAttribute(GSXML.NAME_ATT);
1250 attribute.setValue(collectionName);
1251 collection.setAttributeNode(attribute);
1252
1253 //<displayItem assigned="true" lang="en" name="name">
1254 //"some display name"</displayItem>
1255 Element displayItem = doc.createElement(GSXML.DISPLAY_TEXT_ELEM);
1256
1257 attribute = doc.createAttribute(GSXML.LANG_ATT);
1258 attribute.setValue(this.lang);
1259 displayItem.setAttributeNode(attribute);
1260
1261 attribute = doc.createAttribute(GSXML.NAME_ATT);
1262 attribute.setValue(GSXML.DISPLAY_TEXT_NAME);
1263 displayItem.setAttributeNode(attribute);
1264
1265 try{
1266 Text textNode = doc.createTextNode(
1267 this.getCollectionTitle(getCollectionPID(collectionName)));
1268 displayItem.appendChild(textNode);
1269 } catch(Exception e) {
1270 // can't find Greenstone collections in fedora repository or problem
1271 // getting their titles from their metadata datastream?
1272 ex = new FedoraGS3RunException(e);
1273 ex.setSpecifics("greenstone collections or their metadata"
1274 + "in the fedora repository");
1275 }
1276 // now append the displayItem element as child of the collection element
1277 collection.appendChild(displayItem);
1278 // get the <serviceList> and add it into the collection description.
1279 // Services for all collections in the FedoraGS3 repository are the
1280 // same, offering a ClassifierBrowse to browse titles by starting letter
1281 // and DocRetrieve services: Content, Metadata and Structure.
1282
1283 Element serviceList = createServiceList(doc);
1284 collection.appendChild(serviceList);
1285
1286 Element responseMsg = createResponseMessage(doc, collection, ex,
1287 GSXML.REQUEST_TYPE_DESCRIBE, collectionName);
1288 try{
1289 return FedoraCommons.elementToFormattedString(responseMsg);
1290 }catch(TransformerException e) {
1291 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg
1292 + " " + e;
1293 }
1294 }
1295
1296 /** @return a GS3 describe response message for the services of a collection
1297 * in the Fedora-Greenstone repository. So far, these services are the same for
1298 * all fedora collections: they are the services given in member variable
1299 * serviceNames: DocumentContent/Metadata/StructureRetrieve, ClassifierBrowse,
1300 * ClassifierBrowseMetadataRetrieve.
1301 * @param collectionName - the name of the collection whose services are to
1302 * be described. It will be converted to a fedora collection pid, which is of
1303 * the form "greenstone:&lt;collectionName&gt;-collection". */
1304 public String describeCollectionServices(String collectionName)
1305 {
1306 Document doc = builder.newDocument();
1307
1308 Element collection = doc.createElement(GSXML.COLLECTION_ELEM);
1309 Attr attribute = doc.createAttribute(GSXML.NAME_ATT);
1310 attribute.setValue(collectionName);
1311 collection.setAttributeNode(attribute);
1312
1313 Element serviceList = createServiceList(doc);
1314 collection.appendChild(serviceList);
1315
1316 Element responseMsg = createResponseMessage(doc, collection, null,
1317 GSXML.REQUEST_TYPE_DESCRIBE, collectionName);
1318 try{
1319 return FedoraCommons.elementToFormattedString(responseMsg);
1320 }catch(TransformerException e) {
1321 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg
1322 + " " + e;
1323 }
1324 }
1325
1326 /** All collections in this Digital Library (Fedora Repository) share
1327 * the same services, so this method returns the same as
1328 * describeCollectionService(collName, serviceName).
1329 * @return a GS3 describe response message for the requested service
1330 * of the given collection. DocumentContent/Metadata/StructureRetrieve
1331 * return nothing special except their names; browse (and any query)
1332 * return more complex XML responses.
1333 * All collections in this Digital Library (Fedora Repository) share
1334 * the same services, so this method returns the same as
1335 * describeService(serviceName).
1336 * @param serviceName - the name of the service in the collection which is to
1337 * be described.*/
1338 public String describeService(String serviceName)
1339 {
1340 // For all the *retrieve* services (incl ClassifierBrowseMetadataRetrieve)
1341 // we return:
1342 // <message><response from="<name>Retrieve" type="describe">
1343 // <service name="<name>Retrieve" type="retrieve" /></response></message>
1344 // But for browse (and any query) service, we return the data necessary
1345 // for displaying it
1346
1347 Document doc = this.builder.newDocument();
1348 Element service = doc.createElement(GSXML.SERVICE_ELEM);
1349 Attr attribute = doc.createAttribute(GSXML.NAME_ATT);
1350 attribute.setValue(serviceName);
1351 service.setAttributeNode(attribute);
1352
1353 attribute = doc.createAttribute(GSXML.TYPE_ATT);
1354
1355 if(serviceName.toLowerCase().endsWith("retrieve"))
1356 attribute.setValue(GSXML.SERVICE_TYPE_RETRIEVE);
1357
1358 else if(serviceName.toLowerCase().contains("browse")) {
1359 attribute.setValue(GSXML.SERVICE_TYPE_BROWSE);
1360
1361 // we need name and description <displayItem> elements
1362 Element displayItem
1363 = createNameValuePairElement(doc,
1364 GSXML.DISPLAY_TEXT_ELEM, GSXML.DISPLAY_TEXT_NAME, "Browse");
1365 service.appendChild(displayItem);
1366
1367 displayItem = createNameValuePairElement(doc,
1368 GSXML.DISPLAY_TEXT_ELEM, GSXML.DISPLAY_TEXT_DESCRIPTION,
1369 "Browse pre-defined classification hierarchies");
1370 service.appendChild(displayItem);
1371
1372 // now need a classifierList
1373 Element classifierList = doc.createElement(
1374 GSXML.CLASSIFIER_ELEM+GSXML.LIST_MODIFIER);
1375
1376 int classifierNum = 1;
1377 // append a <classifier content="some letter" name="CL#">
1378 // for each letter of the alphabet:
1379 Element classifier = createClassifierElement(doc, "TitleByLetter",
1380 classifierNum++, "titles (by letter)", "Browse titles by letter");
1381 // now add this <classifier> to the <classifierList>
1382 classifierList.appendChild(classifier);
1383
1384 // ANY MORE CLASSIFIERS? ADD THEM HERE
1385
1386 service.appendChild(classifierList);
1387 } // ELSE check for whether it is a query service
1388 else if(serviceName.toLowerCase().contains("query")) {
1389 attribute.setValue(GSXML.SERVICE_TYPE_QUERY);
1390 if(serviceName.equals("TextQuery"))
1391 describeTextQueryService(service);
1392 else if(serviceName.equals("FieldQuery"))
1393 describeFieldQueryService(service);
1394 }
1395
1396 // don't forget to add the type attribute to the service!
1397 service.setAttributeNode(attribute);
1398
1399 String from = serviceName;
1400
1401 Element responseMsg = createResponseMessage(doc, service, null,
1402 GSXML.REQUEST_TYPE_DESCRIBE, from);
1403 try{
1404 return FedoraCommons.elementToFormattedString(responseMsg);
1405 }catch(TransformerException e) {
1406 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg
1407 + " " + e;
1408 }
1409 }
1410
1411 /** Appends children to the parameter service Element that make the
1412 * final service Element into a describe response XML for FedoraGS3's
1413 * TextQuery service.
1414 * @param service is the service Element that is being filled out. */
1415 protected void describeTextQueryService(Element service) {
1416 Document doc = service.getOwnerDocument();
1417 // we need name, submit (button) and description <displayItem> elements
1418 Element displayItem = createNameValuePairElement(doc,
1419 GSXML.DISPLAY_TEXT_ELEM, GSXML.DISPLAY_TEXT_NAME,
1420 "Text Search");
1421 service.appendChild(displayItem);
1422
1423 displayItem = createNameValuePairElement(doc,
1424 GSXML.DISPLAY_TEXT_ELEM, GSXML.DISPLAY_TEXT_SUBMIT, "Search");
1425 service.appendChild(displayItem);
1426
1427 displayItem = createNameValuePairElement(doc,
1428 GSXML.DISPLAY_TEXT_ELEM, GSXML.DISPLAY_TEXT_DESCRIPTION,
1429 "Title and full-text search service");
1430 service.appendChild(displayItem);
1431
1432 //create the <paramList>
1433 Element paramList = doc.createElement(
1434 GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
1435
1436 // we ignore granularity to search at: it will always be
1437 // document and section level
1438 // we ignore casefolding: always on (that is, case is irrelevant)
1439 // we ignore document display order: always ranked
1440
1441 // Constructing the following:
1442 // <param default="100" name="maxDocs" type="integer">
1443 // <displayItem name="name">Maximum hits to return</displayItem>
1444 // </param>
1445 Element param = doc.createElement(GSXML.PARAM_ELEM);
1446
1447 Attr attribute = doc.createAttribute(GSXML.NAME_ATT);
1448 attribute.setValue(MAXDOCS);
1449 param.setAttributeNode(attribute);
1450
1451 attribute = doc.createAttribute(GSXML.DEFAULT_ATT);
1452 attribute.setValue("100");
1453 param.setAttributeNode(attribute);
1454
1455 attribute = doc.createAttribute(GSXML.TYPE_ATT);
1456 attribute.setValue(GSXML.PARAM_TYPE_INTEGER);
1457 param.setAttributeNode(attribute);
1458
1459 displayItem = createNameValuePairElement(doc,
1460 GSXML.DISPLAY_TEXT_ELEM, GSXML.DISPLAY_TEXT_NAME,
1461 "Maximum hits to return");
1462 param.appendChild(displayItem);
1463
1464 paramList.appendChild(param);
1465
1466 // Constructing the following:
1467 // <param name="query" type="string">
1468 // <displayItem name="name">Query string</displayItem>
1469 // </param>
1470 param = doc.createElement(GSXML.PARAM_ELEM);
1471
1472 attribute = doc.createAttribute(GSXML.NAME_ATT);
1473 attribute.setValue(QUERY);
1474 param.setAttributeNode(attribute);
1475
1476 attribute = doc.createAttribute(GSXML.TYPE_ATT);
1477 attribute.setValue(GSXML.PARAM_TYPE_STRING);
1478 param.setAttributeNode(attribute);
1479
1480 displayItem = createNameValuePairElement(doc,
1481 GSXML.DISPLAY_TEXT_ELEM, GSXML.DISPLAY_TEXT_NAME,
1482 "Query string");
1483 param.appendChild(displayItem);
1484
1485 paramList.appendChild(param);
1486
1487 service.appendChild(paramList);
1488 }
1489
1490 /** Appends children to the parameter service Element that make the
1491 * final service Element into a describe response XML for FedoraGS3's
1492 * FieldQuery service.
1493 * @param service is the service Element that is being filled out. */
1494 protected void describeFieldQueryService(Element service) {
1495 Document doc = service.getOwnerDocument();
1496 // we need name, submit (button) and description <displayItem> elements
1497 Element displayItem = createNameValuePairElement(doc,
1498 GSXML.DISPLAY_TEXT_ELEM, GSXML.DISPLAY_TEXT_NAME,
1499 "Form Search");
1500 service.appendChild(displayItem);
1501
1502 displayItem = createNameValuePairElement(doc,
1503 GSXML.DISPLAY_TEXT_ELEM, GSXML.DISPLAY_TEXT_SUBMIT, "Search");
1504 service.appendChild(displayItem);
1505
1506 displayItem = createNameValuePairElement(doc,
1507 GSXML.DISPLAY_TEXT_ELEM, GSXML.DISPLAY_TEXT_DESCRIPTION,
1508 "Simple fielded search");
1509 service.appendChild(displayItem);
1510
1511 //create the <paramList>
1512 Element paramList = doc.createElement(
1513 GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
1514
1515 // we ignore granularity to search at: it will always be
1516 // document and section level
1517 // we ignore casefolding: always on (that is, case is irrelevant)
1518 // we ignore document display order: always ranked
1519
1520 // Constructing the following:
1521 // <param default="100" name="maxDocs" type="integer">
1522 // <displayItem name="name">Maximum hits to return</displayItem>
1523 // </param>
1524 Element param = doc.createElement(GSXML.PARAM_ELEM);
1525
1526 Attr attribute = doc.createAttribute(GSXML.NAME_ATT);
1527 attribute.setValue(MAXDOCS);
1528 param.setAttributeNode(attribute);
1529
1530 attribute = doc.createAttribute(GSXML.DEFAULT_ATT);
1531 attribute.setValue("100");
1532 param.setAttributeNode(attribute);
1533
1534 attribute = doc.createAttribute(GSXML.TYPE_ATT);
1535 attribute.setValue(GSXML.PARAM_TYPE_INTEGER);
1536 param.setAttributeNode(attribute);
1537
1538 displayItem = createNameValuePairElement(doc,
1539 GSXML.DISPLAY_TEXT_ELEM, GSXML.DISPLAY_TEXT_NAME,
1540 "Maximum hits to return");
1541 param.appendChild(displayItem);
1542
1543 paramList.appendChild(param);
1544
1545 // Constructing the following:
1546 // <param name="simpleField" occurs="4" type="multi">
1547 // <displayItem name="name"></displayItem>
1548 //
1549 // <param name="query" type="string">
1550 // <displayItem name="name">Word or phrase </displayItem>
1551 // </param>
1552 //
1553 // <param default="allFields" name="fieldname" type="enum_single">
1554 // <displayItem name="name">in field</displayItem>
1555 //
1556 // <option name="docTitles">
1557 // <displayItem name="name">document titles</displayItem>
1558 // </option>
1559 // <option name="allTitles">
1560 // <displayItem name="name">document and section titles</displayItem>
1561 // </option>
1562 // <option name="fullText">
1563 // <displayItem name="name">full text</displayItem>
1564 // </option>
1565 // <option name="all">
1566 // <displayItem name="name">titles and full text</displayItem>
1567 // </option>
1568 // <option name="">
1569 // <displayItem name="name"></displayItem>
1570 // </option>
1571 // </param>
1572 // </param>
1573 Element rowOfParams = doc.createElement(GSXML.PARAM_ELEM);
1574 attribute = doc.createAttribute(GSXML.NAME_ATT);
1575 attribute.setValue(SIMPLEFIELD_ATT);
1576 rowOfParams.setAttributeNode(attribute);
1577
1578 // we want the row of controls to occur multiple times
1579 attribute = doc.createAttribute(GSXML.TYPE_ATT);
1580 attribute.setValue(GSXML.PARAM_TYPE_MULTI);
1581 rowOfParams.setAttributeNode(attribute);
1582
1583 attribute = doc.createAttribute(OCCURS_ATT);
1584 attribute.setValue("4"); // we want this row to occur 4 times
1585 rowOfParams.setAttributeNode(attribute);
1586
1587 // <param name="query" type="string">
1588 // <displayItem name="name">Word or phrase </displayItem>
1589 // </param>
1590 param = doc.createElement(GSXML.PARAM_ELEM);
1591
1592 attribute = doc.createAttribute(GSXML.NAME_ATT);
1593 attribute.setValue(QUERY);
1594 param.setAttributeNode(attribute);
1595
1596 attribute = doc.createAttribute(GSXML.TYPE_ATT);
1597 attribute.setValue(GSXML.PARAM_TYPE_STRING);
1598 param.setAttributeNode(attribute);
1599
1600 displayItem = createNameValuePairElement(doc,
1601 GSXML.DISPLAY_TEXT_ELEM, GSXML.DISPLAY_TEXT_NAME,
1602 "Word or phrase");
1603 param.appendChild(displayItem);
1604 rowOfParams.appendChild(param);
1605
1606 // <param default="allFields" name="fieldName" type="enum_single">
1607 // <displayItem name="name">in field</displayItem>
1608 param = doc.createElement(GSXML.PARAM_ELEM);
1609 attribute = doc.createAttribute(GSXML.NAME_ATT);
1610 attribute.setValue(FIELDNAME_ATT);
1611 param.setAttributeNode(attribute);
1612
1613 attribute = doc.createAttribute(GSXML.TYPE_ATT);
1614 attribute.setValue(GSXML.PARAM_TYPE_ENUM_SINGLE);
1615 param.setAttributeNode(attribute);
1616
1617 attribute = doc.createAttribute(GSXML.DEFAULT_ATT);
1618 attribute.setValue(ALL_FIELDS);
1619 param.setAttributeNode(attribute);
1620
1621 displayItem = createNameValuePairElement(doc,
1622 GSXML.DISPLAY_TEXT_ELEM, GSXML.DISPLAY_TEXT_NAME,
1623 "in field");
1624 param.appendChild(displayItem);
1625
1626 String[] searchFieldNames
1627 = {ALL_FIELDS, DOC_TITLES, ALL_TITLES, FULLTEXT};
1628 String[] searchFieldDisplay = {"all titles and full-text",
1629 "document titles only", "document and section titles",
1630 "full-text only"};
1631
1632 // for each fieldName create an option element and insert
1633 // the option into the enum_multi drop-down param:
1634 // <option name="fieldName">
1635 // <displayItem name="name">fieldName</displayItem>
1636 // </option>
1637 for(int i = 0; i < searchFieldNames.length; i++) {
1638 Element option = doc.createElement(GSXML.PARAM_OPTION_ELEM);
1639 attribute = doc.createAttribute(GSXML.NAME_ATT);
1640 attribute.setValue(searchFieldNames[i]);
1641 option.setAttributeNode(attribute);
1642
1643 displayItem = createNameValuePairElement(doc,
1644 GSXML.DISPLAY_TEXT_ELEM, GSXML.DISPLAY_TEXT_NAME,
1645 searchFieldDisplay[i]);
1646 option.appendChild(displayItem);
1647 param.appendChild(option); // add option to the drop-down box
1648 }
1649
1650 rowOfParams.appendChild(param);
1651 paramList.appendChild(rowOfParams);
1652 service.appendChild(paramList);
1653 }
1654
1655 /**
1656 * @return a GS3 describe response message for the requested service
1657 * of the given collection. DocumentContent/Metadata/StructureRetrieve
1658 * return nothing special except their names; browse (and any query)
1659 * return more complex XML responses.
1660 * All collections in this Digital Library (Fedora Repository) share
1661 * the same services, so this method returns the same as
1662 * describeService(serviceName).
1663 * @param collectionName - the name of the collection whose service is to
1664 * be described. It will be converted to a fedora collection pid, which is of
1665 * the form "greenstone:&lt;collectionName&gt;-collection".
1666 * @param serviceName - the name of the service in the collection which is to
1667 * be described. */
1668 public String describeCollectionService(String collectionName,
1669 String serviceName) {
1670 // collectionName can be ignored, because all services are FedoraGS3
1671 // services and are not unique to any particular (greenstone) collection.
1672 return describeService(serviceName);
1673 }
1674
1675 /** This method performs the implemented browse operation: allowing the
1676 * user to browse the titles of documents in the given collection by letter
1677 * and returning the results.
1678 * @param classifierID is the id of the classifier on which to browse. In
1679 * this case, the classifier indicates whether we browse titles by letter, or
1680 * browse (documents) by collection; and it is of the form &lt;CL(letter)&gt;.
1681 * @param collectionName is the name of the collection whose documents
1682 * starting with the given letter will be returned.
1683 * @return a GS3 DocumentStructureRetrieve response message which lists all
1684 * the documents that start with the letter indicated by parameter classifier.
1685 */
1686 public String browse(String collectionName, String classifierID)
1687 {
1688 Document doc = builder.newDocument();
1689 FedoraGS3RunException ex = null; //any RemoteException or UnsupportedEncodingException
1690
1691 // <classifierNodeList>
1692 Element classifierNodeList = doc.createElement(
1693 GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
1694
1695 // <classifierNode nodeID="classifierNum">
1696 Element requestedClassifierNode = doc.createElement(
1697 GSXML.CLASS_NODE_ELEM);
1698 Attr attribute = doc.createAttribute(GSXML.NODE_ID_ATT);
1699 attribute.setValue(classifierID);
1700 requestedClassifierNode.setAttributeNode(attribute);
1701 classifierNodeList.appendChild(requestedClassifierNode);
1702
1703 // <nodeStructure>
1704 Element nodeStructure = doc.createElement(GSXML.NODE_STRUCTURE_ELEM);
1705 requestedClassifierNode.appendChild(nodeStructure);
1706
1707 // And one more time, the top level classifierNode:
1708 Element classifierNode = doc.createElement(GSXML.CLASS_NODE_ELEM);
1709 attribute = doc.createAttribute(GSXML.NODE_ID_ATT);
1710 attribute.setValue(classifierID);
1711 classifierNode.setAttributeNode(attribute);
1712 nodeStructure.appendChild(classifierNode);
1713
1714 // Work out what we're browsing base on the classifierID's number
1715 // classifier CL1 = browse titles by letter;
1716 // classifier CL2 = browse by collection;
1717 //remove the CL prefix and obtain the number from the id:
1718 int classifierNum = Integer.parseInt(classifierID.replace("CL", ""));
1719 switch(classifierNum) {
1720 case 1:
1721 // we're going to loop to the end of the alphabet
1722 int num = 1;
1723 for(char ch = 'A'; ch <= 'Z'; ch++, num++) {
1724 // <classifierNode nodeID="CL3.1">
1725 Element subClassifier = doc.createElement(
1726 GSXML.CLASS_NODE_ELEM);
1727 attribute = doc.createAttribute(GSXML.NODE_ID_ATT);
1728 attribute.setValue(classifierID+"."+num);
1729 subClassifier.setAttributeNode(attribute);
1730 classifierNode.appendChild(subClassifier);
1731 // now we are going to retrieve the document structure for
1732 // this subClassifierID: all the documents that begin with
1733 // its letter.
1734 // remove the starting CL
1735 String letter = String.valueOf(ch);
1736 try{
1737 String[] docPIDs = this.browseTitlesByLetter(
1738 collectionName, letter);
1739 // append the <docNodes> for the docPIDs found as children
1740 // of subclassifier
1741 getStructureElement(subClassifier, docPIDs, DESCENDANTS);
1742 //CHILDREN); // for testing
1743 } catch(Exception e) {
1744 ex = new FedoraGS3RunException(e);
1745 ex.setSpecifics("requested portion of TOC file or "
1746 + "trouble with fielded search ");
1747 }
1748 }
1749 break;
1750 case 2:
1751 break;
1752 default:
1753 ex = new FedoraGS3RunException( // cause is regular exception
1754 new Exception("Unknown classifier ID: " + classifierID));
1755 }
1756 Element responseMsg = createResponseMessage(doc, classifierNodeList, ex,
1757 GSXML.REQUEST_TYPE_DESCRIBE, collectionName+"/ClassifierBrowse");
1758 try{
1759 return FedoraCommons.elementToFormattedString(responseMsg);
1760 }catch(TransformerException e) {
1761 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg
1762 + " " + e;
1763 }
1764 }
1765
1766 /** This method performs something equivalent to a greenstone3
1767 * ClassifierBrowseMetadataRetrieve on the classifierNodeIDs
1768 * @param classNodeIDs array of classifierNode IDs of for which the metadata
1769 * needs to be returned.
1770 * @return a GS3 ClassifierBrowseMetadataRetrieve response message which
1771 * lists the metadata for all the classifierNodes passed as parameter.*/
1772 public String browseMetadataRetrieve(String[] classNodeIDs)
1773 {
1774 Document doc = this.builder.newDocument();
1775 // <classifierNodeList>
1776 Element classifierNodeList = doc.createElement(
1777 GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
1778
1779 // create <classifierNode><metadataList><metadata>s
1780 // </metadataList></classifierNode> for all letters of alphabet
1781 for(int i = 0; i < classNodeIDs.length; i++) {
1782 // strip ID of everything before the first '.' (i.e. remove "CL#.")
1783 int index = classNodeIDs[i].indexOf('.');
1784 String subClassifierNumber = classNodeIDs[i].substring(index+1);
1785 int subClassifierNum = Integer.parseInt(subClassifierNumber);
1786 char letter = (char)('A' + subClassifierNum - 1); // A = 1
1787
1788 // <classifierNode nodeID="CL#.subNum">
1789 Element classifierNode = doc.createElement(GSXML.CLASS_NODE_ELEM);
1790 Attr attribute = doc.createAttribute(GSXML.NODE_ID_ATT);
1791 attribute.setValue(classNodeIDs[i]);
1792 classifierNode.setAttributeNode(attribute);
1793
1794 // <metadataList>
1795 Element metadataList = doc.createElement(
1796 GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
1797
1798 // at least one metadata element: that of the title of this
1799 // classifierNode:
1800 // <metadata name="Title">letter</metadata>
1801 Element metadata = this.createNameValuePairElement(doc,
1802 GSXML.METADATA_ELEM, "Title", String.valueOf(letter));
1803
1804 // now connect up everything
1805 metadataList.appendChild(metadata);
1806 classifierNode.appendChild(metadataList);
1807 classifierNodeList.appendChild(classifierNode);
1808 }
1809
1810 Element responseMsg = createResponseMessage(doc, classifierNodeList, null,
1811 GSXML.REQUEST_TYPE_PROCESS, //collName +
1812 "ClassifierBrowseMetadataRetrieve");
1813 try{
1814 return FedoraCommons.elementToFormattedString(responseMsg);
1815 }catch(TransformerException e) {
1816 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg
1817 + " " + e;
1818 }
1819 }
1820
1821 /** @return a newly created element of the following format:
1822 * &lt;classifier content="somecontent" name="CL+num"&gt;
1823 * &lt;displayItem name="name"&gt;someClassifierName&lt;/displayItem&gt;
1824 * &lt;displayItem name="description"&gt;Browse by classifier name&lt;/displayItem&gt;
1825 * &lt;/classifier&gt;
1826 * @param doc - the document used to create the element
1827 * @param content - value of the content attribute
1828 * @param classifierNum - the number suffixed to the CL, together forming
1829 * the classifier Node's ID
1830 * @param displayNameVal is the bodytext of a named displayItem element
1831 * @param displayDescrVal is the bodytext of a displayItem element with
1832 * description */
1833 protected Element createClassifierElement(Document doc, String content,
1834 int classifierNum, String displayNameVal, String displayDescrVal)
1835 {
1836 final String CL = "CL";
1837 Element classifier = doc.createElement(GSXML.CLASSIFIER_ELEM);
1838 // content attribute
1839 Attr att = doc.createAttribute(GSXML.CLASSIFIER_CONTENT_ATT);
1840 att.setValue(content);
1841 classifier.setAttributeNode(att);
1842 // name attribute
1843 att = doc.createAttribute(GSXML.NAME_ATT);
1844 att.setValue(CL + classifierNum);
1845 classifier.setAttributeNode(att);
1846
1847 // now create the displayItem children for classifier:
1848 // <displayItem name="name">#letter</displayItem>
1849 // <displayItem name="description">
1850 //Browse titles starting with #letter</displayItem>
1851 Element displayItem = createNameValuePairElement(doc,
1852 GSXML.DISPLAY_TEXT_ELEM, GSXML.DISPLAY_TEXT_NAME, displayNameVal);
1853 classifier.appendChild(displayItem);
1854 displayItem = createNameValuePairElement(doc, GSXML.DISPLAY_TEXT_ELEM,
1855 GSXML.DISPLAY_TEXT_DESCRIPTION, displayDescrVal);
1856 classifier.appendChild(displayItem);
1857
1858 return classifier;
1859 }
1860
1861
1862 /** @return a newly created element of the following format:
1863 * &lt;elementName name="somename"&gt;"some display value"&lt;/elementName&gt;
1864 * @param doc - the document used to create the element
1865 * @param elementName - the tag name
1866 * @param name - value of attribute name
1867 * @param value - the body text of the element */
1868 protected Element createNameValuePairElement(Document doc, String elementName,
1869 String name, String value) {
1870 // <elementName name="somename">"some display value"</elementName>
1871 Element element = doc.createElement(elementName);
1872 Attr attribute = doc.createAttribute(GSXML.NAME_ATT);
1873 attribute.setValue(name);
1874 element.setAttributeNode(attribute);
1875
1876 element.appendChild(doc.createTextNode(value));
1877 return element;
1878 }
1879
1880 /**
1881 * @param collection is the collection to search in
1882 * @param query is the query term to search for. It won't specify the
1883 * indexed field to search in, which will mean that GSearch will
1884 * search all default indexed fields.
1885 * @param maxDocs is the maximum number of results to return (which
1886 * at present we consider equivalent to FedoraGSearch's hitpageSize).
1887 */
1888 public String[] textQuery(String collection, String query,
1889 int maxDocs)
1890 throws Exception
1891 {
1892 // no need to search there is no query or query is empty spaces
1893 if(query.trim().equals(""))
1894 return new String[]{};
1895
1896 // QUERY value won't specify indexed field to search, Fedora
1897 // Gsearch will take that as meaning all default indexed fields.
1898 // Params to search() method below: string of fielded query terms;
1899 // hitpageStart, hitpageEnd, snippetsMax (leave that 0)
1900 query = query + " " + "PID" + COLON + GREENSTONE;
1901
1902 String searchResult = this.fedoraGSearch.search(query, 1, maxDocs, 0);
1903 // now we have the XML returned by FedoraGSearch, get the pids
1904 // of the documents returned (if any)
1905 String[] pids = this.fedoraGSearch.getPIDsFromSearchResult(
1906 collection, searchResult);
1907 return pids;
1908 }
1909
1910 /**
1911 * This method performs a fieldquery, searching for x number of phrases
1912 * in each of the 4 indexed fields.
1913 * @param collection is the collection to search in
1914 * @param nameValParamsMap is a Map of several(key, value) entries,
1915 * 4 of which we're concerned with here:
1916 * - the keys are ALL_FIELDS, DOC_TITLES, ALL_TITLES, FULLTEXT
1917 * - the values are a comma separated list of terms (phrases or single
1918 * words) to search that field in. There may be more than 1 or
1919 * there may be none (in which case there may be N empty values or
1920 * spaces separated by commas).
1921 * @param maxDocs is the maximum number of results to return (which
1922 * at present we consider equivalent to FedoraGSearch's hitpageSize).
1923 * */
1924 public String[] fieldQuery(String collection, Map nameValParamsMap,
1925 int maxDocs)
1926 throws Exception
1927 {
1928 // we're going to maintain a list of UNIQUE pids that were returned
1929 // in search results. Hence we use Set:
1930 java.util.Set set = new java.util.HashSet();
1931
1932 // (1) Use Fedora's search to search document titles, if they were
1933 // specified:
1934 String[] docTitlepids = {};
1935
1936 String docTitleTerms = (String)nameValParamsMap.get(DOC_TITLES);
1937 if(docTitleTerms != null) { // no doc titles may have been specified
1938 String[] phrases = docTitleTerms.split(COMMA);
1939
1940 // search the individual phrases first:
1941 for(int i = 0; i < phrases.length; i++) {
1942 if(phrases.equals("") || phrases.equals(" "))
1943 continue; //skip when there are no terms
1944 docTitlepids = this.searchDocumentTitles(
1945 collection, phrases[i], false);
1946 for(int j = 0; j < docTitlepids.length; j++)
1947 set.add(docTitlepids[j]);
1948 }
1949 }
1950 // (2) use FedoraGSearch to search doc AND section titles, and
1951 // fulltext (in case these were specified in nameValParamsMap):
1952 String searchResult = this.fedoraGSearch.search(
1953 nameValParamsMap, 1, maxDocs);
1954
1955 String[] pids = this.fedoraGSearch.getPIDsFromSearchResult(
1956 collection, searchResult);
1957
1958 for(int i = 0; i < pids.length; i++)
1959 set.add(pids[i]);
1960
1961 pids = null;
1962 pids = new String[set.size()];
1963 set.toArray(pids); // unique pids
1964 return pids;
1965 }
1966
1967 /** @return a String representing Greenstone3 XML for a query process
1968 * response returning the results for the query denoted by parameter
1969 * nameValParamsMap.
1970 * @param nameValParamsMap is a Hashmap of name and value pairs for all the
1971 * query field data values. The names match the field names that
1972 * describeCollectionService() would have returned for the query service.
1973 * @param collection is the name of the collection
1974 * @param service is the name of the query service
1975 * This method is only ever called when any of the services in the digital
1976 * library described themselves as type=query. Therefore any digital
1977 * libraries that have no query services, can just return emtpy message
1978 * strings (or even "") since this method will never be called on them
1979 * anyway. */
1980 public String query(String collection, String service,
1981 Map nameValParamsMap)
1982 {
1983 FedoraGS3RunException ex = null;
1984 // (1) obtain the requested number of maximum result documents
1985 int maxDocs = 100;
1986 try{
1987 maxDocs = Integer.parseInt((String)nameValParamsMap.get(MAXDOCS));
1988 } catch(NumberFormatException e) {
1989 maxDocs = 100;
1990 }
1991
1992 String pids[] = {};
1993 // (2) for Textquery, we simply search ALL_FIELDS using FedoraGSearch
1994 if(service.equals("TextQuery")) {
1995 try {
1996 // get the Query field:
1997 String query = (String)nameValParamsMap.get(QUERY);
1998 pids = textQuery(collection, query, maxDocs);
1999 }
2000 catch(Exception e) {
2001 LOG.error("Error in TextQuery processing: " + e);
2002 ex = new FedoraGS3RunException(
2003 "When trying to use FedoraGenericSearch for a TextQuery", e);
2004
2005 }
2006 } else { // (3) FieldQuery
2007 // first get the comma-separated lists
2008 String listOfFieldNames = (String)nameValParamsMap.get(FIELDNAME_ATT);
2009 String listOfSearchTerms = (String)nameValParamsMap.get(QUERY);
2010 // both are comma separated lists, so split both on 'comma'
2011 String[] fieldNames = listOfFieldNames.split(COMMA);
2012 String[] searchTerms = listOfSearchTerms.split(COMMA);
2013
2014 // In the fieldNames and searchTerms lists of nameValParamsMap,
2015 // each searchTerm element was matched with its correspondingly
2016 // indexed fieldName.
2017 // A new map is going to reorganise this, by putting all terms
2018 // for a particular fieldName together in a comma separated list
2019 // and associating that with the fieldName. I.e. (key, value) ->
2020 // (fieldName, comma-separated list of all terms in that field)
2021 Map map = new HashMap();
2022 for(int i = 0; i < searchTerms.length; i++) {
2023 // there may be fewer searchTerms than fieldNames (since some
2024 // fieldNames may have been left empty), so loop on searchTerms
2025 if(map.containsKey(fieldNames[i])) { //fieldName is already
2026 // in the list, so append comma with new value
2027 String termsList = (String)map.get(fieldNames[i]);
2028 termsList = termsList + COMMA + searchTerms[i];
2029 map.put(fieldNames[i], termsList);
2030 } else { // this is the first time this fieldName occurred
2031 // just put the fieldName with searchTerm as-is
2032 map.put(fieldNames[i], searchTerms[i]);
2033 }
2034 }
2035
2036 try {
2037 // For fieldquery, we search on all the fieldNames specified
2038 // - if DOC_TITLES is specified then we use Fedora's search
2039 // - for all other fieldNames specified, we use FedoraGSearch
2040 pids = fieldQuery(collection, map, maxDocs);
2041 }
2042 catch(Exception e) {
2043 LOG.error("Error in FieldQuery processing: " + e);
2044 ex = new FedoraGS3RunException(
2045 "When trying to use FedoraGenericSearch for a FieldQuery", e);
2046 }
2047 }
2048
2049 // Build Greenstone XML Query response message for from
2050 // the pids (which should be document identifiers)
2051 Document doc = builder.newDocument();
2052 // <metadataList><metadata name="numDocsMatched" value="n" />
2053 // </metadataList>
2054 Element metadataList = doc.createElement(
2055 GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
2056 Element metadata = doc.createElement(GSXML.METADATA_ELEM);
2057
2058 Attr attribute = doc.createAttribute(GSXML.NAME_ATT);
2059 attribute.setValue(NUM_DOCS_MATCHED);
2060 metadata.setAttributeNode(attribute);
2061
2062 attribute = doc.createAttribute(GSXML.VALUE_ATT);
2063 attribute.setValue(Integer.toString(pids.length));
2064 metadata.setAttributeNode(attribute);
2065
2066 metadataList.appendChild(metadata);
2067
2068 // <documentNodeList>
2069 // <documentNode nodeID="HASHac0a04dd14571c60d7fbfd.4.2"
2070 // docType='hierarchy' nodeType="leaf" />
2071 // ...
2072 // ...
2073 // </documentNodeList>
2074 Element docNodeList = doc.createElement(
2075 GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
2076 // for each
2077 for(int i = 0; i < pids.length; i++) {
2078 Element docNode = doc.createElement(GSXML.DOC_NODE_ELEM);
2079 attribute = doc.createAttribute(GSXML.NODE_ID_ATT);
2080 attribute.setValue(pids[i]);
2081 docNode.setAttributeNode(attribute);
2082
2083 attribute = doc.createAttribute(GSXML.DOC_TYPE_ATT);
2084 attribute.setValue("hierarchy");
2085 docNode.setAttributeNode(attribute);
2086
2087 attribute = doc.createAttribute(GSXML.NODE_TYPE_ATT);
2088 attribute.setValue("root");
2089 docNode.setAttributeNode(attribute);
2090 docNodeList.appendChild(docNode);
2091 }
2092
2093 Element responseMsg = createResponseMessage(doc, docNodeList, ex,
2094 GSXML.REQUEST_TYPE_PROCESS, service);
2095 try{
2096 return FedoraCommons.elementToFormattedString(responseMsg);
2097 }catch(TransformerException e) {
2098 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg
2099 + " " + e;
2100 }
2101 }
2102
2103 public static void main(String args[]) {
2104 try{
2105 // testing default constructor
2106 //FedoraGS3Connection con = new FedoraGS3Connection();
2107
2108 // testing constructor that takes properties file to show initial
2109 // fedora server values
2110 java.io.File propertyFilename
2111 = new java.io.File("fedoraGS3.properties");
2112 FedoraGS3Connection con = new FedoraGS3Connection(propertyFilename);
2113
2114 // DESCRIBE: serviceList, collectionList
2115 System.out.println("serviceList:\n" + con.getServiceList());
2116
2117 System.out.println("collectionList:\n" + con.getCollectionList());
2118
2119 String[] colPIDs = con.getCollections();
2120 String[] collectionNames = con.getCollectionNames(con.getCollections());
2121
2122
2123 for(int i = 0; i < collectionNames.length; i++) {
2124 System.out.println("Describing collections:\n");
2125 System.out.println(con.describeCollection(collectionNames[i]));
2126 System.out.println("Describing collection services:\n"
2127 + con.describeCollectionServices(collectionNames[i]));
2128 }
2129
2130 String[] serviceNames = con.getServiceNames();
2131 for(int i = 0; i < serviceNames.length; i++) {
2132 System.out.println("Describing " + serviceNames[i] + ":\n"
2133 + con.describeCollectionService("demo", serviceNames[i]));
2134 }
2135
2136
2137 // TRYING OUT SPECIAL top-level document metadata retrieval (DLS, DC)
2138 // along with EX of the top-level document:
2139 System.out.println("\nGET META for greenstone:gs2mgdemo-HASH01d667303fe98545f03c14ae:");
2140 System.out.println(con.getDocumentMetadata(new String[]{"greenstone:gs2mgdemo-HASH01d667303fe98545f03c14ae"}));
2141
2142
2143 String[] docIDs = con.getCollectionDocs(colPIDs[0]);
2144 System.out.println("\nGET CONTENT:");
2145 for(int i = 0; i < docIDs.length; i++) {
2146 System.out.println(con.getContent(docIDs[i]));
2147 }
2148
2149 System.out.println("\nGET META:");
2150 for(int i = 0; i < docIDs.length; i++) {
2151 System.out.println(con.getDocumentMetadata(docIDs[i]));
2152 }
2153
2154 String[] getTitlesFor = {
2155 "greenstone:gs2mgdemo-HASH01d667303fe98545f03c14ae",
2156 "greenstone:gs2mgdemo-HASHa568bac1d8d7bd12a0938b",
2157 "greenstone:gs2mgdemo-HASHa568bac1d8d7bd12a0938b-1",
2158 "greenstone:gs2mgdemo-HASH01d667303fe98545f03c14ae-1.7",
2159 "greenstone:gs2mgdemo-HASHa568bac1d8d7bd12a0938b-1.5.1"
2160 };
2161
2162 // first let's display the regular meta for top-level docs and
2163 // their sections
2164 for(int i = 0; i < getTitlesFor.length; i++) {
2165 System.out.println(con.getDocumentMetadata(getTitlesFor[i]));
2166 }
2167
2168 System.out.println("\nTitles are:");
2169 System.out.println(con.getTitleMetadata(getTitlesFor));
2170
2171 System.out.println("\nGET STRUCTURE:");
2172 for(int i = 0; i < docIDs.length; i++) {
2173 System.out.println(con.getChildren(docIDs[i]));
2174 System.out.println(con.getDocumentStructure(docIDs[i]));
2175 }
2176
2177 // TEST ERROR CASES:
2178 System.out.println("\nTESTING ERROR CASES");
2179 System.out.println(con.getContent("greenstone:demo-pinky"));
2180 String[] errorCases = { "greenstone:demo-HASH23d1019b589e2ef6a680e3-1.5.1.5",
2181 "greenstone:demo-pinky" };
2182 System.out.println(con.getContent(errorCases));
2183 System.out.println(con.getDocumentMetadata(errorCases));
2184 System.out.println(con.getDocumentStructure(errorCases));
2185
2186 System.out.println("\nCLASSIFIER BROWSE");
2187 System.out.println(con.browse("gs2mgdemo", //"ClassifierBrowse",
2188 "CL1"));
2189
2190 System.out.println("\nCLASSIFIER BROWSE METADATA RETRIEVE");
2191 String[] classNodeIDs = new String[26];
2192 for(int i = 0; i < classNodeIDs.length; i++) {
2193 int subClassifierNum = i + 1;
2194 classNodeIDs[i] = "CL1." + subClassifierNum;
2195 }
2196 System.out.println(con.browseMetadataRetrieve(//"gs2mgdemo",
2197 classNodeIDs));
2198
2199 System.out.println("Testing query services");
2200 System.out.println("TEXT QUERY:");
2201 Map formControlValsMap = new HashMap();
2202 formControlValsMap.put(MAXDOCS, "100");
2203 formControlValsMap.put(QUERY, "snails");
2204 String searchResponse
2205 = con.query("gs2mgdemo", "TextQuery", formControlValsMap);
2206 System.out.println(searchResponse);
2207
2208 System.out.println("FIELD QUERY:");
2209 formControlValsMap.clear();
2210 formControlValsMap.put(MAXDOCS, "100");
2211 formControlValsMap.put(QUERY, "interview,Gender equality,cyclone");
2212 formControlValsMap.put(FIELDNAME_ATT,
2213 "allFields,docTitles,allFields,allFields");
2214 searchResponse
2215 = con.query("gs2mgdemo", "FieldQuery", formControlValsMap);
2216 System.out.println(searchResponse);
2217
2218 System.exit(0);
2219 }catch(Exception e) {
2220 JOptionPane.showMessageDialog(
2221 null, e, "Error", JOptionPane.ERROR_MESSAGE);
2222 //System.err.println("ERROR: " + e);
2223 e.printStackTrace();
2224 }
2225 }
2226}
Note: See TracBrowser for help on using the repository browser.