(:~ : Download content from the DB : : @author Rave Technologies, https://www.rave-tech.com/, 2017 :) module namespace download = 'http://www.rave-tech.com/bloomsbury/download'; import module namespace config = 'http://www.rave-tech.com/bloomsbury/config' at './module/config.xqm'; import module namespace blcommon = 'http://www.rave-tech.com/bloomsbury/common' at 'common.xqm'; import module namespace audit = 'http://www.rave-tech.com/bloomsbury/audit' at './module/manage-audit.xqm'; (:~ : To download complete bunch of content from the database into the file system within zip : v1../dummy/fileurl... : @param $cid Content ID to download its component : @param $format Content format to download (word,xml) : @param $type A flat to download all content (all,none) : @header $authorization Authorization key : @return element(result) :) declare %updating %rest:path("/download") %rest:POST("{$body}") %rest:query-param("format", "{$format}", "NONE") %rest:query-param("type", "{$type}", "NONE") %rest:header-param("Authorization", "{$authorization}", "none") %rest:consumes("application/xml", "text/xml") function download:download( $body as document-node(), $format as xs:string, $type as xs:string, $authorization as xs:string ) { config:session-check($authorization), try { if(fn:doc-available(fn:concat($config:CoreDatabase,$config:DownloadConfig))) then if($format='NONE' or $type="NONE") then update:output(FailurePlease supply correct parameters) else if($format='xml' or $format='word') then download:start-process($body,$format,$type,config:session-value($authorization)) else update:output(FailureFormat other than XML/Word not supported) else update:output(Failure{fn:concat('Configuration file is not available :', $config:DownloadConfig)}) } catch * { admin:write-log("[Download][Error: " || $err:description || "]"), admin:write-log("[Download][Error: " || $err:additional || "]"), update:output(ErrorError generated. Please check system log) } }; (:~ : Download content as XML from the database. : @param $inputXml Download parameter chunk of the request : @param $format Required download format (xml,word) : @param $type A flat to download all content (all,none) : @param $sessionValue Session Value : @return element(result) :) (:declare %private %updating function download:start-process( $inputXml as document-node(), $format as xs:string, $type as xs:string, $sessionValue as xs:string ) { let $zipName := fn:format-dateTime(fn:current-dateTime(), "[Y1,4][M01][D01][H01][m01][s01][f01]") let $zipUri := fn:concat($config:OutDir, $zipName,'.zip') let $countDownload := fn:count($inputXml/download/content) let $Uri := for $inputContent in $inputXml/download/content return if($type='all' and fn:not(matches(string-join($inputXml/download/content/uri/text(),'|'),'version'))) then for $db in db:list()[not(contains(.,'bloomsbury'))] return fn:uri-collection(fn:concat($db,$config:ContentDir,$inputContent/cid))[fn:not(fn:contains(.,$config:AuditFileName) or fn:contains(.,$config:VersionControlFileName) or fn:contains(.,$config:InfoXml) or fn:contains(.,$config:MetaXml) or fn:contains(.,$config:WordDir) or fn:contains(.,$config:VersionDir) or fn:contains(.,$config:ClassifyXml) )] else if($type='all' and matches(string-join($inputXml/download/content/uri/text(),'|'),'version')) then for $db in db:list()[not(contains(.,'bloomsbury'))] return fn:uri-collection(fn:concat($db,$config:ContentDir,$inputContent/cid))[fn:not(fn:contains(.,$config:AuditFileName) or fn:contains(.,$config:VersionControlFileName) or fn:contains(.,$config:InfoXml) or fn:contains(.,$config:MetaXml) or fn:contains(.,$config:WordDir) or fn:contains(.,$config:ClassifyXml) )] [fn:contains(.,fn:concat('v',$inputContent/version/text()))] else $inputContent/uri/text() let $zip := archive:create ( for $dbUri in $Uri let $cid := fn:tokenize($dbUri,'/')[4] let $coid := fn:tokenize($dbUri,'/')[5] let $contentType := fn:tokenize($dbUri,'/')[2] let $supportedFormat := db:open($config:CoreDatabase,$config:DownloadConfig)/*:controlledList/*:name[@ctype-idref=$contentType]/@cformat-idref/string() let $outputFormat := if(fn:contains($supportedFormat,fn:replace($format,'word','docx'))) then $format else 'xml' let $isDeleted := db:open(blcommon:get-db-name($contentType),fn:concat($config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml))/info/delete/text() return if($isDeleted='yes') then () else (:if(fn:contains($dbUri,$config:HeaderXml) or $outputFormat='xml') then if($type='all') then element archive:entry { fn:concat($cid,'/',fn:tokenize($dbUri,'/')[fn:last()]) } else() else element archive:entry { fn:concat($cid,'/',fn:replace(fn:tokenize($dbUri,'/')[fn:last()],'.xml','.docx')) }:) if(fn:contains($dbUri,$config:HeaderXml) or $outputFormat='xml') then element archive:entry { fn:concat($cid,'/',fn:tokenize($dbUri,'/')[fn:last()]) } else element archive:entry { fn:concat($cid,'/',fn:replace(fn:tokenize($dbUri,'/')[fn:last()],'.xml','.docx')) } , for $dbUri in $Uri let $cid := fn:tokenize($dbUri,'/')[4] let $coid := fn:tokenize($dbUri,'/')[5] let $contentType := fn:tokenize($dbUri,'/')[2] let $supportedFormat := db:open($config:CoreDatabase,$config:DownloadConfig)/*:controlledList/*:name[@ctype-idref=$contentType]/@cformat-idref/string() let $outputFormat := if(fn:contains($supportedFormat,fn:replace($format,'word','docx'))) then $format else 'xml' let $isDeleted := db:open(blcommon:get-db-name($contentType),fn:concat($config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml))/info/delete/text() let $isPrintReady := db:open(blcommon:get-db-name($contentType),fn:concat($config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml))/info/content-format/text() return if($isDeleted='yes') then () else if(fn:contains($dbUri,$config:HeaderXml) or $outputFormat='xml') then bin:encode-string(fn:serialize((fn:doc($dbUri)))) (:bin:encode-string(fn:serialize( fn:doc($dbUri) ,map {'indent': 'no'})):) else ( let $inputFileName := fn:tokenize($dbUri,'/')[fn:last()] let $inputUri := fn:replace(fn:concat(fn:substring-before($dbUri,$inputFileName),$config:WordDir,fn:replace($inputFileName,'.xml','.docx')),'//','/') let $WordUri := fn:concat($config:OutDir, fn:replace(fn:tokenize($dbUri,'/')[fn:last()],'.xml','.docx')) let $archive := db:retrieve(blcommon:get-db-name($contentType),fn:substring-after($inputUri,blcommon:get-db-name($contentType))) let $worlRelation := fn:parse-xml(archive:extract-text($archive, $config:DocRelXml)) let $wordStyle := fn:parse-xml(archive:extract-text($archive, $config:StyleXml)) let $writeRelation := file:write(fn:concat($config:TempDir,$inputFileName), $worlRelation) let $updateWord := if($isPrintReady='PRINT-READY') then $archive else archive:update($archive, $config:DocXml, fn:serialize(xslt:transform(fn:doc($dbUri), db:open($config:CoreDatabase,$config:DocBook2WordML),map { 'relFilePath':fn:concat($config:TempDir,$inputFileName)}))) let $updateStyle := if($isPrintReady='PRINT-READY') then $updateWord else archive:update($updateWord, $config:StyleXml, fn:serialize(xslt:transform($wordStyle, db:open($config:CoreDatabase,$config:WordStyle)))) return $updateStyle ) ) return ( if(file:is-dir($config:OutDir)) then () else file:create-dir($config:OutDir) , file:write-binary($zipUri, $zip) , for $dbUri in $Uri let $contentType := fn:tokenize($dbUri,'/')[2] return audit:update($dbUri,$contentType,$sessionValue,'Download') , update:output(SuccessZip generated. Pls. check the output{$zipUri}) , config:update-message('[Content Download][Zip generated ' || $zipUri || ']') ) }; :) declare %private %updating function download:start-process( $inputXml as document-node(), $format as xs:string, $type as xs:string, $sessionValue as xs:string ) { let $zipName := fn:format-dateTime(fn:current-dateTime(), "[Y1,4][M01][D01][H01][m01][s01][f01]") let $zipUri := fn:concat($config:OutDir, $zipName,'.zip') let $countDownload := fn:count($inputXml/download/content) let $Uri := for $inputContent in $inputXml/download/content return if($type='all' and fn:not(matches(string-join($inputXml/download/content/uri/text(),'|'),'version'))) then for $db in db:list()[not(contains(.,'bloomsbury') or contains(.,$config:ContentManagementDatabase) or contains(.,$config:MetadataOnlyContentDatabase) or contains(.,$config:OnixDB ))] return fn:uri-collection(fn:concat($db,$config:ContentDir,$inputContent/cid))[fn:not(fn:contains(.,$config:AuditFileName) or fn:contains(.,$config:VersionControlFileName) or fn:contains(.,$config:InfoXml) or fn:contains(.,$config:MetaXml) or fn:contains(.,$config:WordDir) or fn:contains(.,$config:VersionDir) or fn:contains(.,$config:ClassifyXml) )] else if($type='all' and matches(string-join($inputXml/download/content/uri/text(),'|'),'version')) then for $db in db:list()[not(contains(.,'bloomsbury') or contains(.,$config:ContentManagementDatabase) or contains(.,$config:MetadataOnlyContentDatabase) or contains(.,$config:OnixDB ))] return fn:uri-collection(fn:concat($db,$config:ContentDir,$inputContent/cid))[fn:not(fn:contains(.,$config:AuditFileName) or fn:contains(.,$config:VersionControlFileName) or fn:contains(.,$config:InfoXml) or fn:contains(.,$config:MetaXml) or fn:contains(.,$config:WordDir) or fn:contains(.,$config:ClassifyXml) )] [fn:contains(.,fn:concat('v',$inputContent/version/text()))] else $inputContent/uri/text() let $zip := archive:create ( for $dbUri in $Uri let $cid := fn:tokenize($dbUri,'/')[4] let $coid := fn:tokenize($dbUri,'/')[5] let $contentType := fn:tokenize($dbUri,'/')[2] let $supportedFormat := db:open($config:CoreDatabase,$config:DownloadConfig)/*:controlledList/*:name[@ctype-idref=$contentType]/@cformat-idref/string() (:let $outputFormat := if(fn:contains($supportedFormat,fn:replace($format,'word','docx'))) then $format else 'xml':) let $outputFormat := if(($contentType='monograph') or ($contentType='play')) then $supportedFormat else if ($contentType='looseleaf') then if($format='word') then 'docx' else '.xml' let $isDeleted := db:open(blcommon:get-db-name($contentType),fn:concat($config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml))/info/delete/text() return if($isDeleted='yes') then () else if(fn:contains($dbUri,$config:HeaderXml) or $outputFormat='xml') then if($type='all') then element archive:entry { fn:concat($cid,'/',fn:tokenize($dbUri,'/')[fn:last()]) } else() else element archive:entry { fn:concat($cid,'/',fn:replace(fn:tokenize($dbUri,'/')[fn:last()],'.xml','.docx')) } , for $dbUri in $Uri let $cid := fn:tokenize($dbUri,'/')[4] let $coid := fn:tokenize($dbUri,'/')[5] let $contentType := fn:tokenize($dbUri,'/')[2] let $supportedFormat := db:open($config:CoreDatabase,$config:DownloadConfig)/*:controlledList/*:name[@ctype-idref=$contentType]/@cformat-idref/string() (:let $outputFormat := if(fn:contains($supportedFormat,fn:replace($format,'word','docx'))) then $format else 'xml':) let $outputFormat := if(($contentType='monograph') or ($contentType='play')) then $supportedFormat else if ($contentType='looseleaf') then if($format='word') then 'docx' else '.xml' let $isDeleted := db:open(blcommon:get-db-name($contentType),fn:concat($config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml))/info/delete/text() let $isPrintReady := db:open(blcommon:get-db-name($contentType),fn:concat($config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml))/info/content-format/text() return if($isDeleted='yes') then () else if(fn:contains($dbUri,$config:HeaderXml) or $outputFormat='xml') then if($type='all') then bin:encode-string(fn:serialize((fn:doc($dbUri)))) else () else ( let $inputFileName := fn:tokenize($dbUri,'/')[fn:last()] let $inputUri := fn:replace(fn:concat(fn:substring-before($dbUri,$inputFileName),$config:WordDir,fn:replace($inputFileName,'.xml','.docx')),'//','/') let $WordUri := fn:concat($config:OutDir, fn:replace(fn:tokenize($dbUri,'/')[fn:last()],'.xml','.docx')) let $archive := db:retrieve(blcommon:get-db-name($contentType),fn:substring-after($inputUri,blcommon:get-db-name($contentType))) let $worlRelation := fn:parse-xml(archive:extract-text($archive, $config:DocRelXml)) let $wordStyle := fn:parse-xml(archive:extract-text($archive, $config:StyleXml)) let $writeRelation := file:write(fn:concat($config:TempDir,$inputFileName), $worlRelation) let $updateWord := if($isPrintReady='PRINT-READY') then $archive else archive:update($archive, $config:DocXml, fn:serialize(xslt:transform(fn:doc($dbUri), db:open($config:CoreDatabase,$config:DocBook2WordML),map { 'relFilePath':fn:concat($config:TempDir,$inputFileName)}))) let $updateStyle := if($isPrintReady='PRINT-READY') then $updateWord else archive:update($updateWord, $config:StyleXml, fn:serialize(xslt:transform($wordStyle, db:open($config:CoreDatabase,$config:WordStyle)))) return $updateStyle ) ) let $xmlarchive := zip:zip-file( { for $dbUri in $Uri let $cid := fn:tokenize($dbUri,'/')[4] let $coid := fn:tokenize($dbUri,'/')[5] let $filename := fn:tokenize($dbUri,'/')[fn:last()] let $contentType := fn:tokenize($dbUri,'/')[2] let $supportedFormat := db:open($config:CoreDatabase,$config:DownloadConfig)/*:controlledList/*:name[@ctype-idref=$contentType]/@cformat-idref/string() let $outputFormat := if(fn:contains($supportedFormat,fn:replace($format,'word','docx'))) then $format else 'xml' let $isDeleted := db:open(blcommon:get-db-name($contentType),fn:concat($config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml))/info/delete/text() let $isPrintReady := db:open(blcommon:get-db-name($contentType),fn:concat($config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml))/info/content-format/text() return if($isDeleted='yes') then () else {fn:doc($dbUri)} } ) return ( if(file:is-dir($config:OutDir)) then () else file:create-dir($config:OutDir) , if($format!='xml') then file:write-binary($zipUri, $zip) else ( let $xmlzip := file:read-binary($config:Xmlziplocation) return ( file:write-binary($zipUri, $xmlzip) , file:delete($config:Xmlziplocation) ) ) , for $dbUri in $Uri let $contentType := fn:tokenize($dbUri,'/')[2] return audit:update($dbUri,$contentType,$sessionValue,'Download') , update:output(SuccessZip generated. Pls. check the output{$zipUri}) , config:update-message('[Content Download][Zip generated ' || $zipUri || ']') ) }; (:~ : get content format information. : @param $body parameter chunk of the request : @param $format Required format (xml,word) : @param $sessionValue Session Value : @return element(result) :) declare %rest:path("/downloadinfo") %rest:POST("{$body}") %rest:query-param("format", "{$format}", "NONE") %rest:header-param("Authorization", "{$authorization}", "none") %rest:consumes("application/xml", "text/xml") function download:get-format( $body as document-node(), $format as xs:string, $authorization as xs:string ) { let $countDownload := fn:count($body/content-format/content) let $result := for $inputContent in $body/content-format/content for $dbUri in if((($countDownload eq 1) or (fn:contains($inputContent/uri, '/content/latest/')))) then $inputContent/uri/text() else for $db in db:list()[not(contains(.,'bloomsbury') or contains(.,$config:ContentManagementDatabase) or contains(.,$config:MetadataOnlyContentDatabase) or contains(.,$config:OnixDB ))] return fn:uri-collection( fn:concat($db,$config:ContentDir,fn:substring-before(fn:substring-after($inputContent/uri,fn:concat($db,$config:ContentDir)),$config:ContentDir)) )[fn:not(fn:contains(.,$config:AuditFileName) or fn:contains(.,$config:VersionControlFileName) or fn:contains(.,$config:InfoXml) or fn:contains(.,$config:MetaXml) or fn:contains(.,$config:WordDir))] let $cid := fn:tokenize($dbUri,'/')[4] let $coid := fn:tokenize($dbUri,'/')[5] let $contentType := distinct-values(fn:tokenize($dbUri,'/')[2]) let $supportedFormat := db:open($config:CoreDatabase,$config:DownloadConfig)/*:controlledList/*:name[@ctype-idref=$contentType]/@cformat-idref/string() let $outputFormat := if(fn:contains($supportedFormat,fn:replace($format,'word','docx'))) then fn:replace($format,'docx','word') else 'xml' let $isDeleted := for $db in db:list()[not(contains(.,'bloomsbury') or contains(.,$config:ContentManagementDatabase) or contains(.,$config:MetadataOnlyContentDatabase) or contains(.,$config:OnixDB ))] return db:open($db,fn:concat($config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml))/info/delete/text() return if($contentType ='looseleaf') then if($isDeleted='yes') then content is deleted else if(fn:contains($dbUri,$config:HeaderXml)) then false else if($outputFormat='word') then true else false else( if($isDeleted='yes') then content is deleted else if(fn:contains($dbUri,$config:HeaderXml)) then false else if($outputFormat='word') then true else false ) return if($result!='') then { Success, $result } else { Success, records not available. } };