Changeset 22300 for other-projects/gs3-webservices-java-client/trunk/src/GS3Fedora/org/greenstone/fedora/services/FedoraGS3Connection.java
- Timestamp:
- 2010-06-24T13:45:34+12:00 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
other-projects/gs3-webservices-java-client/trunk/src/GS3Fedora/org/greenstone/fedora/services/FedoraGS3Connection.java
r21924 r22300 90 90 * then query services will not be offered */ 91 91 protected String[] serviceNames; 92 93 /** constant CHILDREN indicates that a DocumentStructureRetrieve is to94 * return only the child nodes of a section, not any further descendants */95 protected static final int CHILDREN = 0;96 97 /** constant DESCENDANTS indicates that a DocumentStructureRetrieve is to98 * return all descendants of a section */99 protected static final int DESCENDANTS = 1;100 92 101 93 /** The object used to connect to FedoraGenericSearch, which is used … … 362 354 * @return a GS3 DocumentMetadataRetrieve response message containing the 363 355 * EX metadata for all the requested collections */ 364 365 return getMetadata(collIDs);356 public String getCollectionMetadata(String[] collIDs) { 357 return getMetadata(collIDs, new String[] {"all"}); 366 358 } 367 359 … … 372 364 * "<pid>-sectionNumber". 373 365 * @return a GS3 DocumentMetadataRetrieve response message containing the 374 * EX, DC, DLS metadata for all the requested documents */ 375 public String getDocumentMetadata(String[] docIDs) { 376 return getMetadata(docIDs); 366 * EX, DC, DLS metadata for all the requested documents 367 * @param metadata is the list of metadata elements to be retrieved for each doc */ 368 public String getDocumentMetadata(String[] docIDs, String[] metadata) { 369 return getMetadata(docIDs, metadata); 377 370 } 378 371 … … 381 374 * @param collID is a fedora pid identifying a collection in its repository 382 375 * @return a GS3 DocumentMetadataRetrieve response message containing the 383 * EX metadata for the requested collection */ 376 * EX metadata for the requested collection 377 * @param metadata is the list of metadata elements to be retrieved for each doc */ 384 378 public String getCollectionMetadata(String collID) { 385 return getMetadata(new String[] {collID});379 return getMetadata(new String[] {collID}, new String[] {"all"}); 386 380 } 387 381 … … 393 387 * @return a GS3 DocumentMetadataRetrieve response message containing the 394 388 * EX, DC, DLS metadata for the requested document */ 395 public String getDocumentMetadata(String docID) {396 return getMetadata(new String[] {docID});389 public String getDocumentMetadata(String docID, String[] metadata) { 390 return getMetadata(new String[] {docID}, metadata); 397 391 } 398 392 … … 402 396 * fedora pids for collections, or otherwise may be a document identifier. 403 397 * In the last case, the document ID may consist of either 404 * "documentPID-sectionNumber" or may just be just fedora documentPID */ 405 public String getMetadata(String[] docIDsOrCollIDs) 398 * "documentPID-sectionNumber" or may just be just fedora documentPID 399 * @param metadata is the list of metadata elements to be retrieved for each doc */ 400 public String getMetadata(String[] docIDsOrCollIDs, String[] metadata) 406 401 { 407 402 Document doc = builder.newDocument(); … … 415 410 // create the <documentNode> containing the metadata 416 411 // for each document docID 417 Element docNode = getMetadata(doc, docIDsOrCollIDs[i]);412 Element docNode = getMetadata(doc, docIDsOrCollIDs[i], metadata); 418 413 docNodeList.appendChild(docNode); 419 414 } … … 426 421 GSXML.REQUEST_TYPE_PROCESS, "DocumentMetadataRetrieve"); 427 422 try{ 428 return FedoraCommons.elementTo FormattedString(responseMsg);423 return FedoraCommons.elementToString(responseMsg); 429 424 } catch(TransformerException e) { 430 425 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg … … 444 439 * document given by parameter ID 445 440 * @param id denotes a collection pid, a document pid or a docID of the 446 * form "documentpid-sectionNumber" */ 447 protected Element getMetadata(Document doc, String id) 441 * form "documentpid-sectionNumber" 442 * @param metadata is the list of metadata elements to be retrieved for each doc */ 443 protected Element getMetadata(Document doc, String id, String[] metadata) 448 444 throws RemoteException, UnsupportedEncodingException, 449 445 SAXException, IOException … … 500 496 } 501 497 498 String metafields = ""; 499 for(int i = 0; i < metadata.length; i++) { 500 metafields = metafields + metadata[i] + "|"; 501 } 502 502 503 // Adding in metadata sets in alphabetical order 503 504 // DC metadata for a top-level document is different from EX, DLS: … … 506 507 if(!dc.equals("")) { 507 508 addMetadataWithNamespacedTagNames(doc, metadataList, 508 dc, DC);509 dc, DC, metafields); 509 510 } 510 511 … … 513 514 // in which case, dls and dc will be non-empty strings 514 515 if(!dls.equals("")) { 515 addMetadataWithFixedTagName(doc, metadataList, dls, DLS);516 addMetadataWithFixedTagName(doc, metadataList, dls, DLS, metafields); 516 517 } 517 518 … … 519 520 // collection object, top-level document object, 520 521 // and document section item 521 addMetadataWithFixedTagName(doc, metadataList, ex, EX );522 addMetadataWithFixedTagName(doc, metadataList, ex, EX, metafields); 522 523 523 524 // now the metadataList has been built up … … 539 540 * Dublin Core metadata stored in the Fedora repository). 540 541 * @param metadataSet is the constant datastream identifier, e.g. "DC". 541 * At present this method only applies to the DC metadata as that's the only 542 * one where each tagname is different except for the constant dc: namespace. 542 * At present this method applies to the DC metadata and any others like it 543 * where each tagname is different except for the constant dc: namespace. 544 * @param metafields is a | separated string containing the metadatafields to 545 * extract or "all" if all fields are requested 543 546 */ 544 protected void addMetadataWithNamespacedTagNames(Document doc, 545 Element metadataList, String metaDatastream, String metadataSet)547 protected void addMetadataWithNamespacedTagNames(Document doc, Element metadataList, 548 String metaDatastream, String metadataSet, String metafields) 546 549 throws SAXException, IOException 547 550 { … … 551 554 // The following doesn't work for some reason: to retrieve all elements 552 555 // whose namespace prefix starts with "dc", we pass "*" for localName 553 //NodeList dcMetaTags = src.getElementsByTagNameNS( DC.toLowerCase(), "*");556 //NodeList dcMetaTags = src.getElementsByTagNameNS(metadataSet.toLowerCase(), "*"); 554 557 555 558 // Longer way: get the children of the root document … … 558 561 for(int i = 0; i < children.getLength(); i++) { 559 562 String nodeName = children.item(i).getNodeName(); 560 // check that the nodename starts with the "dc"namespace,563 // check that the nodename starts with the metadataSet ("dc") namespace, 561 564 // which simultaneously ensures that the node's an element: 562 if(nodeName.startsWith(DC.toLowerCase())) { 563 // need to have a period for Greenstone instead of Fedora's colon 564 nodeName = nodeName.replace(COLON, PERIOD); 565 if(nodeName.toLowerCase().startsWith(metadataSet.toLowerCase())) { 566 // need to have a period for Greenstone instead of Fedora's colon 567 nodeName = nodeName.replace(COLON, PERIOD); 568 if(metadataSet.equals(DC)) { // dc:title -> dc.Title 569 nodeName = "dc" + PERIOD + Character.toString(Character.toUpperCase(nodeName.charAt(3))) 570 + nodeName.substring(4); 571 } 572 573 // get the requested metadata fields 574 if(metafields.indexOf("all") != -1 || metafields.indexOf(nodeName) != -1) { 565 575 Element metatag = (Element)children.item(i); 566 576 String value = FedoraCommons.getValue(metatag); 567 577 // <dc:tagname>value</dc:tagname> 568 // we're going to put usethis in our metadata element as569 // <metadata name="dc :tagname">value</metadata>578 // we're going to put this in our metadata element as 579 // <metadata name="dc.Tagname">value</metadata> 570 580 571 581 // create metadata of (name, value) pairs in target DOM (doc) 572 582 Element metadata = doc.createElement(GSXML.METADATA_ELEM); 573 583 Attr attribute = doc.createAttribute(GSXML.NAME_ATT); 584 574 585 attribute.setValue(nodeName); 575 586 metadata.setAttributeNode(attribute); … … 577 588 metadata.appendChild(content); 578 589 metadataList.appendChild(metadata); 590 } 579 591 } 580 592 } … … 586 598 * is the name of the metadata (like author, title). For each element 587 599 * it creates a corresponding new element of the form 588 * <metadata name="namespace:metadataName">value</metadata>. Each of these589 * are then appended to the metadataList parameter.600 * <metadata name="namespace:metadataName">value</metadata>. 601 * Each of these are then appended to the metadataList parameter. 590 602 * @param doc is the Document object using which the new metadata Elements 591 603 * are to be constructed … … 599 611 * At present this method applies to the DLS and EX metadata as they have 600 612 * constant tagnames throughout. 613 * @param metafields is a | separated string containing the metadatafields to 614 * extract or "all" if all fields are requested. 601 615 */ 602 protected void addMetadataWithFixedTagName(Document doc, 603 Element metadataList, String metaDatastream, String metadataSet)616 protected void addMetadataWithFixedTagName(Document doc, Element metadataList, 617 String metaDatastream, String metadataSet, String metafields) 604 618 throws SAXException, IOException 605 619 { … … 630 644 name = name + HYPHEN + metatag.getAttribute(QUALIFIER); 631 645 } 632 String value = FedoraCommons.getValue(metatag); 633 634 // create metadata of (name, value) pairs in target DOM (doc) 635 Element metadata = doc.createElement(GSXML.METADATA_ELEM); 636 Attr attribute = doc.createAttribute(GSXML.NAME_ATT); 637 attribute.setValue(namespacePrefix + name); 638 // prefix with namespace, if any 639 metadata.setAttributeNode(attribute); 640 Text content = doc.createTextNode(value); 641 metadata.appendChild(content); 642 643 metadataList.appendChild(metadata); 646 name = namespacePrefix + name; // prefix with namespace, if any 647 if(metafields.indexOf("all") != -1 || metafields.indexOf(name) != -1) { 648 String value = FedoraCommons.getValue(metatag); 649 650 // create metadata of (name, value) pairs in target DOM (doc) 651 Element metadata = doc.createElement(GSXML.METADATA_ELEM); 652 Attr attribute = doc.createAttribute(GSXML.NAME_ATT); 653 attribute.setValue(name); 654 metadata.setAttributeNode(attribute); 655 Text content = doc.createTextNode(value); 656 metadata.appendChild(content); 657 658 metadataList.appendChild(metadata); 659 } 644 660 } 645 661 } … … 688 704 GSXML.REQUEST_TYPE_PROCESS, "DocumentMetadataRetrieve"); 689 705 try{ 690 return FedoraCommons.elementTo FormattedString(responseMsg);706 return FedoraCommons.elementToString(responseMsg); 691 707 } catch(TransformerException e) { 692 708 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg … … 747 763 } 748 764 749 750 /** @return the documentStructure of the document or section given by docID. 751 * The structure is returned in the XML format of a Greenstone3 752 * DocumentStructureRetrieve response message. This method returns the entire 753 * subSection of the docID (that is, all descendants included). 754 * @param docID the identifier for the document whose structure is required. 755 * This is of the format "greenstone:<collectionName>-<docPID>" 756 * OR "greenstone:<collectionName>-<docPID>-<sectioNumber>" 757 * where "greenstone:<collectionName>-<docPID>-1" is the same as 758 * "greenstone:<collectionName>-<docPID>" and will return the 759 * same response */ 760 public String getDocumentStructure(String docID) { 761 return getStructure(new String[]{docID}, DESCENDANTS); 762 } 763 764 /** @return a view of the structure of the document or section given by docID 765 * which contains only the section and its direct children. This structure is 766 * returned in the XML format of a Greenstone3 DocumentStructureRetrieve 767 * response message. 768 * @param docID the identifier for the document whose structure is required. 769 * This is of the format "greenstone:<collectionName>-<docPID>" 770 * OR "greenstone:<collectionName>-<docPID>-<sectioNumber>" 771 * where "greenstone:<collectionName>-<docPID>-1" is the same as 772 * "greenstone:<collectionName>-<docPID>" and will return the 773 * same response */ 774 public String getChildren(String docID) { 775 return getStructure(new String[]{docID}, CHILDREN); 776 } 777 778 /** @return the documentStructure of the documents or sections given by docIDs. 779 * The structure is returned in the XML format of a Greenstone3 780 * DocumentStructureRetrieve response message. This method returns the entire 781 * subSection of each docID (that is, all descendants included). 782 * @param docIDs is an array of identifiers for the documents whose structures 783 * are required. 784 * This is of the format "greenstone:<collectionName>-<docPID>" 785 * OR "greenstone:<collectionName>-<docPID>-<sectioNumber>" 786 * where "greenstone:<collectionName>-<docPID>-1" is the same as 787 * "greenstone:<collectionName>-<docPID>" and will return the 788 * same response */ 789 public String getDocumentStructure(String[] docIDs) { 790 return getStructure(docIDs, DESCENDANTS); 791 } 792 793 /** @return the documentStructure of the documents or sections given by docIDs 794 * but only the sections and their children (not any further descendants). 795 * The structure is returned in the XML format of a Greenstone3 796 * DocumentStructureRetrieve response message. 797 * @param docIDs the identifiers for the documents whose structures are 798 * required. The docids are of the format "greenstone:<collectionName>-<docPID>" 799 * OR "greenstone:<collectionName>-<docPID>-<sectioNumber>" 800 * where "greenstone:<collectionName>-<docPID>-1" is the same as 801 * "greenstone:<collectionName>-<docPID>" and will return the 802 * same response */ 803 public String getChildren(String[] docIDs) { 804 return getStructure(docIDs, CHILDREN); 805 } 806 807 /** 765 /** @return a String representing Greenstone3 DocumentMetadataRetrieve XML 766 * containing the requested portion of the document structure of the documents 767 * indicated by docIDs: 768 * @param docID is the document identifier of the document whose hierarchical 769 * structure is requested. The name of the collection is already included in the 770 * docID for a Fedora DL. 771 * @param structure - strings specifying the required structure of the document. 772 * It can be a combination of: ancestors, parent, siblings, children, descendants, entire. 773 * @param info - strings specifying the required structural info of the document. 774 * It can be any combination of: siblingPosition, numSiblings, numChildren. 775 */ 776 public String getDocumentStructure(String docID, String[] structure, String[] info) { 777 return getStructure(new String[]{docID}, structure, info); 778 } 779 780 781 /** @return a String representing Greenstone3 DocumentMetadataRetrieve XML 782 * containing the requested portion of the document structure of the documents 783 * indicated by docIDs: 784 * @param docIDs is an array of document identifiers of documents whose 785 * hierarchical structures are requested. The name of the collection is already 786 * included in the docID for a Fedora DL. 787 * @param structure - strings specifying the required structure of each document. 788 * It can be a combination of: ancestors, parent, siblings, children, descendants, entire. 789 * @param info - strings specifying the required structural info of each document. 790 * It can be any combination of: siblingPosition, numSiblings, numChildren. 791 */ 792 public String getDocumentStructure(String[] docIDs, String[] structure, String[] info) { 793 return getStructure(docIDs, structure, info); 794 } 795 796 /** 808 797 * Returns a greenstone3 DocumentStructureRetrieve XML response message 809 798 * containing the document structures for the given docIDs. … … 814 803 * @param docIDs the documentIDs for which the section's structure is returned; 815 804 * where a docID is either a fedora pid <docPID> or <docPID>-<sectionNumber>. 816 * @param levels - either CHILDREN or DESCENDANTS. 817 * CHILDREN returns only the first-level descendants (children) of the 818 * requested document sections indicated by docIDs. 819 * DESCENDANTS returns all descendants of all the document-sections denoted by 820 * docIDs. 805 * @param structure - the structure of the sections to return. Can be any combination of: 806 * ancestors, parent, siblings, children, descendants, entire. 807 * @param infos - strings containing any combination of the values: numChildren, numSiblings, 808 * siblingPosition. The requested info gets added as attributes to the returned root element. 821 809 * @return a greenstone3 DocumentStructureRetrieve XML response message in 822 810 * String format with the structure of the docIDs requested. 823 811 */ 824 protected String getStructure(String[] docIDs, int levels)812 protected String getStructure(String[] docIDs, String[] structure, String[] infos) 825 813 { 826 814 Document doc = builder.newDocument(); … … 833 821 // append the <documentNodes> for the docIDs 834 822 // to the docNodeList 835 getStructureElement(docNodeList, docIDs, levels); 823 //getStructureElement(docNodeList, docIDs, levels); 824 getStructureElement(docNodeList, docIDs, structure, infos); 836 825 } catch(Exception e) { 837 826 ex = new FedoraGS3RunException(e); … … 842 831 GSXML.REQUEST_TYPE_PROCESS, "DocumentStructureRetrieve"); 843 832 try{ 844 return FedoraCommons.elementTo FormattedString(responseMsg);833 return FedoraCommons.elementToString(responseMsg); 845 834 } catch(TransformerException e) { 846 835 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg … … 848 837 } 849 838 } 850 851 /** Given a <documentNodeList> portion of a greenstone3 839 840 841 /** Given a <documentNodeList> portion of a greenstone3 852 842 * DocumentStructureRetrieve XML response message, this method will populate 853 843 * it with the <documentNodes> that represent the structure of the given docIDs. … … 856 846 * @param docIDs the documentIDs for which the section's structure is returned; 857 847 * where a docID is either a fedora pid <docPID> or <docPID>-<sectionNumber>. 858 * @param levels - either CHILDREN or DESCENDANTS. 859 * CHILDREN returns only the first-level descendants (children) of the 860 * requested document sections indicated by docIDs. 861 * DESCENDANTS returns all descendants of all the document-sections denoted by 862 * docIDs. 848 * @param structures - the structure of the sections to return. Can be any combination of: 849 * ancestors, parent, siblings, children, descendants, entire. 850 * @param infos - a string containing any combination of the values: numChildren, numSiblings, 851 * siblingPosition. The requested info gets added as attributes to the returned root element. 863 852 */ 864 protected void getStructureElement(Element docNodeList, 865 String[] docIDs, int levels)853 protected void getStructureElement(Element docNodeList, String[] docIDs, 854 String[] structures, String[] infos) 866 855 throws RemoteException, UnsupportedEncodingException, SAXException, 867 856 IOException 868 857 { 869 // process each docID 870 for(int i = 0; i < docIDs.length; i++) { 871 // work out the document's fedora PID and section ID 872 String sectionID = getSectionIDFromDocID(docIDs[i]); 873 String docPID = getDocPIDFromDocID(docIDs[i]); 874 875 // get the required section, along with children or descendants 876 Element srcDocElement = null; 877 if(levels == CHILDREN) // get the requested section with its children 878 srcDocElement = this.getChildrenOfSectionXML(docPID, sectionID); 879 else // levels == DESCENDANTS, get the section with all its descendants 880 srcDocElement = this.getSubsectionXML(docPID, sectionID); 881 882 // copy-and-convert that structure into a structure format for GS3 883 Element docNode = getStructure(docNodeList.getOwnerDocument(), 884 docIDs[i], docPID, srcDocElement); 885 886 // add it to our list of documentNodes 887 docNodeList.appendChild(docNode); 888 } 889 } 858 // Make one string out of requested structure components, and one string from info components 859 String structure = ""; 860 String info = ""; 861 for(int i = 0; i < structures.length; i++) { 862 structure = structure + structures[i] + "|"; 863 } 864 for(int i = 0; i < infos.length; i++) { 865 info = info + infos[i] + "|"; 866 } 867 868 // process each docID 869 for(int i = 0; i < docIDs.length; i++) { 870 // work out the document's fedora PID and section ID 871 String sectionID = getSectionIDFromDocID(docIDs[i]); 872 String docPID = getDocPIDFromDocID(docIDs[i]); 873 if(sectionID.equals("")) { 874 sectionID = "1"; 875 } 876 877 // get the required section, along with children or descendants 878 Element srcDocElement = getSectionStructureXML(docPID, sectionID, structure, info); 879 Document doc = docNodeList.getOwnerDocument(); 880 881 // copy-and-convert that structure into a structure format for GS3 882 Element docNode = getStructure(doc, docIDs[i], docPID, srcDocElement); 883 884 if(!info.equals("")) { 885 // <nodeStructureInfo> 886 // <info name="" value="" /> 887 // <info name="" value="" /> 888 // ... 889 // </nodeStructureInfo> 890 Element nodeStructureInfo = doc.createElement(GSXML.NODE_STRUCTURE_ELEM+GSXML.INFO_ATT); 891 Element root = srcDocElement.getOwnerDocument().getDocumentElement(); 892 893 if(root.hasAttribute("numSiblings")) { 894 String numSiblings = root.getAttribute("numSiblings"); 895 Element infoEl = doc.createElement(GSXML.INFO_ATT); 896 infoEl.setAttribute(GSXML.NAME_ATT, "numSiblings"); 897 infoEl.setAttribute(GSXML.VALUE_ATT, numSiblings); 898 nodeStructureInfo.appendChild(infoEl); 899 } 900 901 if(root.hasAttribute("siblingPosition")) { 902 String siblingPosition = root.getAttribute("siblingPosition"); 903 Element infoEl = doc.createElement(GSXML.INFO_ATT); 904 infoEl.setAttribute(GSXML.NAME_ATT, "siblingPosition"); 905 infoEl.setAttribute(GSXML.VALUE_ATT, siblingPosition); 906 nodeStructureInfo.appendChild(infoEl); 907 } 908 909 if(root.hasAttribute("numChildren")) { 910 String numChildren = root.getAttribute("numChildren"); 911 Element infoEl = doc.createElement(GSXML.INFO_ATT); 912 infoEl.setAttribute(GSXML.NAME_ATT, "numChildren"); 913 infoEl.setAttribute(GSXML.VALUE_ATT, numChildren); 914 nodeStructureInfo.appendChild(infoEl); 915 } 916 docNode.appendChild(nodeStructureInfo); 917 } 918 919 // add it to our list of documentNodes 920 docNodeList.appendChild(docNode); 921 } 922 } 923 890 924 891 925 /** … … 916 950 Attr attribute = doc.createAttribute(GSXML.NODE_ID_ATT); 917 951 attribute.setValue(requestingDocID); //requestingDocID.replace(HYPHEN+SECTION, "") 918 docNode.setAttributeNode(attribute); 952 docNode.setAttributeNode(attribute); 919 953 920 954 // <nodeStructure> … … 932 966 return docNode; 933 967 } 934 968 969 935 970 /** Recursive method that creates a documentStructure mirroring parameter 936 971 * section, starting from parameter parent down to all descendants … … 983 1018 String sectionID = subSection.hasAttribute(ID) ? 984 1019 subSection.getAttribute(ID) : ""; 985 nodeID.setValue(docID + HYPHEN + sectionID); 1020 if(sectionID.equals("1") 1021 && subSection.getElementsByTagName(SECTION_ELEMENT).getLength() > 0) { // root, non-leaf case 1022 // reset the attribute without the section number 1023 nodeID.setValue(docID+ HYPHEN + sectionID); // maybe important for democlient? 1024 } else { 1025 nodeID.setValue(docID + HYPHEN + sectionID); 1026 } 1027 //nodeID.setValue(docID + HYPHEN + sectionID); 986 1028 docNode.setAttributeNode(nodeID); 987 1029 988 1030 Attr nodeType = doc.createAttribute(GSXML.NODE_TYPE_ATT); 989 if(sectionID.equals("1")) { // root case 990 nodeType.setValue(GSXML.NODE_TYPE_ROOT); 991 // reset the attribute without the section number 992 docNode.setAttribute(GSXML.NODE_ID_ATT, docID); 993 } 994 else if(subSection.getElementsByTagName(SECTION_ELEMENT).getLength() > 0) 995 // this section has further <Section> children, so it's an internal node 996 nodeType.setValue(GSXML.NODE_TYPE_INTERNAL); 997 else if(subSection.hasAttribute(TYPE)) 998 nodeType.setValue(GSXML.NODE_TYPE_INTERNAL); 999 else // leaf 1000 nodeType.setValue(GSXML.NODE_TYPE_LEAF); 1031 if(subSection.hasAttribute(GSXML.NODE_TYPE_ATT)) { 1032 nodeType.setValue(subSection.getAttribute(GSXML.NODE_TYPE_ATT)); 1033 } 1001 1034 docNode.setAttributeNode(nodeType); 1002 1035 return docNode; … … 1068 1101 GSXML.REQUEST_TYPE_PROCESS, "DocumentContentRetrieve"); 1069 1102 try{ 1070 return FedoraCommons.elementTo FormattedString(responseMsg);1103 return FedoraCommons.elementToString(responseMsg); 1071 1104 } catch(TransformerException e) { 1072 1105 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg … … 1202 1235 GSXML.REQUEST_TYPE_DESCRIBE, ""); 1203 1236 try { 1204 return FedoraCommons.elementTo FormattedString(responseMsg);1237 return FedoraCommons.elementToString(responseMsg); 1205 1238 }catch(TransformerException e) { 1206 1239 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg … … 1247 1280 GSXML.REQUEST_TYPE_DESCRIBE, ""); 1248 1281 try{ 1249 return FedoraCommons.elementTo FormattedString(responseMsg);1282 return FedoraCommons.elementToString(responseMsg); 1250 1283 }catch(TransformerException e) { 1251 1284 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg … … 1305 1338 GSXML.REQUEST_TYPE_DESCRIBE, collectionName); 1306 1339 try{ 1307 return FedoraCommons.elementTo FormattedString(responseMsg);1340 return FedoraCommons.elementToString(responseMsg); 1308 1341 }catch(TransformerException e) { 1309 1342 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg … … 1337 1370 GSXML.REQUEST_TYPE_DESCRIBE, collectionName); 1338 1371 try{ 1339 return FedoraCommons.elementTo FormattedString(responseMsg);1372 return FedoraCommons.elementToString(responseMsg); 1340 1373 }catch(TransformerException e) { 1341 1374 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg … … 1420 1453 GSXML.REQUEST_TYPE_DESCRIBE, from); 1421 1454 try{ 1422 return FedoraCommons.elementTo FormattedString(responseMsg);1455 return FedoraCommons.elementToString(responseMsg); 1423 1456 }catch(TransformerException e) { 1424 1457 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg … … 1694 1727 * user to browse the titles of documents in the given collection by letter 1695 1728 * and returning the results. 1729 * @param collectionName is the name of the collection whose documents 1730 * starting with the given letter will be returned. 1696 1731 * @param classifierIDs are the ids of the classifiers on which to browse. In 1697 1732 * this case, the classifier indicates whether we browse titles by letter, or 1698 1733 * browse (documents) by collection; and it is of the form <CL(letter)>. 1699 * @param collectionName is the name of the collection whose documents 1700 * starting with the given letter will be returned. 1701 * @return a GS3 DocumentStructureRetrieve response message which lists all 1734 * @param structures - the requested browse substructure. Can be any combination 1735 * of ancestors, parent, siblings, children, descendants. 1736 * @param infos - the requested structural info. Can be numSiblings, 1737 * siblingPosition, numChildren. 1738 * @return a GS3 ClassifierBrowse response message which lists all 1702 1739 * the documents that start with the letter indicated by parameter classifier. 1703 1740 */ 1704 public String browse(String collectionName, String[] classifierIDs) 1741 public String browse(String collectionName, String[] classifierIDs, 1742 String[] structures, String[] infos) 1705 1743 { 1706 Document doc = builder.newDocument(); 1707 FedoraGS3RunException ex = null; //any RemoteException or UnsupportedEncodingException 1708 1709 // <classifierNodeList> 1710 Element classifierNodeList = doc.createElement( 1711 GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER); 1712 1713 for(int i = 0; i < classifierIDs.length; i++) { 1714 // <classifierNode nodeID="classifierNum"> 1715 Element requestedClassifierNode = doc.createElement( 1716 GSXML.CLASS_NODE_ELEM); 1744 // Construct one string from the structures and structural info arrays 1745 String structure = ""; 1746 String info = ""; 1747 for(int i = 0; i < structures.length; i++) { 1748 structure = structure + structures[i] + "|"; 1749 } 1750 for(int i = 0; i < infos.length; i++) { 1751 info = info + infos[i] + "|"; 1752 } 1753 1754 Document doc = builder.newDocument(); 1755 FedoraGS3RunException ex = null; //any RemoteException or UnsupportedEncodingException 1756 1757 // <classifierNodeList> 1758 Element classifierNodeList = doc.createElement(GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER); 1759 1760 for(int i = 0; i < classifierIDs.length; i++) { 1761 if(classifierIDs[i].startsWith("CL1")) { // browse by titles 1762 browseTitlesByLetterClassifier(doc, classifierNodeList, 1763 collectionName, classifierIDs[i], 1764 structure, info); 1765 } 1766 } 1767 1768 Element responseMsg = createResponseMessage(doc, classifierNodeList, ex, 1769 GSXML.REQUEST_TYPE_DESCRIBE, /*collectionName+/ */"ClassifierBrowse"); 1770 try { 1771 return FedoraCommons.elementToString(responseMsg); 1772 } catch(TransformerException e) { 1773 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg 1774 + " " + e; 1775 } 1776 } 1777 1778 /** CL1 browsing classifier: browsing titles by starting letter. 1779 * The browsing structure is retrieved. 1780 * @param doc - the document object that will contain the CL1 browsing structure. 1781 * @param classifierNodeList - the classifiers will be added to this nodeList. 1782 * @param collectionName - name of the collection through which we are browsing CL1. 1783 * @param classifierID - the ID of the (sub)classifier. Can be CL1, CL1.x, where x is 1784 * a letter. 1785 * @param structure - the requested browse substructure. Can be any combination 1786 * of ancestors, parent, siblings, children, descendants. siblings not yet implemented. 1787 * @param info - the requested structural info. Can be numSiblings, siblingPosition, 1788 * numChildren. 1789 * @return the classifierNodeList with the CL1 classifier browse structure. 1790 */ 1791 public Element browseTitlesByLetterClassifier(Document doc, Element classifierNodeList, 1792 String collectionName, String classifierID, 1793 String structure, String info) 1794 { 1795 FedoraGS3RunException ex = null; //any RemoteException or UnsupportedEncodingException 1796 1797 // TODO 1798 if(structure.indexOf("siblings") != -1) { 1799 LOG.error("Structure: siblings. Not yet implemented\n"); 1800 } 1801 1802 if(structure.indexOf("entire") != -1) { 1803 structure = structure + "ancestors|descendants"; 1804 } 1805 1806 // Structure of ancestors and children only at this stage 1807 int firstLevel = classifierID.indexOf('.'); 1808 int secondLevel = classifierID.lastIndexOf('.'); 1809 1810 // <nodeStructure> 1811 Element nodeStructure = doc.createElement(GSXML.NODE_STRUCTURE_ELEM); 1812 1813 // requested classifier node 1814 Element classNode = doc.createElement(GSXML.CLASS_NODE_ELEM); 1815 Attr attribute = doc.createAttribute(GSXML.NODE_ID_ATT); 1816 attribute.setValue(classifierID); 1817 classNode.setAttributeNode(attribute); 1818 1819 if(firstLevel == -1) { // CL1 - toplevel node 1820 Element root = (Element)classNode.cloneNode(true); // clone the node before appending children 1821 1822 classifierNodeList.appendChild(classNode); 1823 classNode.appendChild(nodeStructure); 1824 1825 nodeStructure.appendChild(root); 1826 if(structure.indexOf("descendants") != -1) { 1827 getTitlesByLetterStructure(collectionName, root, classifierID, true); 1828 } else if(structure.indexOf("children") != -1) { 1829 getTitlesByLetterStructure(collectionName, root, classifierID, false); 1830 } 1831 } 1832 else if(firstLevel == secondLevel) { // CL1.x, where x is a number 1833 1834 if(structure.indexOf("parent") != -1 || structure.indexOf("ancestors") != -1) { 1835 String toplevelID = classifierID.substring(0, firstLevel); 1836 Element toplevelNode = doc.createElement(GSXML.CLASS_NODE_ELEM); 1837 attribute = doc.createAttribute(GSXML.NODE_ID_ATT); 1838 attribute.setValue(toplevelID); 1839 toplevelNode.setAttributeNode(attribute); 1840 Element node = (Element)toplevelNode.cloneNode(true); // clone nodes before appending children 1841 1842 classifierNodeList.appendChild(toplevelNode); 1843 toplevelNode.appendChild(nodeStructure); 1844 1845 nodeStructure.appendChild(node); 1846 node.appendChild(classNode); 1847 } else { 1848 Element node = (Element)classNode.cloneNode(true); 1849 classifierNodeList.appendChild(node); 1850 node.appendChild(nodeStructure); 1851 nodeStructure.appendChild(classNode); 1852 } 1853 1854 int num = Integer.parseInt(classifierID.substring(firstLevel+1)); // get x from CL1.x 1855 char ch = (char)(num - 1 + 'A'); 1856 if(structure.indexOf("descendants") != -1) { 1857 getTitlesForLetter(ch, collectionName, classNode, "descendants"); 1858 } else if(structure.indexOf("children") != -1) { 1859 getTitlesForLetter(ch, collectionName, classNode, "children"); 1860 } 1861 } 1862 else { // ought to be a doc structure retrieve request, not classifierbrowse structure retrieve 1863 LOG.error("ClassifierID: " + classifierID + ". Shouldn't be in browse method"); 1864 } 1865 1866 return classifierNodeList; 1867 } 1868 1869 /** Creates a (CL1) subclassifier element for the docs whose titles start with 1870 * the given letter. 1871 * @param ch - the starting letter of the document titles to retrieve. 1872 * @param collectionName - name of the collection through which we are browsing CL1. 1873 * @param classifierNode - the docNodes found will be appended to this node. 1874 * @param depthStructure - can be descendants or children. Specifies what to retrieve: 1875 * gets descendants of any documents found, otherwise gets just the children. 1876 * @return the given classifierNode which will have the child (or descendant) documents 1877 * appended to it. 1878 */ 1879 public Element getTitlesForLetter(char ch, String collectionName, 1880 Element classifierNode, String depthStructure) 1881 { 1882 Document doc = classifierNode.getOwnerDocument(); 1883 FedoraGS3RunException ex = null; //any RemoteException or UnsupportedEncodingException 1884 1885 1886 // Retrieve the document structure for each subClassifierID: 1887 // all the documents that begin with its letter. 1888 String letter = String.valueOf(ch); 1889 try { 1890 String[] docPIDs = this.browseTitlesByLetter(collectionName, letter); 1891 if(docPIDs.length == 0) { 1892 return classifierNode; // skip letters that don't have any kids 1893 } 1894 1895 for(int i = 0; i < docPIDs.length; i++) { 1896 // work out the document's fedora PID and section ID 1897 String sectionID = getSectionIDFromDocID(docPIDs[i]); 1898 String docPID = getDocPIDFromDocID(docPIDs[i]); 1899 1900 // get the required section, along with children or descendants 1901 Element section = getSectionStructureXML(docPID, sectionID, depthStructure, ""); 1902 1903 // <documentNode nodeID="docID" docType="hierarchy" nodeType="root"> 1904 Element docRootNode = createDocNodeFromSubsection(doc, section, docPID); 1905 1906 // fills in the subtree of the rootNode in our nodeStructure element 1907 createDocStructure(doc, section, docRootNode, docPID); //where section represents the root section 1908 classifierNode.appendChild(docRootNode); 1909 } 1910 } catch(Exception e) { 1911 ex = new FedoraGS3RunException(e); 1912 ex.setSpecifics("requested portion of TOC file or trouble with fielded search "); 1913 } 1914 1915 return classifierNode; 1916 } 1917 1918 1919 /** Creates all the subclassifiers (CL1.x) for CL1, the classifier to browse by the 1920 * starting letter of the alphabet. X is each letter of the alphabet for which there 1921 * are matching document titles. 1922 * @param collectionName - name of the collection through which we are browsing CL1. 1923 * @param classifierNode - the docNodes found will be appended to this node. 1924 * @param classifierID - the ID of parent classifier, i.e. CL1, which is used to create 1925 * the IDs for the subclassifiers (CL.x). 1926 * @param getDescendants - if true, get descendants of any documents found, otherwise 1927 * get just the children. 1928 * @return the given classifierNode, with the CL.x subclassifiers for the letters of 1929 * the alphabet that are represented in the document titles. 1930 */ 1931 public Element getTitlesByLetterStructure(String collectionName, Element classifierNode, 1932 String classifierID, boolean getDescendants) 1933 { 1934 Document doc = classifierNode.getOwnerDocument(); 1935 FedoraGS3RunException ex = null; // any RemoteException or UnsupportedEncodingException 1936 1937 // We're going to loop to the end of the alphabet 1938 int count = 1; 1939 for(char ch = 'A'; ch <= 'Z'; ch++, count++) { 1940 // Retrieve the document structure for each subClassifierID: 1941 // all the documents that begin with its letter. 1942 String letter = String.valueOf(ch); 1943 try { 1944 String[] docPIDs = this.browseTitlesByLetter(collectionName, letter); 1945 if(docPIDs.length == 0) { 1946 continue; // skip letters that don't have any kids 1947 } 1948 1949 // <classifierNode nodeID="CL1.x"> 1950 Element subClassifier = doc.createElement(GSXML.CLASS_NODE_ELEM); 1717 1951 Attr attribute = doc.createAttribute(GSXML.NODE_ID_ATT); 1718 attribute.setValue(classifierIDs[i]); 1719 requestedClassifierNode.setAttributeNode(attribute); 1720 classifierNodeList.appendChild(requestedClassifierNode); 1721 1722 // <nodeStructure> 1723 Element nodeStructure = doc.createElement(GSXML.NODE_STRUCTURE_ELEM); 1724 requestedClassifierNode.appendChild(nodeStructure); 1725 1726 // And one more time, the top level classifierNode: 1727 Element classifierNode = doc.createElement(GSXML.CLASS_NODE_ELEM); 1728 attribute = doc.createAttribute(GSXML.NODE_ID_ATT); 1729 attribute.setValue(classifierIDs[i]); 1730 classifierNode.setAttributeNode(attribute); 1731 nodeStructure.appendChild(classifierNode); 1732 1733 // Work out what we're browsing base on the classifierID's number 1734 // classifier CL1 = browse titles by letter; 1735 // classifier CL2 = browse by collection; 1736 // remove the CL prefix and decimal point to obtain the number from the id: 1737 String classifier = classifierIDs[i].replace("CL", ""); 1738 int decimal = classifier.indexOf('.'); // look for decimal point 1739 if(decimal != -1) { 1740 classifier = classifier.substring(0, decimal); 1741 } 1742 int classifierNum = Integer.parseInt(classifier); 1743 switch(classifierNum) { 1744 case 1: 1745 // we're going to loop to the end of the alphabet 1746 int num = 1; 1747 for(char ch = 'A'; ch <= 'Z'; ch++, num++) { 1748 // Retrieve the document structure for each subClassifierID: 1749 // all the documents that begin with its letter. 1750 String letter = String.valueOf(ch); 1751 try { 1752 String[] docPIDs = this.browseTitlesByLetter( 1753 collectionName, letter); 1754 if(docPIDs.length == 0) { 1755 continue; // skip letters that don't have any kids 1756 } 1757 1758 // <classifierNode nodeID="CL3.1"> 1759 Element subClassifier = doc.createElement( 1760 GSXML.CLASS_NODE_ELEM); 1761 attribute = doc.createAttribute(GSXML.NODE_ID_ATT); 1762 attribute.setValue(classifierIDs[i]+"."+num); 1763 subClassifier.setAttributeNode(attribute); 1764 classifierNode.appendChild(subClassifier); 1765 1766 // append the <docNodes> for the docPIDs found as children 1767 // of subclassifier 1768 getStructureElement(subClassifier, docPIDs, DESCENDANTS); 1769 //CHILDREN); // for testing 1770 } catch(Exception e) { 1771 ex = new FedoraGS3RunException(e); 1772 ex.setSpecifics("requested portion of TOC file or " 1773 + "trouble with fielded search "); 1774 } 1775 } 1776 // No titles in this collection that start with a letter at all 1777 if(!classifierNode.hasChildNodes()) { 1778 // <classifierNode nodeID="CL1.0"> which we will equate with A-Z 1779 Element subClassifier = doc.createElement( 1780 GSXML.CLASS_NODE_ELEM); 1781 attribute = doc.createAttribute(GSXML.NODE_ID_ATT); 1782 attribute.setValue(classifierIDs[i]+"."+0); // 1783 subClassifier.setAttributeNode(attribute); 1784 classifierNode.appendChild(subClassifier); 1785 } 1786 break; 1787 case 2: 1788 break; 1789 default: 1790 ex = new FedoraGS3RunException( // cause is regular exception 1791 new Exception("Unknown classifier ID: " + classifierIDs[i])); 1792 } 1793 } 1794 Element responseMsg = createResponseMessage(doc, classifierNodeList, ex, 1795 GSXML.REQUEST_TYPE_DESCRIBE, /*collectionName+*/"/ClassifierBrowse"); 1796 try{ 1797 return FedoraCommons.elementToFormattedString(responseMsg); 1798 }catch(TransformerException e) { 1799 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg 1800 + " " + e; 1801 } 1802 } 1952 attribute.setValue(classifierID+"."+count); 1953 subClassifier.setAttributeNode(attribute); 1954 classifierNode.appendChild(subClassifier); 1955 1956 if(getDescendants) { // get the documents 1957 1958 // append the <docNodes> for the docPIDs found as children 1959 // of subclassifier 1960 1961 for(int i = 0; i < docPIDs.length; i++) { 1962 // work out the document's fedora PID and section ID 1963 String sectionID = getSectionIDFromDocID(docPIDs[i]); 1964 String docPID = getDocPIDFromDocID(docPIDs[i]); 1965 1966 // get the required section, along with children or descendants 1967 Element section = getSectionStructureXML(docPID, sectionID, "descendants", ""); 1968 1969 // <documentNode nodeID="docID" docType="hierarchy" nodeType="root"> 1970 Element rootNode = createDocNodeFromSubsection(doc, section, docPID); 1971 1972 // fills in the subtree of the rootNode in our nodeStructure element 1973 createDocStructure(doc, section, rootNode, docPID); //where section represents the root section 1974 subClassifier.appendChild(rootNode); 1975 } 1976 } 1977 } catch(Exception e) { 1978 ex = new FedoraGS3RunException(e); 1979 ex.setSpecifics("requested portion of TOC file or " 1980 + "trouble with fielded search "); 1981 } 1982 } 1983 return classifierNode; 1984 } 1985 1803 1986 1804 1987 /** This method performs something equivalent to a greenstone3 1805 1988 * ClassifierBrowseMetadataRetrieve on the classifierNodeIDs 1806 * @param classNodeIDs array of classifierNode IDs offor which the metadata1989 * @param classNodeIDs array of classifierNode IDs for which the metadata 1807 1990 * needs to be returned. 1991 * @param metafields are the classifier metadata fields that are to be returned. 1992 * At present this method ignores them/pretends the requested metafields are 1993 * "all" and always returns the Title meta for the requested classifier nodes 1994 * (because that is all the metadata this Fedora classifier has at present). 1808 1995 * @return a GS3 ClassifierBrowseMetadataRetrieve response message which 1809 1996 * lists the metadata for all the classifierNodes passed as parameter.*/ 1810 public String browseMetadataRetrieve(String[] classNodeIDs )1997 public String browseMetadataRetrieve(String[] classNodeIDs, String[] metafields) 1811 1998 { 1812 1999 Document doc = this.builder.newDocument(); … … 1860 2047 "ClassifierBrowseMetadataRetrieve"); 1861 2048 try{ 1862 return FedoraCommons.elementTo FormattedString(responseMsg);2049 return FedoraCommons.elementToString(responseMsg); 1863 2050 }catch(TransformerException e) { 1864 2051 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg … … 1895 2082 // now create the displayItem children for classifier: 1896 2083 // <displayItem name="name">#letter</displayItem> 1897 // <displayItem name="description"> 1898 //Browse titles starting with #letter</displayItem> 2084 // <displayItem name="description">Browse titles starting with #letter</displayItem> 1899 2085 Element displayItem = createNameValuePairElement(doc, 1900 2086 GSXML.DISPLAY_TEXT_ELEM, GSXML.DISPLAY_TEXT_NAME, displayNameVal); … … 2013 2199 } 2014 2200 2015 /** 2201 /** @return a String representing Greenstone3 XML for a query process 2016 2202 * response returning the results for the query denoted by parameter 2017 2203 * nameValParamsMap. … … 2040 2226 String pids[] = {}; 2041 2227 // (2) for Textquery, we simply search ALL_FIELDS using FedoraGSearch 2042 if(service.e quals("TextQuery")) {2228 if(service.endsWith("TextQuery")) { 2043 2229 try { 2044 2230 // get the Query field: … … 2142 2328 GSXML.REQUEST_TYPE_PROCESS, service); 2143 2329 try{ 2144 return FedoraCommons.elementTo FormattedString(responseMsg);2330 return FedoraCommons.elementToString(responseMsg); 2145 2331 }catch(TransformerException e) { 2146 2332 return FedoraGS3RunException.xmlToStringConversionFailureResponseMsg … … 2186 2372 // along with EX of the top-level document: 2187 2373 System.out.println("\nGET META for greenstone:gs2mgdemo-HASH01d667303fe98545f03c14ae:"); 2188 System.out.println(con.getDocumentMetadata(new String[]{"greenstone:gs2mgdemo-HASH01d667303fe98545f03c14ae"} ));2374 System.out.println(con.getDocumentMetadata(new String[]{"greenstone:gs2mgdemo-HASH01d667303fe98545f03c14ae"}, new String[]{"all"})); 2189 2375 2190 2376 … … 2197 2383 System.out.println("\nGET META:"); 2198 2384 for(int i = 0; i < docIDs.length; i++) { 2199 System.out.println(con.getDocumentMetadata(docIDs[i] ));2385 System.out.println(con.getDocumentMetadata(docIDs[i], new String[]{"all"})); 2200 2386 } 2201 2387 … … 2211 2397 // their sections 2212 2398 for(int i = 0; i < getTitlesFor.length; i++) { 2213 System.out.println(con.getDocumentMetadata(getTitlesFor[i]));2399 System.out.println(con.getDocumentMetadata(getTitlesFor[i], new String[]{"all"})); 2214 2400 } 2215 2401 … … 2219 2405 System.out.println("\nGET STRUCTURE:"); 2220 2406 for(int i = 0; i < docIDs.length; i++) { 2221 System.out.println(con.getChildren(docIDs[i])); 2222 System.out.println(con.getDocumentStructure(docIDs[i])); 2407 System.out.println("Descendents and numChildren:\n" 2408 + con.getDocumentStructure(docIDs[i], new String[] {"descendants"}, new String[] {"numChildren"})); 2409 System.out.println("Parent and numSiblings:\n" 2410 + con.getDocumentStructure(docIDs[i], new String[] {"parent"}, new String[] {"numSiblings"})); 2223 2411 } 2224 2412 … … 2229 2417 "greenstone:demo-pinky" }; 2230 2418 System.out.println(con.getContent(errorCases)); 2231 System.out.println(con.getDocumentMetadata(errorCases ));2232 System.out.println(con.getDocumentStructure(errorCases));2419 System.out.println(con.getDocumentMetadata(errorCases, new String[]{"all"})); 2420 System.out.println(con.getDocumentStructure(errorCases, new String[] {"descendants"}, new String[] {"numChildren"})); 2233 2421 2234 2422 System.out.println("\nCLASSIFIER BROWSE"); 2235 2423 System.out.println(con.browse("gs2mgdemo", //"ClassifierBrowse", 2236 new String[]{"CL1"} ));2424 new String[]{"CL1"}, new String[] {""}, new String[] {""})); 2237 2425 2238 2426 System.out.println("\nCLASSIFIER BROWSE METADATA RETRIEVE"); … … 2243 2431 } 2244 2432 System.out.println(con.browseMetadataRetrieve(//"gs2mgdemo", 2245 classNodeIDs));2433 classNodeIDs, new String[]{"all"})); 2246 2434 2247 2435 System.out.println("Testing query services");
Note:
See TracChangeset
for help on using the changeset viewer.