xquery version "1.0"; (: $Id$ :) (: Module: display and browse collections. :) module namespace browse="http://exist-db.org/xquery/admin-interface/browse-projects"; declare namespace text="http://exist-db.org/xquery/text"; declare namespace request="http://exist-db.org/xquery/request"; declare namespace xdb="http://exist-db.org/xquery/xmldb"; declare namespace util="http://exist-db.org/xquery/util"; declare namespace v="http://exist-db.org/versioning"; declare namespace transform="http://exist-db.org/xquery/transform"; declare namespace edit="http://rebind.bgbm.org/code/correction-report"; declare namespace date="http://exist-db.org/xquery/datetime"; declare namespace httpclient= "http://exist-db.org/xquery/httpclient"; declare namespace http = "http://expath.org/ns/http-client"; declare namespace biocase="http://www.biocase.org/schemas/protocol/1.3"; import module namespace metadata="http://exist-db.org/xquery/rebind/edit-metadata" at "xform-eml.xqm"; (: Main function: outputs the page. :) declare function browse:main() as element() { let $colName := request:get-parameter("collection", "/db")[1] let $colName := if(not(starts-with($colName,"/db")))then(fn:concat("/db",$colName))else($colName) let $projectRoot := rebind:getSetting('db-project-folder') let $publicRoot := rebind:getSetting('db-public-folder') let $protectedRoot := rebind:getSetting('db-protected-folder') (: check if collections exist, if not: create them; they should however already be created :) let $output1 := if(not(xmldb:collection-available($projectRoot))) then (xmldb:create-collection("", $projectRoot)) else () let $output2 := if(not(xmldb:collection-available($publicRoot))) then (xmldb:create-collection("", $publicRoot)) else () let $output3 := if(not(xmldb:collection-available($protectedRoot))) then (xmldb:create-collection("", $protectedRoot)) else () let $patternProjectRoot := fn:concat("^(",$publicRoot,"|",$protectedRoot,")/[^/]+/?$") let $patternProject := fn:concat("^(",$publicRoot,"|",$protectedRoot,")/[^/]+(/.+)?$") let $patternProtectedProject := fn:concat("^",$protectedRoot,"/[^/]+/?") let $patternprojectName := fn:concat("^(",$publicRoot,"|",$protectedRoot,")/") let $patternProjectPath := fn:concat("^(",$publicRoot,"|",$protectedRoot,")/[^/]+") let $isProjectRoot := matches($colName,$patternProjectRoot) let $isProject := matches($colName,$patternProject) let $isProtectedProject := matches($colName,$patternProtectedProject) let $projectName := replace(replace($colName,$patternprojectName,''),"/.*$","") let $projectPath := text:filter($colName,$patternProjectPath)[1] let $metadataFileName := rebind:getSetting('metadata-file') return if(empty($projectPath))then(
Could not find project in path: {$colName}
)else if(not(xmldb:collection-available($colName)))then(
Project '{$projectName}' does not exist at: {$colName}
)else(
Project: {$projectName}
{if($isProject and not($isProjectRoot))then(Up)else()} {browse:display-project($colName)} {if(xdb:is-admin-user(xdb:get-current-user()) and $isProtectedProject) then (
New Collection Upload from bioCASE Upload File {if($isProjectRoot and not(browse:contains-metadata-file($colName)) )then(Create Metadata File)else()} {if($isProjectRoot and browse:contains-metadata-file($colName) )then(Publish Project)else()(: option to publish only if metadata file exists. The check if the data files are valid is done after the Publish button was pressed. :)}




By publishing your data on reBiND you agree to the Biocase code of conduct.
{if($isProjectRoot and browse:contains-metadata-file($colName) )then( )else()}
)else() }
) }; declare option exist:serialize "indent=yes method=xhtml"; declare function browse:show-project-menu() as element() { let $colName := request:get-parameter("collection", "/db") let $colName := if(not(starts-with($colName,"/db")))then(fn:concat("/db",$colName))else($colName) let $panel := request:get-parameter("panel", "status")[1] let $projectRoot := rebind:getSetting('db-project-folder') let $publicRoot := rebind:getSetting('db-public-folder') let $protectedRoot := rebind:getSetting('db-protected-folder') (: check if collections exist, if not: create them :) let $output1 := if(not(xmldb:collection-available($projectRoot))) then (xmldb:create-collection("", $projectRoot)) else () let $output2 := if(not(xmldb:collection-available($publicRoot))) then (xmldb:create-collection("", $publicRoot)) else () let $output3 := if(not(xmldb:collection-available($protectedRoot))) then (xmldb:create-collection("", $protectedRoot)) else () let $link := session:encode-url(request:get-uri()) let $editLogCollectionName := rebind:getSetting('edit-log-folder-name') let $isEditLogCollection := matches($colName,concat(".*?",$editLogCollectionName,"/?$")) return }; (: Process an action. :) declare function browse:process-action($colName as xs:string) as element()* { (: TODO #32: check for rights :) let $action := request:get-parameter("action", ())[1] let $protectedRoot := rebind:getSetting('db-protected-folder') return util:catch("java.lang.Exception", if($action eq "createcollection") then ( browse:create-collection($colName) ) else if($action eq "createproject") then ( browse:create-collection($protectedRoot) ) else if($action eq "upload") then ( browse:upload($colName) ) else if($action eq "upload-biocase") then ( browse:upload-biocase($colName) ) else if($action eq "save-metadata") then ( browse:save-metadata($colName) )else if($action eq "publish") then ( browse:publish() )else(),
An error occurred while processing the action:
{$util:exception-message}
) }; (: Store uploaded content. :) declare function browse:upload($colName as xs:string) as element() { let $name := request:get-parameter("filename", ()), $docName := if($name) then $name else request:get-uploaded-file-name("upload"), $file := request:get-uploaded-file-data("upload") return

Actions:

}; (: TODO This function only gets files with a maximum number of records set to 700, for files greater than this size we need to loop and merge all the XML files retrieved to one single XML file. Need to check the totalSearchHits. :) declare function browse:upload-biocase($colName as xs:string) as element() { let $name := request:get-parameter("filename", ()), $url := request:get-parameter("url", ()), $query_string := "query=%3C%3Fxml+version%3D%271.0%27+encoding%3D%27UTF-8%27%3F%3E%0D%0A%3Crequest+xmlns%3D%27http%3A%2F%2Fwww.biocase.org%2Fschemas%2Fprotocol%2F1.3%27%3E%0D%0A++%3Cheader%3E%3Ctype%3Esearch%3C%2Ftype%3E%3C%2Fheader%3E%0D%0A++%3Csearch%3E%0D%0A++++%3CrequestFormat%3Ehttp%3A%2F%2Fwww.tdwg.org%2Fschemas%2Fabcd%2F2.06%3C%2FrequestFormat%3E%0D%0A++++%3CresponseFormat+start%3D%270%27+limit%3D%275700%27%3Ehttp%3A%2F%2Fwww.tdwg.org%2Fschemas%2Fabcd%2F2.06%3C%2FresponseFormat%3E%0D%0A++++++%3Ccount%3Efalse%3C%2Fcount%3E%0D%0A++%3C%2Fsearch%3E%0D%0A%3C%2Frequest%3E", $reqs := {$query_string} , $post := http:send-request($reqs), $totalSearchHits := $post[2]//biocase:response/biocase:content/@totalSearchHits (:doc("/db/test/abcd/biocase_response_example.xml")//biocase:response/biocase:content/*:) (:return

{$post//@status}

:) (:Check for response code 200 from server:) return if ( $post[1]/@status eq '200' or $post[1]/@status eq '201' ) then (:$abcd_data := $post[2]//biocase:response/biocase:content/* :) (: the document is saved but this div content is not displayed :)

Actions:

else () (:TODO should indicate that the file has not been uploaded as there was a problem - please check the url and that a valid filename has been entered:) }; (: Save metadata file. :) declare function browse:save-metadata-old($colName as xs:string) as element() { let $data := request:get-data() let $file-name := rebind:getSetting('metadata-file') (: check to make sure we have valid post data :) return if (not($data)) then
else (

Actions:

) }; declare function browse:save-metadata($colName as xs:string) as element()* { let $data := request:get-data() let $file-name := rebind:getSetting('metadata-file') let $action := request:get-parameter("action", ())[1] let $save := xdb:store($colName, xdb:encode-uri($file-name), $data) (: check to make sure we have valid post data :) (:return if($action eq "save-form") then( :) return if($data) then( let $fileName := request:get-parameter("name", "test.xml")[1] return (
File 'metadata.xml' was successfully saved!
) )else(
) }; (: publish a project :) declare function browse:publish() as element() { (: TODO #31: check if there is a project with the same name in the public collection. If so promt a warning and ask if the existing project should be overwritten :) let $colName := request:get-parameter("project", ()) let $publicRoot := rebind:getSetting('db-public-folder') let $protectedRoot := rebind:getSetting('db-protected-folder') let $patternprojectName := fn:concat("^(",$publicRoot,"|",$protectedRoot,")/") let $patternProjectRoot := fn:concat("^(",$publicRoot,"|",$protectedRoot,")/[^/]+/?$") let $patternProtectedProject := fn:concat("^",$protectedRoot,"/[^/]+/?") let $projectName := replace(replace($colName,$patternprojectName,''),"/.*$","") let $isProjectRoot := matches($colName,$patternProjectRoot) let $isProtectedProject := matches($colName,$patternProtectedProject) (: TODO #28: do other integrity checks, give warning if any one fails, like no metadata file, validation fails, etc. :) (: TODO #28: check if correction is running :) return if(xdb:is-admin-user(xdb:get-current-user()) and $isProtectedProject and $isProjectRoot) then ( let $move := xdb:move(concat($protectedRoot,"/",$projectName), $publicRoot) return

Actions:

)else() }; (: Create a collection. :) declare function browse:create-collection($parentColName as xs:string) as element() { (: TODO #30: check if name is equal to the correction report folder, if so: do not create new folder :) let $newcol := request:get-parameter("create", ()) return

Actions:

}; (: Display a list with all the projects :) declare function browse:display-projects($colName as xs:string) as element()* { let $currentCollection := request:get-parameter("file", "/db")[1] let $currentCollection := request:get-parameter("collection", $currentCollection)[1] let $currentCollection := if(not(starts-with($currentCollection,"/db")))then(fn:concat("/db",$currentCollection))else($currentCollection) return if(count(xdb:get-child-collections($colName)) > 0) then ( )else() }; declare function browse:display-project-collections($colName as xs:string) as element()* { let $editLogCollectionName := rebind:getSetting('edit-log-folder-name') for $child in xdb:get-child-collections($colName) let $path := concat($colName, '/', $child), $created := xdb:created($path) order by $child return
  • {if($child eq $editLogCollectionName)then( {xdb:decode-uri(xs:anyURI($child))} )else( {xdb:decode-uri(xs:anyURI($child))} )}
  • }; declare function browse:display-project-files($colName as xs:string) as element()* { let $protectedRoot := rebind:getSetting('db-protected-folder') let $patternProtectedProject := fn:concat("^",$protectedRoot,"/[^/]+/?") let $isProtectedProject := matches($colName,$patternProtectedProject) for $child at $count in xdb:get-child-resources($colName) let $restUri := concat(request:get-context-path(), '/rest') let $eXideUri := concat(request:get-context-path(), '/apps/eXide2/index.html?doc=') let $extension := fn:replace(fn:lower-case(fn:replace($child, '.*\.','')),'7z','zip7') let $lastRevision := browse:last-revision($colName, $child)//v:properties/v:revision/string() let $isMetadata := browse:is-metadata-file($colName, $child) let $metaTag := if($isMetadata)then(" metadata")else() order by $child return
  • {xdb:decode-uri(xs:anyURI($child))}
  • }; declare function browse:display-project($colName as xs:string) as element()* { }; declare function browse:is-filetype-editable($fileExtension as xs:string) as xs:boolean{ let $editableFiletypes := tokenize(rebind:getSetting('editable-file-types'),",") return not(empty(index-of($editableFiletypes,$fileExtension))) }; declare function browse:is-filetype-validatable($fileExtension as xs:string) as xs:boolean{ (: TODO #34: decide if file is editable based on whether it is stored in the XML storage of eXist-db and not based on the file extension :) let $editableFiletypes := tokenize(rebind:getSetting('validatable-file-types'),",") return not(empty(index-of($editableFiletypes,$fileExtension))) }; declare function browse:is-metadata-file($colName as xs:string, $fileName as xs:string) as xs:boolean{ let $metadataFileName := rebind:getSetting('metadata-file') let $publicRoot := rebind:getSetting('db-public-folder') let $protectedRoot := rebind:getSetting('db-protected-folder') let $patternProjectRoot := fn:concat("^(",$publicRoot,"|",$protectedRoot,")/[^/]+/?$") let $isProjectRoot := matches($colName,$patternProjectRoot) return if($fileName eq $metadataFileName and $isProjectRoot)then(true())else(false()) }; declare function browse:contains-metadata-file($colName as xs:string) as xs:boolean{ let $metadataFileName := rebind:getSetting('metadata-file') return not(empty(index-of(xdb:get-child-resources($colName),$metadataFileName))) }; declare function browse:get-file-status($collectionName as xs:string, $filename as xs:string) as xs:int*{ let $editLogCollectionName := rebind:getSetting('edit-log-folder-name') let $edit-log := doc(concat($collectionName,'/',$editLogCollectionName,'/',$filename)) return if(exists($edit-log))then( let $info-unreviewed-count := count($edit-log//edit:edit[@severity="info" and @reviewed="false"]) let $info-total-count := count($edit-log//edit:edit[@severity="info"]) let $warning-unreviewed-count := count($edit-log//edit:edit[@severity="warning" and @reviewed="false"]) let $warning-total-count := count($edit-log//edit:edit[@severity="warning"]) let $error-unreviewed-count := count($edit-log//edit:edit[@severity="error" and @reviewed="false"]) let $error-total-count := count($edit-log//edit:edit[@severity="error"]) let $result := ($error-unreviewed-count,$error-total-count,$warning-unreviewed-count,$warning-total-count,$info-unreviewed-count,$info-total-count) return $result )else() }; declare function browse:last-revision($collection as xs:string, $resource as xs:string) { let $vCollection := concat("/db/system/versions", $collection) let $versions := for $version in collection($vCollection)/v:version[ v:properties[v:document = $resource] ] order by xs:long($version/v:properties/v:revision) descending return $version return $versions[1] }; (: Get the name of the parent collection from a specified collection path. :) declare function browse:get-parent-collection($path as xs:string) as xs:string { if($path eq "/db") then $path else replace($path, "/[^/]*$", "") };