Changeset 3978 for TI01-discovery
- Timestamp:
- 03/06/08 15:21:00 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TI01-discovery/branches/ws-Discovery2-upgrade/src/ndg/services/discovery/PresentAgent.java
r2841 r3978 1 1 package ndg.services.discovery; 2 2 3 import java.util.Hashtable;4 3 import java.util.Iterator; 4 import java.util.Properties; 5 5 import java.util.Vector; 6 import java.util.Properties; 7 8 import java.io.*; 9 10 import org.apache.xmlrpc.XmlRpc; 11 import org.apache.xmlrpc.XmlRpcClient; 12 13 import org.jdom.*; 14 import org.jdom.input.SAXBuilder; 15 import org.jdom.output.XMLOutputter; 16 import org.jdom.output.Format; 6 import java.util.logging.Logger; 17 7 18 8 /** … … 21 11 * @author Matt Pritchard <m.j.pritchard@rl.ac.uk> 22 12 */ 23 public class PresentAgent { 13 public class PresentAgent 14 { 15 private static Logger logger = Logger.getLogger(PresentAgent.class.getName()); 24 16 25 17 static Properties properties = new ServiceProperties().getProperties(); 26 18 27 19 // Input parameters 28 Vector documentNames; 29 String format = "original"; //default 30 31 // Output holder 32 Vector returnDocs; 33 Vector failedDocs = new Vector(); 20 private Vector<String> documentNames; 21 private String format = DiscoveryServiceSkeleton.ORIGINAL_FORMAT; //default 34 22 35 23 /** … … 40 28 /** 41 29 * Minimal constructor 42 * @param documentName String containing name (eg. /db/dif/badc/somedoc.xml)30 * @param documentName String containing name (eg. somedoc.xml) 43 31 */ 44 public PresentAgent(Vector documentNames)32 public PresentAgent(Vector<String> documentNames) 45 33 { 46 34 this.documentNames = documentNames; … … 51 39 * @param s String containing name (eg. /db/dif/badc/somedoc.xml) 52 40 */ 53 public void setDocumentNames(Vector documentNames)41 public void setDocumentNames(Vector<String> documentNames) 54 42 { 55 43 this.documentNames = documentNames; … … 59 47 * Sets the format in which to present the document 60 48 * @param s String containing format (eg. payload, ndgdoc, dc) 49 * @throws DiscoveryWSException if an invalid format is specified 61 50 */ 62 public void setFormat(String s) 51 public void setFormat(String s) throws DiscoveryWSException 63 52 { 64 this.format = s; 53 if (DiscoveryServiceSkeleton.isValidFormat(s)) 54 { 55 this.format = s; 56 } 57 else 58 { 59 String errorMessage = "Invalid format, " + s + 60 " - please use getListNames to get the valid list of formats"; 61 logger.warning(errorMessage); 62 throw new DiscoveryWSException(errorMessage); 63 } 65 64 } 66 65 … … 68 67 * Fetches document(s) in either "original" format or one of a number of supported<br> 69 68 * output formats (see presentFormatList).</p> 70 * In the case of each supported output format, a check is made as to whether the document<br>71 * exists in that format within /db/discovery/original and if not, one is generated on the fly.72 69 * @return PresentSummary object containing status, statusMessage and if appropriate, XML document as a String 70 * @throws DiscoveryDBException 73 71 */ 74 public PresentSummary doPresent() 72 public PresentSummary doPresent() throws DiscoveryDBException 75 73 { 74 PresentSummary result = null; 76 75 77 PresentSummary result = new PresentSummary(); 78 79 //byte[] returnDoc = null; 80 String returnDoc = null; 81 XmlRpc.setEncoding("UTF-8"); 82 83 try 84 { 85 86 // Set xmlDbURI as class variable so can reuse it in error messages 87 String uri = properties.getProperty("xmlrpc.uri"); 88 89 // Create xmlrpc client & set username, password 90 XmlRpcClient xmlrpc = new XmlRpcClient( uri ); 91 xmlrpc.setBasicAuthentication(properties.getProperty("xmlrpc.username"),properties.getProperty("xmlrpc.password")); 92 System.out.println("Initialising XMLRPC connection to " + uri); 93 94 Hashtable options = new Hashtable(); 95 options.put("indent", "yes"); 96 options.put("encoding", "UTF-8"); 97 //options.put("process-xsl-pi", "no"); 98 99 //0. For each document requested, do an XMLRPC call to fetch it 100 Iterator it = this.documentNames.iterator(); 101 returnDocs = new Vector(); 102 103 while ( it.hasNext() ) 104 { 105 String thisdoc = (String)it.next(); 106 107 if ( this.format.equals("original") ) 108 { 109 110 //1. If it's original format request, find the one document in /db/discovery/original that matches this name 111 Vector queryParams = new Vector(); 112 113 String xqueryStr = "let $doc := collection('/db/discovery/original')//root()[util:document-name(.) = '"+thisdoc+"' ] for $i in $doc return <document><collection>{util:collection-name($i)}</collection><content>{$i}</content></document>"; 114 115 queryParams.addElement( xqueryStr.getBytes("UTF-8") ); 116 queryParams.addElement( 1 ); 117 queryParams.addElement( 1 ); 118 119 Hashtable docSearchOptions = new Hashtable(); 120 docSearchOptions.put("indent", "yes"); 121 docSearchOptions.put("encoding", "UTF-8"); 122 docSearchOptions.put("process-xsl-pi", "no"); 123 queryParams.addElement( docSearchOptions ); 124 125 try 126 { 127 byte[] resultByteArray = (byte[])xmlrpc.execute( "query", queryParams ); 128 ByteArrayInputStream resultStream = new ByteArrayInputStream( resultByteArray ); 129 130 SAXBuilder builder = new SAXBuilder(); 131 org.jdom.Document doc = builder.build( resultStream ); 132 org.jdom.Element root = doc.getRootElement(); 133 134 org.jdom.Element document = root.getChild("document"); 135 org.jdom.Element collection = document.getChild("collection"); 136 org.jdom.Element content = document.getChild("content"); 137 138 // Determine which subcollection of /db/discovery/original/FORMAT this doc belongs to and apply appropriate namespace for extraction of content 139 String[] collectionParts = collection.getTextTrim().split("/"); 140 String thisFormat = collectionParts[4]; 141 142 String namespaceURI = properties.getProperty("namespace." + thisFormat); 143 String rootElement = properties.getProperty("rootElement." + thisFormat); 144 String namespacePrefix = properties.getProperty("namespacePrefix." + thisFormat); 145 146 if ( content != null ) 147 { 148 org.jdom.Element elem = null; 149 if ( namespacePrefix.equals("") ) 150 { 151 elem = content.getChild(rootElement, Namespace.getNamespace(namespaceURI) ); 152 } 153 else 154 { 155 elem = content.getChild(rootElement, Namespace.getNamespace(namespacePrefix, namespaceURI) ); 156 } 157 158 // If this doesn't work, try & fetch it as if it belongs to no namespace 159 if ( elem == null ) 160 { 161 elem = content.getChild(rootElement, Namespace.getNamespace("")); 162 } 163 164 // Use XMLOutputter 165 XMLOutputter out = new XMLOutputter (); 166 out.setFormat( Format.getCompactFormat() ); // UTF-8 & trimming of whitespace 167 returnDoc = out.outputString( elem ); 168 169 if (returnDoc != null) 170 { 171 returnDocs.add( returnDoc ); 172 } 173 } 174 175 } 176 catch ( java.lang.NullPointerException e) 177 { 178 // Catch failure for this individual document 179 returnDocs.add( "" ); 180 failedDocs.add(thisdoc); 181 } 182 183 } 184 else if ( this.format.equals("DC") ) 185 { 186 // Implements revision @2575 of TI07-MOLES/trunk/DublinCore/XQuery/NDG-DublinCore.xquery 187 Vector queryParams = new Vector(); 188 String xqueryStr = "import module namespace voclib='http://ndg.nerc.ac.uk/xquery/lib/vocab' at 'xmldb:exist:///db/xqueryLib/Vocabs/vocab_xquery_lib.xquery'; import module namespace utillib='http://ndg.nerc.ac.uk/xquery/lib/utilities' at 'xmldb:exist:///db/xqueryLib/Utilities/utility_xquery_lib.xquery'; declare default element namespace 'http://ndg.nerc.ac.uk/moles'; declare namespace xsi='http://www.w3.org/2001/XMLSchema-instance'; declare namespace dc='http://purl.org/dc/elements/1.1/'; declare namespace oai_dc='http://www.openarchives.org/OAI/2.0/oai_dc/'; declare namespace dummy='http://ndg.nerc.ac.uk/dummy'; declare variable $targetCollection as xs:string {'/db/discovery/moles'}; declare variable $repositoryIdentifier as xs:string {'RepositoryID'}; declare variable $localIdentifier as xs:string {'LocalID'}; declare function local:docExists($coll as xs:string, $doc as xs:string) as item()* { let $testset := collection($coll)//root() let $matches := for $i in $testset where util:document-name($i) = $doc return document-uri($i) return $matches }; let $i := local:docExists('/db/discovery/original/"+this.format+"', '"+thisdoc+"') return if ( fn:empty($i) ) then ( for $DE in collection($targetCollection)/dgMetadata/dgMetadataRecord[ exists('dgDataEntity') and dgMetadataID/schemeIdentifier='NDG-B0' ] where util:document-name($DE)='"+thisdoc+"' return element dummy:container { element oai_dc:dc { attribute xsi:schemaLocation {'http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd'}, element dc:title {string($DE/name)}, element dc:type {'Dataset'}, element dc:identifier {concat($DE/dgMetadataID/repositoryIdentifier, $utillib:moles_id_separator, 'DC', $utillib:moles_id_separator, $DE/dgMetadataID/localIdentifier)}, for $identifiers in $DE/(dgMetadataDescription/descriptionSection/descriptionOnlineReference | abstract/abstractOnlineReference)[ exists(dgReferenceClass/dgValidTermID/ParentListID) and voclib:spot-vocab($voclib:ndg_online_reference_classes_vocab, dgReferenceClass/dgValidTermID/ParentListID) and dgReferenceClass/dgValidTerm='DataPage'] return element dc:identifier {data($identifiers/dgSimpleLink/URI)}, element dc:description {string($DE/dgMetadataDescription/abstract/abstractText)}, element dc:date { if (exists($DE/(dgMetadataProvenance | DataProvenance)/RecordUpdate/UpdateDate)) then for $updatedate in ($DE/(dgMetadataProvenance | DataProvenance)/RecordUpdate/UpdateDate) order by xs:date($updatedate) return data($updatedate[1]) else string($DE/(dgMetadataProvenance | DataProvenance)/RecordCreation/CreatedDate) }, for $StructuredKeyword in distinct-values($DE/dgStructuredKeyword[ voclib:spot-vocab($voclib:cf_standard_names, dgValidTermID/ParentListID) or voclib:spot-vocab($voclib:gcmd_science_valids, dgValidTermID/ParentListID) or voclib:spot-vocab($voclib:gcmd_project_valids, dgValidTermID/ParentListID) or voclib:spot-vocab($voclib:iso_topic_list, dgValidTermID/ParentListID) or voclib:spot-vocab($voclib:bodc_parameter_usage_vocab, dgValidTermID/ParentListID) or voclib:spot-vocab($voclib:bodc_parameter_discovery_vocab, dgValidTermID/ParentListID) ]/dgValidTerm) order by $StructuredKeyword return element dc:subject {string($StructuredKeyword)}, for $StructuredKeyword1 in distinct-values($DE/dgDataEntity/dgDataSummary/dgParameterSummary/dgStdParameterMeasured[ voclib:spot-vocab($voclib:gcmd_science_valids, dgValidTermID/ParentListID) or voclib:spot-vocab($voclib:gcmd_project_valids, dgValidTermID/ParentListID) or voclib:spot-vocab($voclib:bodc_parameter_usage_vocab, dgValidTermID/ParentListID) or voclib:spot-vocab($voclib:bodc_parameter_discovery_vocab, dgValidTermID/ParentListID) ]/dgValidTerm) order by $StructuredKeyword1 return element dc:subject {string($StructuredKeyword1)}, for $DataCreatorRole in $DE/dgDataEntity/dgDataRoles/dgDataCreator/dgRoleHolder order by $DataCreatorRole/startDate empty least return for $DataCreatorRoleHolder in collection($targetCollection)/dgMetadata/(dgOrganisation | dgPerson) [(dgMetadataID/schemeIdentifier='NDG-B0' and dgMetadataID/repositoryIdentifier=$DataCreatorRole/(dgOrganisationID | dgPersonID)/repositoryIdentifier and dgMetadataID/localIdentifier=$DataCreatorRole/(dgOrganisationID | dgPersonID)/localIdentifier)] return element dc:creator { if (string(local-name($DataCreatorRoleHolder))='dgOrganisation') then (string($DataCreatorRoleHolder/name)) else if (string(local-name($DataCreatorRoleHolder))='dgPerson') then (string(concat(string($DataCreatorRoleHolder/name/initials), ' ', string($DataCreatorRoleHolder/name/familyName)))) else ('empty content') }, for $DataCuratorRole in $DE/dgDataEntity/dgDataRoles/dgDataCurator/dgRoleHolder[not(exists(endDate)) or endDate=''] order by $DataCuratorRole/startDate empty least return for $DataCuratorRoleHolder in collection($targetCollection)/dgMetadata/(dgOrganisation | dgPerson) [(dgMetadataID/schemeIdentifier='NDG-B0' and dgMetadataID/repositoryIdentifier=$DataCuratorRole/(dgOrganisationID | dgPersonID)/repositoryIdentifier and dgMetadataID/localIdentifier=$DataCuratorRole/(dgOrganisationID | dgPersonID)/localIdentifier)] return element dc:publisher { if (string(local-name($DataCuratorRoleHolder))='dgOrganisation') then (string($DataCuratorRoleHolder/name)) else if (string(local-name($DataCuratorRoleHolder))='dgPerson') then (string(concat(string($DataCuratorRoleHolder/name/initials), ' ', string($DataCuratorRoleHolder/name/familyName)))) else ('empty content') } } (: </oai_dc:dc> :) } (: dummy:container :) ) else ( element dummy:container { doc(fn:item-at($i, 1)) } )"; 189 190 queryParams.addElement( xqueryStr.getBytes("UTF-8") ); 191 queryParams.addElement( 1 ); 192 queryParams.addElement( 1 ); 193 194 Hashtable docSearchOptions = new Hashtable(); 195 docSearchOptions.put("indent", "yes"); 196 docSearchOptions.put("encoding", "UTF-8"); 197 docSearchOptions.put("process-xsl-pi", "no"); 198 queryParams.addElement( docSearchOptions ); 199 200 try 201 { 202 byte[] resultByteArray = (byte[])xmlrpc.execute( "query", queryParams ); 203 //System.out.println( new String(resultByteArray) ); 204 ByteArrayInputStream resultStream = new ByteArrayInputStream( resultByteArray ); 205 206 SAXBuilder builder = new SAXBuilder(); 207 org.jdom.Document doc = builder.build( resultStream ); 208 org.jdom.Element root = doc.getRootElement(); 209 org.jdom.Element container = root.getChild("container", Namespace.getNamespace("dummy","http://ndg.nerc.ac.uk/dummy")); 210 org.jdom.Element elem = container.getChild(properties.getProperty("rootElement.DC"), Namespace.getNamespace(properties.getProperty("namespacePrefix.DC"), "http://www.openarchives.org/OAI/2.0/oai_dc/") ); 211 // If this doesn't work, try & fetch it as if it belongs to no namespace 212 if ( elem == null ) 213 { 214 elem = container.getChild(properties.getProperty("rootElement.DC"),Namespace.getNamespace(properties.getProperty("namespacePrefix.DC"),"")); 215 } 216 217 // Use XMLOutputter 218 XMLOutputter out = new XMLOutputter (); 219 out.setFormat( Format.getCompactFormat() ); // UTF-8 & trimming of whitespace 220 returnDoc = out.outputString( elem ); 221 222 if (returnDoc != null) 223 { 224 returnDocs.add( returnDoc ); 225 } 226 227 } 228 catch ( java.lang.NullPointerException e) 229 { 230 // Catch failure for this individual document 231 returnDocs.add( "" ); 232 failedDocs.add(thisdoc); 233 } 234 235 } 236 else if ( this.format.equals("DIF") ) 237 { 238 239 Vector queryParams = new Vector(); 240 // Implements revision @2575 of TI07-MOLES/trunk/DIF/XQuery/NDG-DIF.xquery 241 String xqueryStr = "import module namespace voclib='http://ndg.nerc.ac.uk/xquery/lib/vocab' at 'xmldb:exist:///db/xqueryLib/Vocabs/vocab_xquery_lib.xquery'; import module namespace utillib='http://ndg.nerc.ac.uk/xquery/lib/utilities' at 'xmldb:exist:///db/xqueryLib/Utilities/utility_xquery_lib.xquery'; declare default element namespace 'http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/'; declare namespace xsi='http://www.w3.org/2001/XMLSchema-instance'; declare namespace moles='http://ndg.nerc.ac.uk/moles'; declare namespace dummy='http://ndg.nerc.ac.uk/dummy'; declare variable $targetCollection as xs:string {'/db/discovery/moles'}; declare variable $repositoryIdentifier as xs:string {'RepositoryID'}; declare variable $localIdentifier as xs:string {'LocalID'}; declare function local:docExists($coll as xs:string, $doc as xs:string) as item()* { let $testset := collection($coll)//root() let $matches := for $i in $testset where util:document-name($i) = $doc return document-uri($i) return $matches }; let $i := local:docExists('/db/discovery/original/"+this.format+"', '"+thisdoc+"') return if ( fn:empty($i) ) then ( for $DE in collection($targetCollection)/moles:dgMetadata/moles:dgMetadataRecord[ exists('moles:dgDataEntity') and moles:dgMetadataID/moles:schemeIdentifier='NDG-B0' ] where util:document-name($DE)='"+thisdoc+"' return element dummy:container { element DIF { attribute xsi:schemaLocation {'http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/dif_v9.4.xsd'}, element Entry_ID {concat($DE/moles:dgMetadataID/moles:repositoryIdentifier, $utillib:moles_id_separator, 'DIF', $utillib:moles_id_separator, $DE/moles:dgMetadataID/moles:localIdentifier)}, element Entry_Title {string($DE/moles:name)}, element Data_Set_Citation { for $DataCreatorRole in $DE/moles:dgDataEntity/moles:dgDataRoles/moles:dgDataCreator/moles:dgRoleHolder[not(exists(moles:endDate)) or moles:endDate=''][1] return for $DataCreatorRoleHolder in collection($targetCollection)/moles:dgMetadata/(dgOrganisation | dgPerson)[( moles:dgMetadataID/moles:localIdentifier=$DataCreatorRole/(moles:dgOrganisationID | moles:dgPersonID)/moles:repositoryIdentifier and moles:dgMetadataID/moles:repositoryIdentifier=$DataCreatorRole/(moles:dgOrganisationID | moles:dgPersonID)/moles:localIdentifier)] return element Dataset_Creator { if (exists($DataCreatorRoleHolder/moles:name/moles:initials)) then string(concat(string($DataCreatorRoleHolder/moles:name/moles:initials), ' ', string($DataCreatorRoleHolder/moles:name/moles:familyName))) else string($DataCreatorRoleHolder/moles:abbreviation) }, element Dataset_Title {string($DE/moles:name)} }, for $StructuredKeyword in ($DE/(moles:dgStructuredKeyword | moles:dgDataEntity/moles:dgDataSummary/moles:dgParameterSummary/moles:dgStdParameterMeasured)[(voclib:spot-vocab($voclib:gcmd_science_valids, moles:dgValidTermID/moles:ParentListID) or voclib:spot-vocab($voclib:gcmd_science_valids_correct, moles:dgValidTermID/moles:ParentListID) or voclib:spot-vocab($voclib:gcmd_science_valids_categories, moles:dgValidTermID/moles:ParentListID))] ) return if (exists($StructuredKeyword/*/moles:dgValidTerm)) then element Parameters { element Category {string($StructuredKeyword/*/moles:dgValidTerm)}, if (exists($StructuredKeyword/*/moles:dgValidSubterm) and $StructuredKeyword/*/moles:dgValidSubterm != '' and $StructuredKeyword/*/moles:dgValidSubterm != ' ') then for $Subterm in $StructuredKeyword//moles:dgValidSubterm[exists(moles:dgValidTerm)] where exists($Subterm/moles:dgValidSubterm) order by $Subterm/moles:ListLevel return if ($Subterm/moles:ListLevel=1) then element Topic {string($Subterm/moles:dgValidSubterm/moles:dgValidTerm)} else if ($Subterm/moles:ListLevel=2) then element Term {string($Subterm/moles:dgValidSubterm/moles:dgValidTerm)} else if ($Subterm/moles:ListLevel=3) then element Variable {string($Subterm/moles:dgValidSubterm/moles:dgValidTerm)} else if ($Subterm/moles:ListLevel=4) then element Detailed_Variable {string($Subterm/moles:dgValidSubterm/moles:dgValidTerm)} else element GCMD_Science_Valid {data($Subterm/moles:dgValidSubterm/moles:dgValidTerm)} else() } else(), for $StructuredKeyword in ($DE/(moles:dgStructuredKeyword | moles:dgDataEntity/moles:dgDataSummary/moles:dgParameterSummary/moles:dgStdParameterMeasured)[voclib:spot-vocab($voclib:gcmd_science_valids, moles:dgValidTermID/moles:ParentListID) or voclib:spot-vocab($voclib:gcmd_science_valids_correct, moles:dgValidTermID/moles:ParentListID) or voclib:spot-vocab($voclib:gcmd_science_valids_deprecated, moles:dgValidTermID/moles:ParentListID) and (not(exists(moles:ListLevel)) or moles:ListLevel=0)]) return element Parameters {data($StructuredKeyword/moles:dgValidTerm)}, for $ISOTopicCategory in ($DE/moles:dgStructuredKeyword[voclib:spot-vocab($voclib:iso_topic_list, moles:dgValidTermID/moles:ParentListID)]) return element ISO_Topic_Category {string($ISOTopicCategory/moles:dgValidTerm)}, for $Keyword in distinct-values($DE/moles:dgStructuredKeyword[ not (voclib:spot-vocab($voclib:iso_topic_list, moles:dgValidTermID/moles:ParentListID) or voclib:spot-vocab($voclib:gcmd_science_valids, moles:dgValidTermID/moles:ParentListID) or voclib:spot-vocab($voclib:gcmd_science_valids_correct, moles:dgValidTermID/moles:ParentListID) or voclib:spot-vocab($voclib:iso_topic_list, moles:dgValidTermID/moles:ParentListID) )]/moles:dgValidTerm) return element Keyword {string($Keyword)}, for $DepDPTRepository in distinct-values($DE/moles:dgDataEntity/moles:RelatedDeployment/moles:DataProductionToolID/moles:repositoryIdentifier) for $DepDPTLocal in distinct-values($DE/moles:dgDataEntity/moles:RelatedDeployment/moles:DataProductionToolID[moles:repositoryIdentifier=$DepDPTRepository]/moles:localIdentifier) let $DepDPTRecord := collection($targetCollection)/moles:dgMetadata/moles:dgMetadataRecord[moles:dgMetadataID[moles:schemeIdentifier='NDG-B0' and moles:repositoryIdentifier=$DepDPTRepository and moles:localIdentifier=$DepDPTLocal]] return element Sensor_Name { element Short_Name {data($DepDPTRecord/moles:abbreviation)}, element Long_Name {data($DepDPTRecord/moles:name)} }, for $DepObsStnRepository in distinct-values($DE/moles:dgDataEntity/moles:RelatedDeployment/moles:ObservationStationID/moles:repositoryIdentifier) for $DepObsStnLocal in distinct-values(($DE/moles:dgDataEntity/moles:RelatedDeployment/moles:ObservationStationID[moles:repositoryIdentifier=$DepObsStnRepository]/moles:localIdentifier)) let $DepObsStnRecord := collection($targetCollection)/moles:dgMetadata/moles:dgMetadataRecord[moles:dgMetadataID[moles:repositoryIdentifier=$DepObsStnRepository and moles:localIdentifier=$DepObsStnLocal]] return element Source_Name { element Short_Name {data($DepObsStnRecord/moles:abbreviation)}, element Long_Name {data($DepObsStnRecord/moles:name)} }, for $TemporalRange in $DE/moles:dgDataEntity/moles:dgDataSummary/moles:dgDataCoverage/(moles:dgTemporalCoverage | moles:dgSpatioTemporalCoverage/moles:dgSpatioTemporalRange/moles:dgTemporalCoverage)/moles:DateRange return element Temporal_Coverage { element Start_Date {data($TemporalRange/moles:DateRangeStart)}, element End_Date {data($TemporalRange/moles:DateRangeEnd)} }, for $TemporalTerm in $DE/moles:dgDataEntity/moles:dgDataSummary/moles:dgDataCoverage/(moles:dgTemporalCoverage | moles:dgSpatioTemporalCoverage/moles:dgSpatioTemporalRange/moles:dgTemporalCoverage)/moles:dgChronostratigraphicTerm[voclib:spot-vocab($voclib:gcmd_chronostratigraphic_valids, moles:dgValidTermID/moles:ParentListID)]/moles:dgValidTerm return element Paleo_Temporal_Coverage {element Chronostratigraphic_Unit {data($TemporalTerm)}}, for $Data_Set_Progress in ($DE/moles:dgDataEntity/moles:dgDataSummary/moles:dgDataStatus/moles:dgDatasetClosure) return element Data_Set_Progress {data($Data_Set_Progress)}, for $BoundingBox in $DE/moles:dgDataEntity/moles:dgDataSummary/moles:dgDataCoverage/(moles:dgSpatialCoverage | moles:dgSpatioTemporalCoverage/moles:dgSpatioTemporalRange/moles:dgSpatialCoverage)/moles:BoundingBox return element Spatial_Coverage { element Southernmost_Latitude {data($BoundingBox/moles:LimitSouth)}, element Northernmost_Latitude {data($BoundingBox/moles:LimitNorth)}, element Westernmost_Longitude {data($BoundingBox/moles:LimitWest)}, element Easternmost_Longitude {data($BoundingBox/moles:LimitEast)} }, for $Location in ($DE/moles:dgDataEntity/moles:dgDataSummary/moles:dgDataCoverage/(moles:dgSpatialCoverage | moles:dgSpatioTemporalCoverage/moles:dgSpatioTemporalRange/moles:dgSpatialCoverage)/moles:dgArea[voclib:spot-vocab($voclib:gcmd_location_valids, moles:dgValidTermID/moles:ParentListID)]) return element Location {data($Location/moles:dgValidTerm)}, for $DepActRepository in distinct-values($DE/moles:dgDataEntity/moles:RelatedDeployment/moles:ActivityID/moles:repositoryIdentifer) for $DepActLocal in distinct-values($DE/moles:dgDataEntity/moles:RelatedDeployment/moles:ActivityID[moles:repositoryIdentifer=$DepActRepository]/moles:localIdentifer) let $DepActRecord := collection($targetCollection)/moles:dgMetadata/moles:dgMetadataRecord[moles:dgMetadataID[moles:repositoryIdentifier=$DepActRepository and moles:localIdentifier=$DepActLocal]] return element Project { element Short_Name {data($DepActRecord/abbreviation)}, element Long_Name {data($DepActRecord/name)} }, if (exists($DE/moles:dgDataEntity/moles:dgDataGranule/moles:accessControlPolicy)) then for $DG in $DE/moles:dgDataEntity/moles:dgDataGranule return element Access_Constraints { if (exists($DG/moles:dgGranuleSummary/moles:dgGranuleName)) then concat('For data granule ', $DG/moles:dgGranuleSummary/moles:dgGranuleName, ': ') else (), if (exists($DG/moles:accessControlPolicy/moles:accessControlPolicyURL)) then concat('See access control policy at ', escape-uri($DG/moles:accessControlPolicy/moles:accessControlPolicyURL, true())) else if (exists($DG/moles:accessControlPolicy/moles:accessControlPolicyText)) then data($DG/moles:accessControlPolicy/moles:accessControlPolicyText) else for $securityCondition in $DG/moles:accessControlPolicy/moles:dgSecurityCondition return if (exists($securityCondition/moles:conditionExplanationText)) then concat('Effect: ', data($securityCondition/moles:effect), ' - ', data($securityCondition/moles:conditionExplanationText)) else concat('Effect: ', data($securityCondition/moles:effect), 'needs ', data($securityCondition/moles:attauthRole), ' from ', data($securityCondition/moles:dgAttributeAuthority)) } else (), if (exists($DE/moles:dgDataEntity/moles:dgDataRoles/moles:dgDataCreator/moles:dgRoleHolder)) then for $DataCreatorRole in $DE/moles:dgDataEntity/moles:dgDataRoles/moles:dgDataCreator/moles:dgRoleHolder order by $DataCreatorRole/moles:startDate empty least return for $DataCreatorRoleHolder in collection($targetCollection)/moles:dgMetadata/(moles:dgOrganisation | moles:dgPerson) [(moles:dgMetadataID/moles:schemeIdentifier='NDG-B0' and moles:dgMetadataID/moles:repositoryIdentifier=$DataCreatorRole/*/moles:repositoryIdentifier and moles:dgMetadataID/moles:localIdentifier=$DataCreatorRole/*/moles:localIdentifier)] return element Originating_Center { if (string(local-name($DataCreatorRoleHolder))='dgOrganisation') then (string($DataCreatorRoleHolder/moles:name)) else if (string(local-name($DataCreatorRoleHolder))='dgPerson') then (string(concat(string($DataCreatorRoleHolder/moles:name/moles:initials), ' ', string($DataCreatorRoleHolder/moles:name/moles:familyName)))) else ('empty content') } else (), for $DataCuratorRole in $DE/moles:dgDataEntity/moles:dgDataRoles/moles:dgDataCurator/moles:dgRoleHolder [not(exists(moles:endDate)) or moles:endDate=''] return for $DataCuratorRoleHolder in collection($targetCollection)/moles:dgMetadata/(moles:dgOrganisation | moles:dgPerson) [(moles:dgMetadataID/moles:schemeIdentifier='NDG-B0' and moles:dgMetadataID/moles:repositoryIdentifier=$DataCuratorRole/*/moles:repositoryIdentifier and moles:dgMetadataID/moles:localIdentifier=$DataCuratorRole/*/moles:localIdentifier)] return element Data_Center { element Data_Center_Name { element Short_Name { if (exists($DataCuratorRoleHolder/moles:name/moles:initials)) then string(concat(string($DataCuratorRoleHolder/moles:name/moles:initials), ' ', string($DataCuratorRoleHolder/moles:name/moles:familyName))) else string($DataCuratorRoleHolder/moles:abbreviation) }, element Long_Name { if (exists($DataCuratorRoleHolder/moles:name/moles:initials)) then string(concat(string($DataCuratorRoleHolder/moles:name/moles:initials), ' ', string($DataCuratorRoleHolder/moles:name/moles:familyName))) else string($DataCuratorRoleHolder/moles:name) } }, if (exists($DataCuratorRoleHolder/moles:contactDetails/moles:URI)) then element Data_Center_URL {data($DataCuratorRoleHolder/moles:contactDetails/moles:URI)} else (), for $DGID in $DE/moles:dgDataEntity/moles:dgDataGranule/moles:dataModelID return element Data_Set_ID {concat($DGID/moles:repositoryIdentifier, $utillib:moles_id_separator, $DGID/moles:schemeIdentifier, $utillib:moles_id_separator, $DGID/moles:localIdentifier)}, element Personnel { element Role {'Data Center Contact'}, if (exists($DataCuratorRoleHolder/name/knownAs)) then element First_Name {string($DataCuratorRoleHolder/moles:name/moles:knownAs)} else if (exists($DataCuratorRoleHolder/moles:name/moles:initials)) then element First_Name {string($DataCuratorRoleHolder/moles:name/moles:initials)} else (), element Last_Name { if (exists($DataCuratorRoleHolder/moles:name/moles:familyName)) then string($DataCuratorRoleHolder/moles:name/moles:familyName) else string($DataCuratorRoleHolder/moles:name) }, if (exists($DataCuratorRole/moles:contactDetails/moles:eMail)) then element Email {string($DataCuratorRole/moles:contactDetails/moles:eMail)} else if (exists($DataCuratorRoleHolder/contactDetails/eMail)) then (element Email {string($DataCuratorRoleHolder/moles:contactDetails/moles:eMail)}) else (), if (exists($DataCuratorRole/moles:contactDetails/moles:telephone)) then element Phone {string($DataCuratorRole/moles:contactDetails/moles:telephone)} else if (exists($DataCuratorRoleHolder/moles:contactDetails/moles:telephone)) then element Phone {string($DataCuratorRoleHolder/moles:contactDetails/moles:telephone)} else (), if (exists($DataCuratorRole/moles:contactDetails/moles:fax)) then element Fax {string($DataCuratorRole/moles:contactDetails/moles:fax)} else if (exists($DataCuratorRoleHolder/moles:contactDetails/moles:fax)) then element Fax {string($DataCuratorRoleHolder/moles:contactDetails/moles:fax)} else (), if (exists($DataCuratorRole/moles:contactDetails/moles:address)) then element Contact_Address { for $addressline in $DataCuratorRole/moles:contactDetails/moles:address/moles:addressline return element Address {data($addressline)}, if (exists($DataCuratorRole/moles:contactDetails/moles:address/moles:city)) then element City {string($DataCuratorRole/moles:contactDetails/moles:address/moles:city)} else (), if (exists($DataCuratorRole/moles:contactDetails/moles:address/moles:postcode)) then element Postal_Code {string($DataCuratorRole/moles:contactDetails/moles:address/moles:postcode)} else (), if (exists($DataCuratorRole/moles:contactDetails/moles:address/moles:country)) then element Country {string($DataCuratorRole/moles:contactDetails/moles:address/moles:country)} else () } else if (exists($DataCuratorRoleHolder/moles:contactDetails/moles:address)) then element Contact_Address { for $addressline in $DataCuratorRoleHolder/moles:contactDetails/moles:address/moles:addressline return element Address {data($addressline)}, if (exists($DataCuratorRoleHolder/moles:contactDetails/moles:address/moles:city)) then element City {string($DataCuratorRoleHolder/moles:contactDetails/moles:address/moles:city)} else (), if (exists($DataCuratorRoleHolder/moles:contactDetails/moles:address/moles:postcode)) then element Postal_Code {string($DataCuratorRoleHolder/moles:contactDetails/moles:address/moles:postcode)} else (), if (exists($DataCuratorRoleHolder/moles:contactDetails/moles:address/moles:country)) then element Country {string($DataCuratorRoleHolder/moles:contactDetails/moles:address/moles:country)} else () } else () } }, element Summary {string($DE/moles:dgMetadataDescription/moles:abstract/moles:abstractText)}, for $DG in $DE/moles:dgDataEntity/moles:dgDataGranule return if ($DG/moles:dataModelID/moles:schemeIdentifier='NDG-A0') then (element Related_URL { element URL_Content_Type {'NDG_A_SERVICE'}, if (exists($DG/instance/URI)) then element URL {escape-uri($DG/instance/URI, true())} else if ($DG/moles:dataModelID/moles:repositoryIdentifier='badc.nerc.ac.uk') then element URL {escape-uri('http://dmgdev1.esc.rl.ac.uk/cgi-bin/ndgDataAccess?datasetSource=dmgdev1.esc.rl.ac.uk&datasetID=', true())} else ($DG/moles:dataModelID/moles:repositoryIdentifier), element Description {'The NDG service delivering data via NDG A metadata.'} }, element Related_URL { element URL_Content_Type {'GET DATA > CSML'}, if (exists($DG/instance)) then element URL {escape-uri($DG/instance/URI, true())} else if ($DG/moles:dataModelID/moles:repositoryIdentifier='badc.nerc.ac.uk') then element URL {escape-uri('http://dmgdev1.esc.rl.ac.uk/cgi-bin/ndgDataAccess?datasetSource=dmgdev1.esc.rl.ac.uk&datasetID=', true())} else (), element Description {'The NDG service delivering data via NDG A metadata. Additional tag to be more in line with latest version of GCMD valids'} }) else if ($DG/moles:dataModelID/moles:schemeIdentifier='CDML-0') then (element Related_URL { element URL_Content_Type {'NDG_A_SERVICE'}, if (exists($DG/instance)) then element URL {escape-uri($DG/instance/URI, true())} else if ($DG/moles:dataModelID/moles:repositoryIdentifier='badc.nerc.ac.uk') then element URL {escape-uri('http://cdat.badc.nerc.ac.uk/cgi-bin/dxui.py?datasetURI_1=/', true())} else (), element Description {'The NDG service delivering data via Data extractor. Additional tag to be more in line with latest version of GCMD valids'} }, element Related_URL { element URL_Content_Type {'GET DATA > DX'}, if (exists($DG/instance)) then element URL {escape-uri($DG/instance/URI, true())} else if ($DG/moles:dataModelID/moles:repositoryIdentifier='badc.nerc.ac.uk') then element URL {escape-uri('http://cdat.badc.nerc.ac.uk/cgi-bin/dxui.py?datasetURI_1=/', true())} else (), element Description {'The NDG service delivering data via Data extractor. Additional tag to be more in line with latest version of GCMD valids'} }) else if ($DG/moles:dataModelID/moles:schemeIdentifier='URI') then element Related_URL { element URL {data($DG/moles:instance/moles:URI)}, if (exists($DG/moles:instance/moles:instanceComment)) then element Description {data($DG/moles:instance/moles:instanceComment)} else element Description {'URL to aid in delivering data. Note that this may point directly to the data or, more likely, point to the web site of the curator.'} } else (), for $RelURL_Desc in ($DE/moles:dgMetadataDescription/moles:descriptionSection/moles:descriptionOnlineReference) return if (exists($RelURL_Desc/moles:dgSimpleLink)) then element Related_URL { element URL {data($RelURL_Desc/moles:dgSimpleLink/URI)}, element Description {concat(data($RelURL_Desc/dgSimpleLink/moles:name), ' - ', data($RelURL_Desc/dgSimpleLink/moles:notes))} } else (), element Metadata_Name {'[CEOS IDN DIF]'}, element Metadata_Version {'9.4'}, if (exists($DE/moles:dgMetadataProvenance/moles:RecordCreation)) then element DIF_Creation_Date {data($DE/moles:dgMetadataProvenance/moles:RecordCreation/moles:CreatedDate)} else (), for $MDUpdt in $DE/moles:dgMetadataProvenance/moles:RecordUpdate return element DIF_Revision_History {concat(data($MDUpdt/moles:UpdateDate), ' - ', data($MDUpdt/moles:UpdateSummary), ' - ', data($MDUpdt/moles:UpdatedBy))}, if (exists($DE/moles:dgMetadataProvenance/moles:RecordReview)) then element Future_DIF_Review_Date {data($DE/moles:dgMetadataProvenance/moles:RecordReview/moles:ReviewDate)} else () } } ) else ( element dummy:container { doc(fn:item-at($i, 1)) } )"; 242 queryParams.addElement( xqueryStr.getBytes("UTF-8") ); 243 queryParams.addElement( 1 ); 244 queryParams.addElement( 1 ); 245 246 Hashtable docSearchOptions = new Hashtable(); 247 docSearchOptions.put("indent", "yes"); 248 docSearchOptions.put("encoding", "UTF-8"); 249 docSearchOptions.put("process-xsl-pi", "no"); 250 queryParams.addElement( docSearchOptions ); 251 252 try 253 { 254 255 byte[] resultByteArray = (byte[])xmlrpc.execute( "query", queryParams ); 256 ByteArrayInputStream resultStream = new ByteArrayInputStream( resultByteArray ); 257 258 259 SAXBuilder builder = new SAXBuilder(); 260 org.jdom.Document doc = builder.build( resultStream ); 261 org.jdom.Element root = doc.getRootElement(); 262 org.jdom.Element container = root.getChild("container", Namespace.getNamespace("dummy","http://ndg.nerc.ac.uk/dummy")); 263 org.jdom.Element elem = container.getChild(properties.getProperty("rootElement.DIF"), Namespace.getNamespace(properties.getProperty("namespace.DIF")) ); 264 // If this doesn't work, try & fetch it as if it belongs to no namespace 265 if ( elem == null ) 266 { 267 System.out.println("Had retrieve without namespace"); 268 elem = container.getChild(properties.getProperty("rootElement.DIF"),Namespace.getNamespace("")); 269 } 270 271 // Use XMLOutputter 272 XMLOutputter out = new XMLOutputter (); 273 out.setFormat( Format.getCompactFormat() ); // UTF-8 & trimming of whitespace 274 returnDoc = out.outputString( elem ); 275 276 if (returnDoc != null) 277 { 278 returnDocs.add( returnDoc ); 279 } 280 } 281 catch ( java.lang.NullPointerException e) 282 { 283 // Catch failure for this individual document 284 returnDocs.add( "" ); 285 failedDocs.add(thisdoc); 286 } 287 } 288 else if ( this.format.equals("MDIP") ) 289 { 290 //1. Check to see if a dc-format document exists for this name 291 Vector queryParams = new Vector(); 292 // Implements revision #2372 of TI07-MOLES/trunk/MDIP/XQueries/NDG-MDIP.xquery 293 String xqueryStr = "import module namespace voclib='http://ndg.nerc.ac.uk/xquery/lib/vocab' at 'xmldb:exist:///db/xqueryLib/Vocabs/vocab_xquery_lib.xquery'; import module namespace utillib='http://ndg.nerc.ac.uk/xquery/lib/utilities' at 'xmldb:exist:///db/xqueryLib/Utilities/utility_xquery_lib.xquery'; declare default element namespace 'http://www.oceannet.org/mdip/xml'; declare namespace moles='http://ndg.nerc.ac.uk/moles'; declare namespace gco='http://www.isotc211.org/2005/gco'; declare namespace xsi='http://www.w3.org/2001/XMLSchema-instance'; declare namespace dummy='http://ndg.nerc.ac.uk/dummy'; declare variable $targetCollection as xs:string {'/db/discovery/moles'}; declare variable $repositoryIdentifier as xs:string {'RepositoryID'}; declare variable $localIdentifier as xs:string {'LocalID'}; declare function local:docExists($coll as xs:string, $doc as xs:string) as item()* { let $testset := collection($coll)//root() let $matches := for $i in $testset where util:document-name($i) = $doc return document-uri($i) return $matches }; declare variable $ISO_639-2_ns as xs:string{$voclib:ISO_639-2_ns}; declare variable $ISO_3166_ns as xs:string{$voclib:ISO_3166_ns}; let $i := local:docExists('/db/discovery/original/"+this.format+"', '"+thisdoc+"') return if ( fn:empty($i) ) then ( for $DE in collection($targetCollection)/moles:dgMetadata/moles:dgMetadataRecord[ exists('moles:dgDataEntity') and moles:dgMetadataID/moles:schemeIdentifier='NDG-B0' ] where util:document-name($DE)='"+thisdoc+"' return element dummy:container { element Metadata { element Title {data($DE/moles:name)}, if (exists($DE/moles:dgDataEntity/moles:dgDataSummary/moles:dgDatasetLanguage)) then for $lang in $DE/moles:dgDataEntity/moles:dgDataSummary/moles:dgDatasetLanguage return element Language{ element LanguageName {data($lang/moles:dgValidTerm)}, element LanguageVocab {data($lang/moles:dgValidTermID/moles:ParentListID)}, element LanguageCode {data($lang/moles:dgValidTermID/moles:TermID)} } else (), element Abstract {string($DE/moles:dgMetadataDescription/moles:abstract/moles:abstractText)}, for $isoTopic in $DE/moles:dgStructuredKeyword[voclib:spot-vocab($voclib:iso_topic_list, moles:dgValidTermID/moles:ParentListID)] return element TopicCategory { element TopicCategoryName {data($isoTopic/moles:dgValidTerm)}, element TopicCategoryVocab {data($isoTopic/moles:dgValidTermID/moles:ParentListID)}, element TopicCategoryCode {data($isoTopic/moles:dgValidTermID/moles:TermID)} }, for $subject in ($DE/moles:dgDataEntity/moles:dgDataSummary/moles:dgParameterSummary/moles:dgStdParameterMeasured[ voclib:spot-vocab($voclib:gcmd_science_valids, moles:dgValidTermID/moles:ParentListID) or voclib:spot-vocab($voclib:gcmd_project_valids, moles:dgValidTermID/moles:ParentListID) or voclib:spot-vocab($voclib:gcmd_science_valids_categories, moles:dgValidTermID/moles:ParentListID) or voclib:spot-vocab($voclib:bodc_parameter_usage_vocab, moles:dgValidTermID/moles:ParentListID) or voclib:spot-vocab($voclib:bodc_parameter_discovery_vocab, moles:dgValidTermID/moles:ParentListID) ]) return (element Subject { element SubjectName {data($subject/moles:dgValidTerm)}, element SubjectVocab {data($subject/moles:dgValidTermID/moles:ParentListID)}, element SubjectCode {data($subject/moles:dgValidTermID/moles:TermID)} }, for $subterm in $subject//moles:dgValidSubterm return (element Subject { element SubjectName {data($subterm/moles:dgValidTerm)}, element SubjectVocab {data($subterm/moles:dgValidTermID/moles:ParentListID)}, element SubjectCode {data($subterm/moles:dgValidTermID/moles:TermID)} } ) ), if (exists($DE//moles:dgTemporalCoverage/(moles:DateSingle | moles:DateRange))) then element Date { element DatasetStartDate { let $dateStart:=min($DE//moles:dgTemporalCoverage/(moles:DateSingle | moles:DateRange/moles:DateRangeStart) cast as xs:date) return if (empty($dateStart)) then () else data($dateStart) }, element DatasetEndDate { let $dateEnd:=max($DE//moles:dgTemporalCoverage/(moles:DateSingle | moles:DateRange/moles:DateRangeEnd) cast as xs:date) return if (empty($dateEnd)) then () else data($dateEnd) } } else (), let $west := min($DE/moles:dgDataEntity/moles:dgDataSummary//moles:BoundingBox/moles:LimitWest cast as xs:decimal) return element WestCoOrdinate {data($west)}, let $east := max($DE/moles:dgDataEntity/moles:dgDataSummary//moles:BoundingBox/moles:LimitEast cast as xs:decimal) return element EastCoOrdinate {data($east)}, let $north := max($DE/moles:dgDataEntity/moles:dgDataSummary//moles:BoundingBox/moles:LimitNorth cast as xs:decimal) return element NorthCoOrdinate {data($north)}, let $south := min($DE/moles:dgDataEntity/moles:dgDataSummary//moles:BoundingBox/moles:LimitSouth cast as xs:decimal) return element SouthCoOrdinate {data($south)}, element DatasetIdentifier {concat($DE/moles:dgMetadataID/moles:repositoryIdentifier, $utillib:moles_id_separator, 'MDIP', $utillib:moles_id_separator, $DE/moles:dgMetadataID/moles:localIdentifier)}, for $target in $DE/moles:dgStructuredKeyword[voclib:spot-vocab($voclib:ndg_data_provider_vocab, moles:dgValidTermID/moles:ParentListID) ] return element Target { element TargetName {data($target/moles:dgValidTerm)}, element TargetVocab {data($target/moles:dgValidTermID/moles:ParentListID)}, element TargetCode {data($target/moles:dgValidTermID/moles:TermID)} } } } ) else ( element dummy:container { doc(fn:item-at($i, 1)) } ) "; 294 System.out.println( "xquery was:\n" + xqueryStr ); 295 queryParams.addElement( xqueryStr.getBytes("UTF-8") ); 296 queryParams.addElement( 1 ); 297 queryParams.addElement( 1 ); 298 299 Hashtable docSearchOptions = new Hashtable(); 300 docSearchOptions.put("indent", "yes"); 301 docSearchOptions.put("encoding", "UTF-8"); 302 docSearchOptions.put("process-xsl-pi", "no"); 303 queryParams.addElement( docSearchOptions ); 304 try 305 { 306 307 byte[] resultByteArray = (byte[])xmlrpc.execute( "query", queryParams ); 308 309 ByteArrayInputStream resultStream = new ByteArrayInputStream( resultByteArray ); 310 System.out.println( new String(resultByteArray) ); 311 // Use XMLOutputter 312 XMLOutputter out = new XMLOutputter (); 313 out.setFormat( Format.getCompactFormat() ); // UTF-8 & trimming of whitespace 314 315 SAXBuilder builder = new SAXBuilder(); 316 org.jdom.Document doc = builder.build( resultStream ); 317 org.jdom.Element root = doc.getRootElement(); 318 org.jdom.Element container = root.getChild("container", Namespace.getNamespace("dummy","http://ndg.nerc.ac.uk/dummy")); 319 org.jdom.Element elem = container.getChild(properties.getProperty("rootElement.MDIP"), Namespace.getNamespace(properties.getProperty("namespace.MDIP"))); 320 // If this doesn't work, try & fetch it as if it belongs to no namespace 321 if ( elem == null ) 322 { 323 elem = container.getChild(properties.getProperty("rootElement.MDIP"),Namespace.getNamespace("")); 324 } 325 326 327 returnDoc = out.outputString( elem ); 328 if (returnDoc != null) 329 { 330 returnDocs.add( returnDoc ); 331 } 332 } 333 catch ( java.lang.NullPointerException e) 334 { 335 // Catch failure for this individual document 336 returnDocs.add( "" ); 337 failedDocs.add(thisdoc); 338 } 339 } 340 341 else if ( this.format.equals("ISO19115") ) 342 { 343 //1. Check to see if a dc-format document exists for this name 344 Vector queryParams = new Vector(); 345 // Implements revision @2334 of TI07-MOLES/trunk/ISO19115-19139/XQuery/NDG-ISO19115-139.xquery 346 String xqueryStr = "import module namespace voclib='http://ndg.nerc.ac.uk/xquery/lib/vocab' at 'xmldb:exist:///db/xqueryLib/Vocabs/vocab_xquery_lib.xquery'; import module namespace utillib='http://ndg.nerc.ac.uk/xquery/lib/utilities' at 'xmldb:exist:///db/xqueryLib/Utilities/utility_xquery_lib.xquery'; declare default element namespace 'http://www.isotc211.org/2005/gmd'; declare namespace moles='http://ndg.nerc.ac.uk/moles'; declare namespace gco='http://www.isotc211.org/2005/gco'; declare namespace gmd='http://www.isotc211.org/2005/gmd'; declare namespace gml='http://www.opengis.net/gml'; declare namespace xlink='http://www.w3.org/1999/xlink'; declare namespace xsi='http://www.w3.org/2001/XMLSchema-instance'; declare namespace dummy='http://ndg.nerc.ac.uk/dummy'; declare variable $targetCollection as xs:string {'/db/discovery/moles'}; declare variable $repositoryIdentifier as xs:string {'RepositoryID'}; declare variable $localIdentifier as xs:string {'LocalID'}; declare function local:docExists($coll as xs:string, $doc as xs:string) as item()* { let $testset := collection($coll)//root() let $matches := for $i in $testset where util:document-name($i) = $doc return document-uri($i) return $matches }; declare variable $ISO_639-2_ns as xs:string{$voclib:ISO_639-2_ns}; declare variable $ISO_3166_ns as xs:string{$voclib:ISO_3166_ns}; let $i := local:docExists('/db/discovery/original/"+this.format+"', '"+thisdoc+"') return if ( fn:empty($i) ) then ( for $DE in collection($targetCollection)/moles:dgMetadata/moles:dgMetadataRecord[ exists('moles:dgDataEntity') and moles:dgMetadataID/moles:schemeIdentifier='NDG-B0' ] where util:document-name($DE)='"+thisdoc+"' return element dummy:container { element MD_Metadata { attribute xsi:schemaLocation {'http://www.isotc211.org/2005/gmd http://www.isotc211.org/2005/gmd/metadataEntity.xsd'}, element fileIdentifier {element gco:CharacterString {concat($DE/moles:dgMetadataID/moles:repositoryIdentifier, $utillib:moles_id_separator, 'ISO19115', $utillib:moles_id_separator, $DE/moles:dgMetadataID/moles:localIdentifier)}}, element language { element gmd:LanguageCode { attribute codeList {'http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#LanguageCode'}, attribute codeListValue {'eng'}, 'English'} } (: </language> :), element hierarchyLevel { element MD_ScopeCode { attribute codeList {'http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_ScopeCode'}, attribute codeListValue {'http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_ScopeCode_dataset'}, 'dataset'} } (: </hierarchyLevel> :), for $parent in $DE/moles:dgRelatedDataEntity[moles:RelationID/moles:dgValidTerm='is-part-of'] return element parentIdentifier {element gco:CharacterString {concat($DE/moles:dgMetadataID/moles:repositoryIdentifier, ':', $DE/moles:dgMetadataID/moles:localIdentifier, ':', $DE/moles:dgMetadataID/moles:localIdentifier)}}, for $DataCuratorRole in $DE/moles:dgDataEntity/moles:dgDataRoles/moles:dgDataCurator/moles:dgRoleHolder[not(exists(moles:endDate)) or moles:endDate=''] return for $DataCuratorRoleHolder in collection($targetCollection)/moles:dgMetadata/(moles:dgPerson | moles:dgOrganisation)[ moles:dgMetadataID/moles:schemeIdentifier='NDG-B0' and moles:dgMetadataID/moles:repositoryIdentifier=$DataCuratorRole/(moles:dgPersonID | moles:dgOrganisationID)/moles:repositoryIdentifier and moles:dgMetadataID/moles:localIdentifier=$DataCuratorRole/(moles:dgPersonID | moles:dgOrganisationID)/moles:localIdentifier] return element contact { element CI_ResponsibleParty { if (string(local-name($DataCuratorRoleHolder))='dgOrganisation') then element organisationName {element gco:CharacterString {string($DataCuratorRoleHolder/moles:name)}} else if (string(local-name($DataCuratorRoleHolder))='dgPerson') then element individualName {element gco:CharacterString {string(concat(string($DataCuratorRoleHolder/moles:name/moles:initials), ' ', string($DataCuratorRoleHolder/moles:name/moles:familyName)))}} else ('empty content') , element positionName { if (exists($DataCuratorRoleHolder/moles:localName)) then element gco:CharacterString {$DataCuratorRoleHolder/moles:localName} else if (exists($DataCuratorRole/moles:roleName)) then element gco:CharacterString {$DataCuratorRole/moles:roleName} else element gco:CharacterString {'Curator'} } (: </positionName>:), element contactInfo { element gmd:CI_Contact { if (exists($DataCuratorRole/moles:contactDetails/moles:telephone or $DataCuratorRole/moles:contactDetails/moles:fax or $DataCuratorRoleHolder/moles:contactDetails/moles:telephone or $DataCuratorRoleHolder/moles:contactDetails/moles:fax)) then element phone { element gmd:CI_Telephone { if (exists($DataCuratorRole/moles:contactDetails/moles:telephone)) then element voice { element gco:CharacterString {data($DataCuratorRole/moles:contactDetails/moles:telephone)} } (:</voice>:) else if (exists($DataCuratorRoleHolder/moles:contactDetails/moles:telephone)) then element voice { element gco:CharacterString {data($DataCuratorRoleHolder/moles:contactDetails/moles:telephone)} } (:</voice>:) else (), if (exists($DataCuratorRole/moles:contactDetails/moles:fax)) then element facsimile { element gco:CharacterString {data($DataCuratorRoleHolder/moles:contactDetails/moles:fax)} } (: </facsimile> :) else if (exists($DataCuratorRoleHolder/moles:contactDetails/moles:telephone)) then element facsimile { element gco:CharacterString {data($DataCuratorRoleHolder/moles:contactDetails/moles:fax)} } (: </facsimile> :) else () } (: </gmd:CI_Telephone> :) } (: </phone> :) else (), element address { element gmd:CI_Address { if (exists($DataCuratorRole/moles:contactDetails/moles:address/moles:addressline)) then for $addressline in $DataCuratorRole/moles:contactDetails/moles:address/moles:addressline return element deliveryPoint {element gco:CharacterString {data($addressline)}} else if (exists($DataCuratorRoleHolder/moles:contactDetails/moles:address/moles:addressline)) then for $addressline in $DataCuratorRoleHolder/moles:contactDetails/moles:address/moles:addressline return element deliveryPoint {element gco:CharacterString {data($addressline)}} else (), if (exists($DataCuratorRole/moles:contactDetails/moles:address/moles:city)) then element city {element gco:CharacterString {data($DataCuratorRole/moles:contactDetails/moles:address/moles:city)}} else if (exists($DataCuratorRoleHolder/moles:contactDetails/moles:address/moles:city)) then element city {element gco:CharacterString {data($DataCuratorRoleHolder/moles:contactDetails/moles:address/moles:city)}} else (), if (exists($DataCuratorRole/moles:contactDetails/moles:eMail)) then element electronicMailAddress {element gco:CharacterString {data($DataCuratorRole/moles:contactDetails/moles:eMail)}} else if (exists($DataCuratorRoleHolder/moles:contactDetails/moles:address/moles:postcode)) then element electronicMailAddress {element gco:CharacterString {data($DataCuratorRoleHolder/moles:contactDetails/moles:eMail)}} else () } (: </gmd:CI_Address> :) } (: </address> :) } (: </gmd:CI_Contact> :) } (: </contactInfo> :), element role { element CI_RoleCode { attribute codeList {'http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_RoleCode'}, attribute codeListValue {'http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_RoleCode_custodian'}, if (exists($DataCuratorRole/moles:localName)) then data($DataCuratorRole/moles:localName) else if (exists($DataCuratorRoleHolder/moles:localName)) then data($DataCuratorRoleHolder/moles:localName) else 'Curator' } (: </CI_RoleCode> :) } (: </role> :) } (: </CI_ResponsibleParty> :) } (: </contact> :), element dateStamp {element gco:Date {adjust-date-to-timezone(current-date())}}, element metadataStandardName {element gco:CharacterString {'ISO 19115:2003'}}, element metadataStandardVersion {element gco:CharacterString {'2003'}}, element identificationInfo { element gmd:MD_DataIdentification { element citation { element gmd:CI_Citation { element title {element gco:CharacterString {data($DE/moles:name)}}, if (exists($DE/moles:abbreviation) and not(empty($DE/moles:abbreviation))) then element alternateTitle {element gco:CharacterString {data($DE/moles:abbreviation)}} else (), element date { if (exists($DE/(moles:DataProvenance | moles:dgMetadataProvenance)/moles:RecordCreation/moles:CreatedDate)) then element gmd:CI_Date { element date {element gco:Date {adjust-date-to-timezone(data($DE/(moles:DataProvenance | moles:dgMetadataProvenance)/moles:RecordCreation/moles:CreatedDate))}}, element dateType { element CI_DateTypeCode { attribute codeList {'http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode'}, attribute codeListValue {'http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#CI_DateTypeCode_creation' }, 'Creation'} } (: </dataType> :) } (: </gmd:CI_Date> :) else attribute gco:nilReason {'unknown'} } (: </date> :) } (: </gmd:CI_Citation> :) } (: </citation> :), element abstract {element gco:CharacterString {data($DE/moles:dgMetadataDescription/moles:abstract/moles:abstractText)}}, element language { element gmd:LanguageCode { attribute codeList {'http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#LanguageCode'}, attribute codeListValue {'eng'}, 'English' } } (: </language> :), for $ISOTopicCategory in ($DE/moles:dgStructuredKeyword[dgValidTermID/moles:ParentListID='http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_TopicCategoryCode']) return element topicCategory { element gmd:MD_TopicCategoryCode { attribute codeList {'http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_TopicCategoryCode'}, attribute codeListValue {string($ISOTopicCategory/moles:dgValidTerm)}, string($ISOTopicCategory/moles:dgValidTerm)} } (: </topicCategory> :), if (exists($DE/moles:dgDataEntity/moles:dgDataSummary/moles:dgDataCoverage)) then element extent { element gmd:EX_Extent { (: add bounding boxes:) for $geoBBox in $DE/moles:dgDataEntity/moles:dgDataSummary/moles:dgDataCoverage//moles:BoundingBox return element geographicElement { element EX_GeographicBoundingBox { element westBoundLongitude {element gco:Decimal {data($geoBBox/moles:LimitWest)}}, element eastBoundLongitude {element gco:Decimal {data($geoBBox/moles:LimitEast)}}, element southBoundLatitude {element gco:Decimal {data($geoBBox/moles:LimitSouth)}}, element northBoundLatitude {element gco:Decimal {data($geoBBox/moles:LimitNorth)}} } (: </EX_GeographicBoundingBox> :) } (: </geographicElement> :), (: add location terms:) for $geoArea in $DE/moles:dgDataEntity/moles:dgDataSummary/moles:dgDataCoverage//moles:dgArea return element geographicElement { element EX_GeographicDescription { element geographicIdentifier { element gmd:RS_Identifier { element gco:CharacterString {element code {data($geoArea/moles:dgValidTerm)}}, element gco:CharacterString {element codeSpace {data($geoArea/moles:dgValidTermID/moles:ParentListID)}} } } } (: </EX_GeographicDescription> :) } (: </geographicElement> :) } (: </gmd:EX_Extent> :) } (: </extent> :) else() } (:</gmd:MD_DataIdentification> :) } (: </identificationInfo> :) } (: </MD_Metadata> :) } ) else ( element dummy:container { doc(fn:item-at($i, 1)) } ) "; 347 System.out.println( "xquery was:\n" + xqueryStr ); 348 queryParams.addElement( xqueryStr.getBytes("UTF-8") ); 349 queryParams.addElement( 1 ); 350 queryParams.addElement( 1 ); 351 352 Hashtable docSearchOptions = new Hashtable(); 353 docSearchOptions.put("indent", "yes"); 354 docSearchOptions.put("encoding", "UTF-8"); 355 docSearchOptions.put("process-xsl-pi", "no"); 356 queryParams.addElement( docSearchOptions ); 357 try 358 { 359 360 byte[] resultByteArray = (byte[])xmlrpc.execute( "query", queryParams ); 361 362 ByteArrayInputStream resultStream = new ByteArrayInputStream( resultByteArray ); 363 System.out.println( new String(resultByteArray) ); 364 // Use XMLOutputter 365 XMLOutputter out = new XMLOutputter (); 366 out.setFormat( Format.getCompactFormat() ); // UTF-8 & trimming of whitespace 367 368 SAXBuilder builder = new SAXBuilder(); 369 org.jdom.Document doc = builder.build( resultStream ); 370 org.jdom.Element root = doc.getRootElement(); 371 org.jdom.Element container = root.getChild("container", Namespace.getNamespace("dummy","http://ndg.nerc.ac.uk/dummy")); 372 org.jdom.Element elem = container.getChild(properties.getProperty("rootElement.ISO19115"), Namespace.getNamespace(properties.getProperty("namespace.ISO19115"))); 373 // If this doesn't work, try & fetch it as if it belongs to no namespace 374 if ( elem == null ) 375 { 376 elem = container.getChild(properties.getProperty("rootElement.ISO19115"),Namespace.getNamespace("")); 377 } 378 379 380 returnDoc = out.outputString( elem ); 381 if (returnDoc != null) 382 { 383 returnDocs.add( returnDoc ); 384 } 385 } 386 catch ( java.lang.NullPointerException e) 387 { 388 // Catch failure for this individual document 389 returnDocs.add( "" ); 390 failedDocs.add(thisdoc); 391 } 392 } 393 394 else 395 { 396 throw new Exception("Format " + this.format + " not implemented."); 397 } 398 } 399 400 if ( returnDocs.isEmpty() || (returnDocs.size() == failedDocs.size()) ) 401 { 402 result.setStatus(false); 403 result.setStatusMessage("Error retrieving all documents"); 404 405 } else { 406 result.setStatus(true); 407 result.setStatusMessage("Success"); 408 result.setDocuments( returnDocs ); 409 } 410 if ( failedDocs.size() > returnDocs.size() ) 411 { 412 String failedDocMessage = " but some failed documents : "; 413 Iterator failedIt = failedDocs.iterator(); 414 int failedCount = 0; 415 while ( failedIt.hasNext() ) 416 { 417 failedDocMessage += (String)failedIt.next(); 418 if ( failedCount < (failedDocs.size()-1) ) 419 { 420 failedDocMessage += ", "; 421 } 422 failedCount++; 423 } 424 result.setStatusMessage( result.getStatusMessage() + failedDocMessage ); 425 } 426 } 427 catch (Exception e) 428 { 429 result.setStatus( false ); 430 result.setStatusMessage( "Error retrieving document(s) : " + e.toString() ); 431 } 76 // firstly prepare the search query string 77 String sqlQuery = constructSearchQuery(); 78 79 // now run the query using the db client configured appropriately 80 InterfaceDBClient client = DBProperties.setupDBClient(); 81 String[][] results = client.runQuery(sqlQuery); 82 client.closeConnection(); 83 84 // now extract the results data 85 result = processResults(results); 432 86 433 87 return result; 434 88 } 435 89 90 /** 91 * Parse returned results from DB call and put these into a PresentSummary object 92 * to return via the webservice 93 * 94 * @param results - 2D string array of results from DB 95 * @return PresentSummary populated with results set 96 */ 97 private PresentSummary processResults(String[][] results) 98 { 99 logger.info("Extracting results"); 100 PresentSummary result = new PresentSummary(); 101 102 if (results.length > 0) 103 { 104 Vector<String> returnedDocs = new Vector<String>(); 105 for (int i=0; i < results.length; i++) 106 { 107 logger.info("Adding document to results set"); 108 // NB, array is filename, file contents 109 returnedDocs.add(results[i][1]); 110 } 111 result.setStatus(true); 112 result.setStatusMessage("Success"); 113 result.setDocuments(returnedDocs); 114 logger.info("Results added to present summary"); 115 } 116 else 117 { 118 result.setStatus( false ); 119 String outMessage = "Document retrieval was successful but generated no results."; 120 result.setStatusMessage(outMessage); 121 logger.info(outMessage); 122 } 123 logger.info("Results extracted"); 124 return result; 125 } 126 127 /** 128 * Set up a SQL Select query with the input search parameters 129 * 130 * @return String - SQL command 131 */ 132 private String constructSearchQuery() 133 { 134 logger.info("Creating search query"); 135 136 String sqlCmd = null; 137 138 // construct apostrophe separated list of documents to use in 'IN' statement 139 Iterator<String> it = this.documentNames.iterator(); 140 StringBuffer allDocs = new StringBuffer(); 141 while ( it.hasNext() ) 142 { 143 String thisdoc = it.next(); 144 if (allDocs.length() > 0) 145 allDocs.append(", "); 146 allDocs.append("'" + thisdoc + "'"); 147 } 148 149 // if the format is original, we can look this up directly from the original doc table 150 if (this.getFormat().equals(DiscoveryServiceSkeleton.ORIGINAL_FORMAT)) 151 { 152 sqlCmd = "SELECT original_document_filename, original_document FROM " + 153 DBProperties.ORIGINAL_DOCUMENT_TABLE + DBProperties.WHERE_STATEMENT + 154 DBProperties.ORIGINAL_DOCUMENT_TABLE + ".original_document_filename IN (" + allDocs.toString() + ")"; 155 } 156 else 157 { 158 sqlCmd = "SELECT original_document_filename, transformed_document FROM " + 159 DBProperties.ORIGINAL_DOCUMENT_TABLE + ", " + DBProperties.TRANSFORMED_DOCUMENT_TABLE + 160 DBProperties.WHERE_STATEMENT + DBProperties.TRANSFORMED_DOCUMENT_TABLE + ".original_document_id = " + 161 DBProperties.ORIGINAL_DOCUMENT_TABLE + ".original_document_id AND " + 162 DBProperties.TRANSFORMED_DOCUMENT_TABLE + ".transformed_format = '" + this.getFormat() + "' AND " + 163 DBProperties.ORIGINAL_DOCUMENT_TABLE + ".original_document_filename IN (" + allDocs.toString() + ")"; 164 } 165 logger.info("Search query created"); 166 return sqlCmd; 167 } 168 169 public String getFormat() { 170 return format; 171 } 172 173 public Vector getDocumentNames() { 174 return documentNames; 175 } 176 436 177 } 437 178
Note: See TracChangeset
for help on using the changeset viewer.