/** *######################################################################### * GS3ServicesAPIA.java - part of the demo-client for Greenstone 3, of the * Greenstone digital library suite from the New Zealand Digital Library * Project at the * University of Waikato, New Zealand. *

* Copyright (C) 2008 New Zealand Digital Library Project *

* This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. *######################################################################## */ package org.greenstone.gs3client.dlservices; import javax.swing.JOptionPane; import java.util.HashMap; import java.util.Map; import java.io.IOException; import java.net.MalformedURLException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.rpc.ServiceException; import org.xml.sax.SAXException; import org.greenstone.gs3client.data.DocumentNodeData; import org.apache.log4j.Logger; //Import log4j classes import java.util.Properties; /** * GS3ServicesAPIA does two things: * - it implements DigitalLibraryServicesAPIA for enabling the Java-client * to access Greenstone's repository of collections and documents. It * makes this possible through use of Greenstone 3's web services. * - it inherits from GS3WebServicesQBRAPI, which means it inherits all the * methods that deal with invoking the Greenstone 3 web services * functionality (through use of Apache Axis' Service and Call objects). * It therefore provides an equivalent method to each Greenstone 3 web * service operation, even if some of these web service operations are * never called by the Java-client and therefore not prescribed by the * DigitalLibraryServicesAPIA interface. * @author ak19 */ public class GS3ServicesAPIA extends GS3WebServicesQBRAPI implements DigitalLibraryServicesAPIA { /** The Logger for this class */ static Logger LOG = Logger.getLogger(GS3ServicesAPIA.class); /** Storing the baseURL, worked out from wsdlURL */ protected String baseURL; /** Storing language settings for requests and responses*/ protected String language; /** Displays a dialog to get user input for the location of the Greenstone 3 * web services' WSDL file */ public GS3ServicesAPIA() throws ServiceException, MalformedURLException, ParserConfigurationException, IOException, Exception { this(showWsdlInputDialog()); } /** GS3ServicesAPIA constructor, which, given the url to the wsdl file, * finds either service and port or the service's endpoint of the GS3 Web * Services and instantiates the associated Service and Call objects. * @param wsdlURLName - location of the WSDL for Greenstone 3's * web services */ public GS3ServicesAPIA(String wsdlURLName) throws ServiceException, MalformedURLException, ParserConfigurationException, IOException, SAXException { super(wsdlURLName); // Very important to initialise member language to some value, in // this case, it is set to "" (which Greenstone takes as English). this.language = ""; // work out the baseURL from the wsdlURL, which is just the domain prefix // (e.g. http://localhost:8383) String url = wsdlURLName; int index = url.indexOf("://") + "://".length(); index = url.indexOf('/', index); url = url.substring(0, index); // everything upto the first / separator this.baseURL = url; } /** Static method that displays a dialog requesting the user to * input the location of Greenstone 3 web services' WSDL file. * @return a String representing the URL location of Greenstone 3 web * services' WSDL file */ public static String showWsdlInputDialog() throws Exception { String wsdlURL = ""; Properties properties = new Properties(); // set default values from any properties file try { if(DigitalLibraryServicesAPIA.propertiesFile.exists()) { properties.load(new java.io.FileInputStream( DigitalLibraryServicesAPIA.propertiesFile)); } } catch(Exception e) { LOG.warn("Exception loading properties from file " + DigitalLibraryServicesAPIA.propertiesFile + ": " + e); } // Show the dialog and get input for the wsdlURL property // It will display GS3WebServicesQBRAPI.defaultWsdlURL in the input // field if it can not find a wsdlURL property in the propertiesFile wsdlURL = JOptionPane.showInputDialog( "Enter the URL of the wsdl file of GS3's QBRSOAPServer web services", properties.getProperty("wsdlURL", GS3WebServicesQBRAPI.defaultWsdlURL) ); if(wsdlURL == null) { // cancel pressed throw new CancelException( "User cancelled out of connecting to GS3 Web Services"); } else { // if ok clicked, update properties with the input value properties.setProperty("wsdlURL", wsdlURL); } // Store the user-entered URL for future use, so it is loaded next time try { java.io.FileOutputStream out = new java.io.FileOutputStream( DigitalLibraryServicesAPIA.propertiesFile); properties.store(out, "GS3ServicesAPIA"); out.close(); } catch(Exception e) { LOG.warn("Exception writing properties to file " + DigitalLibraryServicesAPIA.propertiesFile + ": " + e); } return wsdlURL; } //************DigitalLibraryServicesAPIA METHOD IMPLEMENTATIONS************// /** @return the name of this digital library for displaying in the client */ public String getDisplayName() { return "Greenstone3"; } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * Sets the preferred language (code) for metadata and other content to be * returned on request messages. If the preferred language is not available, * the implementation may choose to send English back instead, or failing * that, send the data in any other available language. * @param language has to be a language code as recognised by Greenstone3 * (the language codes used by W3C probably). E.g. "en" for English. */ public void setLanguage(String language) { this.language = language; } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * Gets the language that's set as the preferred language. * @return the language code as recognised by Greenstone3 (which are the * language codes used by W3C probably). E.g. "en" for English. */ public String getLanguage() { return language; } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @return the overall directory path for associated files (not including * the document's nodeID/pid). This can be used to *formulate* the base url * of JEditorPane's HTML documents. If the documents from any digital library * do not contain relative paths, or otherwise deal with the resolution of * relative urls themselves, then return "" from here. */ public String getAssocFileBaseURL() { return baseURL; // return ""; // for old GS3 } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @return the directory path to the associated files of the given document * node. For instance, the base url of a JEditorPane's HTML documents can be * set to this. */ public String getAssocFileBaseURL(DocumentNodeData docNode) { return "_httpdocimg_/"; // for now. // TODO: /*DocumentNodeData root = docNode.getRoot(); if(root != null) return root.getAssocFilePath(); else return "";*/ } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract * @return Greenstone3 XML describe response message originating from * the Message Router, describing the Collections, ServiceRacks * and Services supported by the Message Router for all collections. */ public String describe() { return this.describe(language, ""); } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @param collection is the name of the collection to be described. * @return Greenstone3 XML describe response message originating from a * collection, describing the collection (display items) as well as * listing any services supported specifically by the collection. */ public String describeCollection(String collection) { return this.describeCollection(collection, language, ""); } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @param collection is the name of the collection to be described. * @param service is the name of the collection's service to be described. * @return Greenstone3 XML describe response message originating from a * collection's service, describing the service (display items). */ public String describeCollectionService(String collection, String service) { return this.describeCollectionService(collection, service, language, ""); } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @param service is the name of the collection's service to be described. * @return Greenstone3 XML describe response message originating from a * general (non-collection specific) service, describing the requested * service (for example with GS3 display items). */ public String describeService(String service) { return this.describeService(service, language, ""); } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @param collection is the name of the collection. * @param docIDs is an array of document identifiers of documents whose (text) * contents are requested. * @return a String representing Greenstone3 DocumentContentRetrieve XML * containing the document contents of the documents indicated by docIDs */ public String retrieveDocumentContent(String collection, String[] docIDs) { return this.retrieveDocumentContent(collection, language, docIDs); } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @param collection is the name of the collection. * @param docID is the document identifier of the document whose (text) * content is requested. * @return a String representing Greenstone3 DocumentContentRetrieve XML * containing the document contents of the document indicated by docID */ public String retrieveDocumentContent(String collection, String docID) { return this.retrieveDocumentContent(collection, language, new String[]{ docID }); } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @param collection is the name of the collection. * @param docIDs is an array of document identifiers of documents whose * metadata is requested. * @return a String representing Greenstone3 DocumentMetadataRetrieve XML * containing all the metadata of all the documents indicated by docIDs * @param metadata is the list of metadata elements to be retrieved for each doc. */ public String retrieveDocumentMetadata(String collection, String[] docIDs, String[] metafields) { return this.retrieveDocumentMetadata(collection, language, docIDs, metafields); } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @param collection is the name of the collection. * @param docID is the document identifier of the document whose metadata is * requested. * @return a String representing Greenstone3 DocumentMetadataRetrieve XML * containing all the metadata of the document denoted by docID * @param metadata is the list of metadata elements to be retrieved for each doc. */ public String retrieveDocumentMetadata(String collection, String docID, String[] metafields) { return this.retrieveDocumentMetadata(collection, language, new String[] { docID }, metafields); } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @param collection is the name of the collection. * @param docIDs is an array of document identifiers of documents whose titles * are requested * @return a String representing Greenstone3 DocumentMetadataRetrieve XML * containing only the title metadata of the documents denoted by docIDs */ public String retrieveTitleMetadata(String collection, String[] docIDs) { final String[] titleMetaName = {"Title"}; return this.retrieveDocumentMetadata(collection, language, docIDs, titleMetaName); } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @return a String representing Greenstone3 DocumentMetadataRetrieve XML * containing only the title metadata of the document denoted by docID * @param collection is the name of the collection * @param docID is the document identifier of the document whose titles is * requested */ public String retrieveTitleMetadata(String collection, String docID) { final String[] titleMetaName = {"Title"}; return this.retrieveDocumentMetadata(collection, language, new String[] { docID }, titleMetaName); } /** @return a String representing Greenstone3 DocumentMetadataRetrieve XML * containing the requested portion of the document structure of the documents * indicated by docIDs: * @param collection is the name of the collection. * @param docIDs is an array of document identifiers of documents whose * hierarchical structures are requested. * @param structure - strings specifying the required structure of each document. * It can be a combination of: ancestors, parent, siblings, children, descendants, entire. * @param info - strings specifying the required structural info of each document. * It can be any combination of: siblingPosition, numSiblings, numChildren. */ public String retrieveDocumentStructure(String collection, String[] docIDs, String[] structure, String[] info) { return retrieveDocumentStructure(collection, language, docIDs, structure, info); } /** @return a String representing Greenstone3 DocumentMetadataRetrieve XML * containing the requested portion of the document structure of the documents * indicated by docIDs: * @param collection is the name of the collection. * @param docID is the document identifier of the document whose hierarchical * structure is requested. * @param structure - strings specifying the required structure of the document. * It can be a combination of: ancestors, parent, siblings, children, descendants, entire. * @param info - strings specifying the required structural info of the document. * It can be any combination of: siblingPosition, numSiblings, numChildren. */ public String retrieveDocumentStructure(String collection, String docID, String[] structure, String[] info) { return retrieveDocumentStructure(collection, language, new String[] {docID}, structure, info); } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @return a String representing Greenstone3 DocumentMetadataRetrieve XML * containing the document structure of the documents indicated by docIDs: * this means all their descendants * @param collection is the name of the collection * @param docIDs is an array of document identifiers of documents whose * hierarchical structures are requested */ public String retrieveDocumentStructure(String collection, String[] docIDs) { return this.retrieveEntireDocumentStructure(collection, language, docIDs); } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @return a String representing Greenstone3 DocumentMetadataRetrieve XML * containing the document structure of the document indicated by docID: * this means all its descendants * @param collection is the name of the collection * @param docID is the document identifier of the document whose hierarchical * structure is requested*/ public String retrieveDocumentStructure(String collection, String docID) { return this.retrieveEntireDocumentStructure(collection, language, new String[] { docID }); } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @return a String representing Greenstone3 DocumentMetadataRetrieve XML * containing a view of the document structure of the documents denoted by * docs where only the requested documents and their direct children are * returned. * @param collection is the name of the collection * @param docIDs is an array of document identifiers of documents whose * hierarchical structures are requested */ public String retrieveDocumentChildren(String collection, String[] docIDs) { return this.retrieveDocumentStructure(collection, collection, docIDs, new String[] { "children" }, null); } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @return a String representing Greenstone3 DocumentMetadataRetrieve XML * containing a view of the document structure of the document denoted by * docID where only the document and its direct children are returned. * @param collection is the name of the collection * @param docID is the document identifier of the document whose hierarchical * structure is requested */ public String retrieveDocumentChildren(String collection, String docID) { return this.retrieveDocumentStructure(collection, collection, new String[] { docID }, new String[] { "children" }, null); } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @return a String representing Greenstone3 ClassifierBrowse XML * giving the entire *structure* of the classification denoted by * classifierID (including the structures of document descendants of * the classifier). * @param classifierIDs - each ID is of the form CL# where the number (#) * marks out structured sections like CL1.1.3 or CL2 * @param collection is the name of the collection * @param service is the name of the browse service (=ClassifierBrowse usually) * @param structure - the requested browse substructure. Can be any combination * of ancestors, parent, siblings, children, descendants. * @param info - the requested structural info. Can be numSiblings, siblingPosition, * numChildren */ public String retrieveBrowseStructure(String collection, String service, String[] classifierIDs, String[] structure, String[] info) { return this.browse(collection, service, language, classifierIDs, structure, info); } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @return a String representing Greenstone3 * ClassifierBrowseMetadataRetrieve XML giving all the metadata for * all the subclassifiers denoted by nodeIDs. * @param nodeIDs is of the form CL#.# where the number (#) marks * out structured sections like CL2.1.3. NodeIDs are generally subsections * of top-level classifierNodes (CL#, e.g. CL3). * @param metafields are the classifier metadata fields that are to be returned. * @param collection is the name of the collection * @param service is the name of the Browse's MetadataRetrieve service * (usually the browse service is ClassifierBrowse, in which case it always * has a retrieve service called ClassifierBrowseMetadataRetrieve) */ public String retrieveBrowseMetadata(String collection, String service, String[] nodeIDs, String[] metafields) { return this.retrieveBrowseMetadata(collection, service, language, nodeIDs, metafields); } /** Part of the GS3 Java-Client's DigitalLibraryServicesAPIA interface * contract. * @return a String representing Greenstone3 XML for a query process * response returning the results for the query denoted by parameter * nameValParamsMap. * @param nameValParamsMap is a Map of name and value pairs for all the * query field data values. The names match the field names that * describeCollectionService() would have returned for the query service. * @param collection is the name of the collection * @param service is the name of the query service */ public String query(String collection, String service, Map nameValParamsMap) { return this.query(collection, service, language, nameValParamsMap); } /*public static void main(String args[]) { try{ GS3ServicesAPIA ws = new GS3ServicesAPIA(); // (1) trying 4 describe methods System.out.println(ws.describe("", "")); System.out.println(ws.describeCollectionOrServiceRack("gs2mgppdemo", "", "")); System.out.println(ws.describeCollectionService("gs2mgppdemo", "AdvancedFieldQuery", "", "")); System.out.println(ws.describeService("AddItem", "", "")); // (2) try 3 query methods (simplerFieldQuery twice) + getFieldNameMappings() Map map = new HashMap(); map.put("maxDocs", "100"); map.put("level", "Sec"); map.put("accent", "1"); map.put("matchMode", "some"); map.put("fqf", "ZZ,ZZ,ZZ,ZZ"); map.put("case", "1"); map.put("sortBy", "1"); map.put("fqv", "snail,water,,"); String response = ws.query("gs2mgppdemo", "FieldQuery", "", map); System.out.println("Regular query: " + response); System.out.println("Field mappings: " + ws.getFieldNameMappings()); response = ws.simplerFieldNameQuery( "gs2mgppdemo", "FieldQuery", "", map); System.out.println("response:\n" + response); // trying the same with special field names map.clear(); map.put("maxDocs", "100"); map.put("level", "Sec"); map.put("accent", "on"); map.put("matchMode", "some"); map.put("fields", "all fields,all fields,all fields,all fields"); map.put("case", "on"); map.put("sortBy", "on"); map.put("values", "snail,water,,"); response = ws.simplerFieldNameQuery( "gs2mgppdemo", "FieldQuery", "", map); System.out.println("response:\n" + response); // trying query - array version String[] names = {"maxDocs", "level", "accent", "matchMode", "fqf", "case", "sortBy", "fqv"}; String[] values = {"100", "Sec", "1", "some", "ZZ,ZZ,ZZ,ZZ", "1", "1", "snail,water,,"}; System.out.println(ws.query("gs2mgppdemo", "FieldQuery", "", names, values)); // (3) try 2 browse System.out.println("describe browse:\n" + ws.describeCollectionService("gs2mgppdemo", "ClassifierBrowse", "", "")); System.out.println("browse children of CL1-CL4:\n" + ws.browse("gs2mgppdemo", "ClassifierBrowse", "", new String[]{"CL1", "CL2", "CL3", "CL4"}, new String[]{"children"})); System.out.println("browse descendants of CL2.3:\n" + ws.browseDescendants("gs2mgppdemo", "ClassifierBrowse", "", new String[]{"CL2.3"})); // (4) try 2 DocStructure System.out.println("retrieve ancestors and children structure of HASH016193b2847874f3c956d22e.4:\n" + ws.retrieveDocumentStructure("gs2mgppdemo", "", new String[]{"HASH016193b2847874f3c956d22e.4"}, new String[]{"ancestors", "children"}, new String[]{"numSiblings"})); System.out.println("retrieve entire structure of HASH016193b2847874f3c956d22e.4.1:\n" + ws.retrieveEntireDocumentStructure( "gs2mgppdemo", "", new String[]{"HASH016193b2847874f3c956d22e.4.1"})); // (5) try the 1 DocumentContent retrieve System.out.println("retrieve content of HASH016193b2847874f3c956d22e.4:\n" + ws.retrieveDocumentContent("gs2mgppdemo", "", new String[]{"HASH016193b2847874f3c956d22e.4", "HASH016193b2847874f3c956d22e.4.1", "HASH016193b2847874f3c956d22e.4.2"})); // (6) try 2 DocumentMeta System.out.println("retrieve title meta of HASH016193b2847874f3c956d22e.4 children:\n" + ws.retrieveDocumentMetadata("gs2mgppdemo", "", new String[]{"HASH016193b2847874f3c956d22e.4.1", "HASH016193b2847874f3c956d22e.4.2", "HASH016193b2847874f3c956d22e.4.3"}, new String[]{"Title"})); System.out.println("retrieve all meta of HASH016193b2847874f3c956d22e.4 children:\n" + ws.retrieveAllDocumentMetadata("gs2mgppdemo", "", new String[]{"HASH016193b2847874f3c956d22e.4", "HASH016193b2847874f3c956d22e.4.1", "HASH016193b2847874f3c956d22e.4.2", "HASH016193b2847874f3c956d22e.4.3"})); // (7) try 2 BrowseMeta System.out.println("retrieve all browse meta of CL1, CL2, CL2.1, CL3:\n" + ws.retrieveAllBrowseMetadata("gs2mgppdemo", "", "", new String[]{"CL1", "CL2", "CL2.1", "CL3"})); System.out.println("retrieve Title, hastxt browse meta of CL1, CL2, CL2.1, CL3:\n" + ws.retrieveBrowseMetadata("gs2mgppdemo", "", "", new String[]{"CL1", "CL2","CL2.1", "CL3"}, new String[]{"Title", "hastxt"})); // (8) try process: String requestXMLMessage = "" + "" + "" + "" + "" + "" + "" + ""; System.out.println(ws.process(requestXMLMessage)); // (9) activate, deactivate and the 2 reconfigures System.out.println("activate:\n" + ws.activate("collection", "gs2mgppdemo")); System.out.println("deactivate:\n" + ws.deactivate("site", "site1")); System.out.println("configure MR:\n" + ws.reconfigure()); System.out.println("configure:\n" + ws.reconfigure("collectionList")); // (10) 1 format System.out.println("format:\n" + ws.format("gs2mgppdemo", "FieldQuery", "")); // (11) 2 processType: build/NewCollection, build/ImportCollection System.out.println("describe build/NewCollection:\n" + ws.describeService("build/NewCollection", "", "")); Map params = new HashMap(10); params.put("creator", "me@home"); params.put("collName", "the demo collection"); params.put("collShortName", "demo"); System.out.println("processType build/NewCollection:\n" + ws.processTypeService("build/NewCollection", "", params)); params.clear(); params.put("collection", "demo"); System.out.println("processType build/ImportCollection:\n" + ws.processTypeService("build/ImportCollection", "", params)); // (12) Test status(), if possible System.out.println("status:\n" + ws.status("build/NewCollection", "", "1")); // (13) One applet-type service: //Map params = new HashMap(10); params.clear(); params.put("pc", "1"); params.put("pptext", "health"); params.put("pfe", "0"); params.put("ple", "10"); params.put("pfd", "0"); params.put("pld", "10"); params.put("pfl", "0"); params.put("pll", "10"); System.out.println("appletTypeService:\n" + ws.appletTypeService("gs2mgppdemo", "PhindApplet", "query", params)); // no PhindApplet service deployed in gs2mgppdemo anymore, so maybe that's // why it doesn't work. The request matches what's in the manual (p.50) though. // (14) One enrich service: params.clear(); params.put("annotationType", "Date,Location"); String[] nodeIDs = {"HASHac0a04dd14571c60d7fbfd"}; String[] nodeContents = { "FOOD AND AGRICULTURE ORGANIZATION OF THE UNITED NATIONS\n" + "Rome 1986\nP-69\nISBN 92-5-102397-2\nFAO 1986"}; System.out.println("enrich:\n" + ws.enrich("GatePOSTag", "en", params, nodeIDs, nodeContents)); // no GatePOSTag service deployed in gs2mgppdemo anymore, so maybe that's // why it doesn't work. The request matches what's in the manual (p.50) though. // (16) try help System.out.println(ws.help()); System.out.println(ws.help("describe")); }catch(Exception e) { System.out.println("Problem accessing service\n" + e.getMessage()); e.printStackTrace(); } }*/ }