teacup/content.xqm

1646 lines
79 KiB
Plaintext

(:~
: Add content into the system
:
: @author Rave Technologies, https://www.rave-tech.com/, 2017
:)
(:~
: Update History :
: Modified on 16/03/21: Resolve ticket CMS-235
:)
module namespace contents = 'http://www.rave-tech.com/bloomsbury/contents';
import module namespace config = 'http://www.rave-tech.com/bloomsbury/config' at './module/config.xqm';
import module namespace audit = 'http://www.rave-tech.com/bloomsbury/audit' at './module/manage-audit.xqm';
import module namespace report = 'http://www.rave-tech.com/bloomsbury/report' at 'report.xqm';
import module namespace blcommon = 'http://www.rave-tech.com/bloomsbury/common' at 'common.xqm';
import module namespace blpipelines = 'http://www.rave-tech.com/bloomsbury/pipelines' at 'pipelines.xqm';
import module namespace schematron = "http://github.com/Schematron/schematron-basex";
declare namespace pipeline = 'http://cms.bloomsbury.com/pipeline';
declare namespace product = 'http://cms.bloomsbury.com/product-manifest';
(:~
: To search content.
: @param $query Term to search
: @param $pid Product ID
: @param $page Page number of the list optional
: @param $size Total number of records to display in a page optional
: @param $ctype to search within Content Type, single
: @param $version to search on all available versions (true/false)
: @header $authorization Authorization key
: @return element(result)
:)
declare
%rest:path("/content")
%rest:GET
%rest:query-param("q", "{$query}")
%rest:query-param("title", "{$title}")
%rest:query-param("publisher", "{$publisher}")
%rest:query-param("series", "{$series}")
%rest:query-param("id", "{$id}")
%rest:query-param("pid", "{$pid}")
%rest:query-param("cid", "{$cid}")
%rest:query-param("page", "{$page}")
%rest:query-param("size", "{$size}")
%rest:query-param("ctype", "{$ctype}")
%rest:query-param("version", "{$version}")
%rest:header-param("Authorization", "{$authorization}", "none")
function contents:search($query as xs:string?,
$title as xs:string?,
$publisher as xs:string?,
$series as xs:string?,
$pid as xs:string?,
$cid as xs:string?,
$id as xs:string?,
$page as xs:integer?,
$size as xs:integer?,
$ctype as xs:string?,
$version as xs:boolean,
$authorization as xs:string
)
{
config:session-check($authorization),
try
{
if($query!='' or $title!='' or $publisher!='' or $series!='' or $id!='')
then
let $page := if($page) then $page else $config:page
let $size := if($size) then $size else $config:size
let $start := if($page eq 1)
then $page
else if($page gt 1)
then fn:sum(($page * $size)+1) - $size
else fn:sum(($page * $size)) - $size
let $end := if($page eq 1)
then $size
else if($page gt 1)
then fn:sum(($start + $size)-1)
else fn:sum($start + $size)
let $dbname := string-join((
if(fn:contains($ctype,$config:Audio) or fn:contains($ctype,$config:Video) or
fn:contains($ctype,$config:Person) or fn:contains($ctype,$config:Publisher) or
fn:contains($ctype,$config:Organisation) or fn:contains($ctype,$config:Series) or
fn:contains($ctype,$config:Image))
then $config:MetadataOnlyContentDatabase else(),
if(fn:contains($ctype,$config:playDatabase)) then $config:playDatabase else(),
if(fn:contains($ctype,$config:MonographDatabase)) then $config:MonographDatabase else(),
if(fn:contains($ctype,$config:LooseleafDatabase)) then $config:LooseleafDatabase else(),
if(fn:contains($ctype,$config:screenplayDatabase)) then $config:screenplayDatabase else()
),'|')
let $uri := if($ctype!='' and $id='' and $title='')
then
let $cid := fn:distinct-values(db:open($config:CoreDatabase,$config:JobDir)/job/job-info[job-type='Ingest']
[content-type=$ctype]/cid)
for $uri in fn:uri-collection(fn:concat(blcommon:get-db-name($ctype),$config:ContentDir))[fn:tokenize(.,'/')[4]=$cid]
[fn:contains(.,'/content/latest')]
[fn:not(fn:contains(.,$config:AuditFileName)
or fn:contains(.,$config:VersionControlFileName)
or fn:contains(.,$config:InfoXml)
or fn:contains(.,$config:VersionDir)
or fn:contains(.,$config:Metadata)
)]
return
if(fn:doc($uri)//*[if($query!='') then fn:contains(fn:lower-case(.),fn:lower-case($query)) else *])
then $uri
else ()
else
if($title!='')
then
(
for $db in db:list()[if($ctype!='') then fn:matches(.,fn:concat('^',$dbname,'$'),'i') else fn:not(fn:contains(.,$config:CoreDatabase) or fn:contains(.,$config:OnixDB) or fn:contains(.,$config:ContentManagementDatabase) or fn:contains(.,$config:AuditDatabase) or fn:contains(.,$config:ContentMetadataDatabse))]
for $uri in db:open($db)[not(name(/*)='info')]
[fn:not( fn:contains(.,$config:InfoXml)
or fn:contains(.,$config:VersionDir)
or fn:contains(.,$config:VersionControlFileName)
)
] /*[if($title!='')
then(
if(fn:starts-with($title,'"'))
then
if(/*:TEI/*:text/*:body//*:div[@type="play"]/*:head//text())
then (/*:TEI/*:text/*:body//*:div[@type="play"]/*:head//text()[. contains text {$title} phrase])
else if(/*/*:item_title)
then (/*/*:item_title)//text()[. contains text {$title} phrase]
else (/*:book/*:info/*:title)//text()[. contains text {$title} phrase]
else(
if(/*:TEI/*:text/*:body//*:div[@type="play"]/*:head//text())
then (/*:TEI/*:text/*:body//*:div[@type="play"]/*:head//text()[. contains text {$title} all words])
else if(/*/*:item_title)
then (/*/*:item_title)//text()[. contains text {$title} all words]
else (/*:book/*:info/*:title)//text()[. contains text {$title} all words]
))
else *
]/base-uri()[if(fn:contains(.,$config:MetadataOnlyContentDatabase)) then fn:matches(fn:tokenize(.,'/')[3],$ctype,'i') else fn:matches(fn:tokenize(.,'/')[2],$ctype,'i')]
return $uri
)
else
if($publisher!='')
then
for $uri in fn:uri-collection(fn:concat($config:playDatabase,'/content/'))
[fn:not(fn:contains(.,$config:AuditFileName)
or fn:contains(.,$config:VersionControlFileName)
or fn:contains(.,$config:InfoXml)
)]
[if($version eq fn:true()) then (.) else fn:contains(.,'/content/latest')]
return
if(fn:doc($uri)[if($publisher!='') then fn:matches(string-join(*:TEI/*:teiHeader/*:fileDesc/*:publicationStmt/*:publisher/text(),'|'),fn:normalize-space($publisher),'i') else *])
then $uri
else()
else
if($series!='')
then
let $OnixDoc := fn:collection(fn:concat($config:OnixDB,$config:Onix))
let $PlayDoc := fn:collection('play')
for $series in $OnixDoc/ONIXMessage/Product/Series/(TitleOfSeries|Title[TitleType=01]/TitleText)[fn:contains(lower-case(.),lower-case($series))]
let $OnixIsbn := $series/ancestor::*:Product/*:ProductIdentifier[ProductIDType='15']/IDValue
for $PlayUri in $PlayDoc/*:TEI/*:teiHeader/*:fileDesc/*:publicationStmt/*:idno[@type='isbn'][fn:contains(.,$OnixIsbn)]/base-uri(.)
return $PlayUri[if($version eq fn:true()) then (.) else fn:contains(.,'/content/latest')]
else
if($id!='')
then
for $db in db:list()[if($ctype!='') then fn:matches(.,fn:concat('^',$dbname,'$'),'i') else fn:not(fn:contains(.,$config:CoreDatabase) or fn:contains(.,$config:OnixDB) or fn:contains(.,$config:ContentManagementDatabase) or fn:contains(.,$config:AuditDatabase) or fn:contains(.,$config:ContentMetadataDatabse))]
for $uri in fn:uri-collection($db)[if((fn:matches(fn:tokenize(.,'/')[2],'^play$') or fn:matches(fn:tokenize(.,'/')[2],'^monograph$'))) then fn:contains(.,'latest') else .]
[fn:not(
fn:contains(.,$config:VersionDir)
or fn:contains(.,$config:VersionControlFileName)
)
] [if(fn:contains(.,$config:MetadataOnlyContentDatabase)) then fn:matches(fn:tokenize(.,'/')[3],$ctype,'i') else fn:matches(fn:tokenize(.,'/')[2],$ctype,'i')]
return
if(fn:doc($uri)
[if($id!='')
then
(if (lower-case(./*/@id/string()))
then
fn:contains( lower-case(fn:normalize-space(./*/@id)) ,lower-case($id))
else if (./*/@xml:id/string())
then
fn:contains( fn:normalize-space(./*/@xml:id) ,$id)
else()
)
else *
])
then $uri
else ()
else ()
let $countRecord := fn:count($uri)
let $userXml := db:open($config:CoreDatabase,fn:concat($config:UserDir,fn:substring-before(config:session-value($authorization),'$$$$'),'.xml'))
let $userDept := fn:concat('(',fn:string-join($userXml/user//department/text(),'|'),')')
let $contentRecords := for $result in $uri[fn:position() = $start to $end]
let $version := if(fn:contains($result,'/content/version/')) then for $uritoken in fn:tokenize($result,'/')[8] return fn:replace($uritoken,'v','')
else(
let $versionControlUri := fn:concat(fn:substring-before($result, 'content/latest/'),$config:VersionControlFileName)
return
if(fn:doc-available($versionControlUri))
then
let $versionDoc := doc($versionControlUri)
let $nextVersion := fn:sum(fn:max($versionDoc/versions/version/@number) + 1)
return $nextVersion
else 1
)
let $isAlreadyCheckedOut := db:open($config:CoreDatabase,$config:LockDir)/locks/lock/files/file[uri=$result]
[version=$version]
let $snippet := <snippet>{if($query!='')
then
(if(fn:starts-with($query,'"')) then (fn:doc($result)//text()[fn:matches(., replace($query,'"',''),'i' )])[1] else fn:doc($result)//*[text() contains text {$query} all words])[1]
else if ($title!='')
then (if(fn:starts-with($title,'"')) then (fn:doc($result)//text()[fn:matches(., replace($title,'"',''),'i' )])[1] else fn:doc($result)//*[text() contains text {$title} any word])[1]
else ()
}</snippet>
let $cid := <cid>{fn:tokenize($result,'/')[4]}</cid>
let $coid := <coid>{fn:tokenize($result,'/')[5]}</coid>
let $Dbname := fn:tokenize($result,'/')[2]
let $infoXml := db:open($Dbname ,fn:concat($config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml))
let $metadatacontentType:= fn:tokenize($result,'/')[3]
let $metacontent := if(fn:contains($metadatacontentType,$config:Audio)or fn:contains($metadatacontentType,$config:Video)
or fn:contains($metadatacontentType,$config:Person) or fn:contains($metadatacontentType,$config:Publisher)
or fn:contains($metadatacontentType,$config:Organisation) or fn:contains($metadatacontentType,$config:Series)
or fn:contains($metadatacontentType,$config:Image)
)
then 'true'
else 'false'
let $auditUri := if(fn:contains($result,'/metadataonlycontent/')) then () else fn:concat($config:AuditDatabase,'/',fn:tokenize($result,'/')[2],$config:ContentDir,fn:tokenize($result,'/')[fn:position()=4],'/',fn:tokenize($result,'/')[fn:position()=5],'/',$config:AuditFileName)
let $auditXml := fn:doc($auditUri)/audits/audit[type='Checkin'][fn:last()]
let $IngestAuditXml := fn:doc($auditUri)/audits/audit[type='Ingestion']
let $checkoutauditXml := fn:doc($auditUri)/audits/audit[type='Checkout'][fn:last()]
let $CheckedoutdbyUser := $checkoutauditXml/requester-id/string()
let $checkedusername := distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[id=$CheckedoutdbyUser][fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))]/name/string())
let $CheckedoutDate := <checkedout-date>{$checkoutauditXml/date-time/string()}</checkedout-date>
let $checkedoutby := <checkedout-by>{$checkedusername}</checkedout-by>
let $titles := <title>
{
if(normalize-space(fn:doc($result)/*:book/*:part/*:info/*:title[ @*:style='n-PartTitle']/text()) )
then fn:concat(fn:doc($result)/*:book/*:part/*:info/*:title[ @*:style='n-PartTitle']/text(), ': ' ,fn:doc($result)/*:book/*:part/*:chapter[1]/*:info/*:title//text())
else if(fn:doc($result)//*:item_title) then fn:doc($result)//*:item_title//text() else (fn:doc($result)//*:title//text())[1]
,
if(fn:doc($result)//*:title or fn:doc($result)//*:item_title) then () else fn:replace(fn:tokenize($result,'/')[fn:last()],'.xml','')
}
</title>
order by $titles
return
<content>{
$titles,
if($title!='')
then
if(fn:starts-with($title,'"') )
then
<subtitles>{
if(fn:doc($result)//*:TEI/*:text/*:body//*:div[@type="play"])
then
for $subtitle in fn:doc($result)//*:TEI/*:text/*:body//*:div[@type="play"]/*:head[matches(.,replace($title,'^"(.*)"$',''),'i')]//text()
return
<subtitle id="{fn:doc($result)//*:TEI/*:text/*:body//*:div[@type="play"][matches(*:head,$subtitle,'qi')]/@xml:id/string()}" name="{$subtitle}"></subtitle>
else()
}</subtitles>
else
<subtitles>{
if(fn:doc($result)//*:TEI/*:text/*:body//*:div[@type="play"])
then
for $subtitle in fn:doc($result)//*:TEI/*:text/*:body//*:div[@type="play"]/*:head//text()[. contains text {$title} any word]
return
<subtitle id="{fn:doc($result)//*:TEI/*:text/*:body//*:div[@type="play"][matches(*:head,$subtitle,'qi')]/@xml:id/string()}" name="{$subtitle}"></subtitle>
else()
}</subtitles>
else(),
if($series!='')
then
let $playisbn := fn:doc($result)/*:TEI/*:teiHeader/*:fileDesc/*:publicationStmt/*:idno[@type='isbn']/text()
return <series>{fn:collection(fn:concat($config:OnixDB,$config:Onix))/ONIXMessage/Product[ProductIdentifier[ProductIDType='15']/IDValue[. = $playisbn]]/Series/(TitleOfSeries|Title[TitleType=01]/TitleText)/string()}</series>
else()
,
if($publisher!='')
then
fn:doc($result)/*:TEI/*:teiHeader/*:fileDesc/*:publicationStmt/*:publisher
else()
,
if($id!='')
then
let $id := if (
fn:doc($result)/*/@xml:id/string()
)
then fn:doc($result)/*/@xml:id/string()
else if ( fn:doc($result)/*/@id/string() )
then fn:doc($result)/*/@id/string()
else ()
return <id>{$id}</id>
else(),
<snippet><para>{$snippet//text()}</para></snippet>,
<content-type>{if($infoXml!='')then $infoXml/info/ctype/text() else $metadatacontentType}</content-type>,
<meta-content>{$metacontent}</meta-content>,
<department>{$infoXml/info/area/text()}</department>,
<checkout>{if($isAlreadyCheckedOut) then 'true' else 'false'}</checkout>,
<locked>{if($infoXml!='') then if(fn:matches($infoXml/info/area/text(),$userDept)) then fn:false() else fn:true() else fn:false()}</locked>,
$CheckedoutDate,
$checkedoutby,
<uri>{$result}</uri>,
$cid,
$coid,
<version>{$version}</version>,
<deleted>{if($infoXml/info/delete!='') then $infoXml/info/delete/text() else 'no'}</deleted>,
<print-ready>{if($infoXml/info/content-format='PRINT-READY') then 'yes' else 'no'}</print-ready>
}</content>
return
if($contentRecords)
then
(
<result><status>Success</status><total>{$countRecord}</total><entities>{$contentRecords}</entities></result>,
config:non-update-message("[Content Search][Done successfully]")
)
else
(
<result><status>Success</status><message>No result found</message></result>,
config:non-update-message("[Content Search][No result found]")
)
else <result><status>Failure</status><message>Please supply the search term</message></result>
}
catch *
{
admin:write-log("[Content Search][Error: " || $err:description || "]"),
admin:write-log("[Content Search][Error: " || $err:additional || "]"),
<result><status>Error</status><message>Error generated. Please check system log</message></result>
}
};
(:~
: To get audit information.
: @param $cid Content ID to download its component
: @param $coid Component ID
: @header $authorization Authorization key
: @return element(result)
:)
declare
%rest:path("/audit/{$ctype=.+}/{$cid=.+}/{$coid=.+}")
%rest:GET
%rest:header-param("Authorization", "{$authorization}", "none")
function contents:get-audit(
$cid as xs:string,
$coid as xs:string,
$ctype as xs:string,
$authorization as xs:string
)
{
config:session-check($authorization),
try
{
(:let $uri := fn:uri-collection(blcommon:get-db-name($ctype))[fn:tokenize(.,'/')[4]=$cid]
[fn:tokenize(.,'/')[5]=$coid]
[fn:contains(.,$config:AuditFileName)]
[fn:not(fn:contains(.,$config:Metadata))]:)
let $uri := fn:uri-collection(fn:concat($config:AuditDatabase,'/',$ctype))[fn:tokenize(.,'/')[5]=$cid]
[fn:tokenize(.,'/')[6]=$coid]
return
if(fn:doc-available($uri))
then
(
<result><status>Success</status><message>Audit file is available</message>{fn:doc($uri)}</result>,
config:non-update-message('[Audit Get][Audit file sent ' || $uri || ']')
)
else <result><status>Failure</status><message>No related audit file is available{fn:concat('####CID###',$cid,'#####Coid###',$coid)}</message></result>
}
catch *
{
admin:write-log("[Audit Info][Error: " || $err:description || "]"),
admin:write-log("[Audit Info][Error: " || $err:additional || "]"),
<result><status>Error</status><message>Error generated. Please check system log</message></result>
}
};
(:~
: Get ingest pipeline
: @param $contentTypeID Content type ID
: @param $formatID Ingest format ID
: @return string
:)
declare function contents:get-applied-ingest-pipeline(
$contentTypeID as xs:string,
$formatID as xs:string
)
{
db:open($config:CoreDatabase,$config:PipelineConfig)/pipelines/pipeline[@ct-id-ref=$contentTypeID]
[matches(@format-id-ref,$formatID)]/@id-ref/string()
};
(::~
: To browse content.
: @param $dept Department ID
: @param $ct Content Type
: @param $page Page number of the list optional
: @param $size Total number of records to diplay in a page optional
: @header $authorization Authorization key
: @return element(result)
:)
declare
%rest:path("/browsecontent")
%rest:GET
%rest:query-param("dept", "{$dept}")
%rest:query-param("ct", "{$ct}")
%rest:query-param("page", "{$page}")
%rest:query-param("size", "{$size}")
%rest:header-param("Authorization", "{$authorization}", "none")
function contents:browse($dept as xs:string?,
$ct as xs:string?,
$page as xs:integer?,
$size as xs:integer?,
$authorization as xs:string
)
{
config:session-check($authorization),
try
{ if($ct!='' or $dept!='')
then
let $page := if($page) then $page else $config:page
let $size := if($size) then $size else $config:size
let $start := if($page eq 1)
then $page
else if($page gt 1)
then fn:sum(($page * $size)+1) - $size
else fn:sum(($page * $size)) - $size
let $end := if($page eq 1)
then $size
else if($page gt 1)
then fn:sum(($start + $size)-1)
else fn:sum($start + $size)
let $ContentTypeXML := fn:doc(fn:concat($config:CoreDatabase,$config:ContentType))
let $ct := if($ContentTypeXML/*:controlledList/*:name[@xml:id/string()=$ct]/@referenceid)
then $ContentTypeXML/*:controlledList/*:name[@xml:id/string()=$ct]/@referenceid/string()
else $ct
let $CtDeptinfo := for $db in db:list()[not( contains(.,$config:CoreDatabase) or contains(.,$config:MetadataOnlyContentDatabase) or contains(.,$config:OnixDB) or contains(.,$config:AuditDatabase) or contains(.,$config:ContentMetadataDatabse))]
return if(db:open($db,$config:ContentDir)/info[area=$dept] or db:open($db,$config:ContentDir)/info[ctype=$ct]) then 'true' else 'false'
return
if($CtDeptinfo='true')
then
(
if ($ct='looseleaf')
then
let $content-type-cid := fn:distinct-values(db:open(blcommon:get-db-name($ct),$config:ContentDir)/*:info[*:ctype=$ct]/*:cid/string())
let $department-cid := fn:distinct-values(db:open(blcommon:get-db-name($ct),$config:ContentDir)/*:info[*:area=$dept]/*:cid/string())
let $totalRecord := for $uri in fn:uri-collection(fn:concat($config:LooseleafDatabase,$config:ContentDir))[if($ct) then fn:tokenize(.,'/')[4]=$content-type-cid else(.)]
[if($dept) then fn:tokenize(.,'/')[4]=$department-cid else(.)]
[fn:contains(.,$config:HeaderXml)]
[fn:not(fn:contains(.,$config:VersionControlFileName)
or fn:contains(.,$config:InfoXml)
or fn:contains(.,$config:VersionDir)
)]
return $uri
let $Records :=
let $content-type-cid := fn:distinct-values(db:open($config:LooseleafDatabase,$config:ContentDir)/info[ctype=$ct]/cid/string())
let $department-cid := fn:distinct-values(db:open($config:LooseleafDatabase,$config:ContentDir)/info[area=$dept]/cid/string())
let $uris := (
for $uri in $totalRecord
let $title := <title>{
if(normalize-space(fn:doc($uri)/*:book/*:part/*:info/*:title[ @*:style='n-PartTitle']/text()) )
then fn:concat(fn:doc($uri)/*:book/*:part/*:info/*:title[ @*:style='n-PartTitle']/text(), ': ' ,fn:doc($uri)/*:book/*:part/*:chapter[1]/*:info/*:title//text())
else (fn:doc($uri)//*:title//text())[1],
if(fn:doc($uri)//*:title) then () else fn:replace(fn:tokenize($uri,'/')[fn:last()],'.xml','')
}</title>
order by upper-case($title)
return $uri
)[position()= $start to $end]
for $uri in $uris
let $versions := let $versionControlUri := fn:concat(fn:substring-before($uri, 'content/latest/'),$config:VersionControlFileName)
return
if(fn:doc-available($versionControlUri))
then
let $versionDoc := doc($versionControlUri)
let $nextVersion := fn:sum(fn:max($versionDoc/versions/version/@number) + 1)
return $nextVersion
else 1
let $title := <title>{
if(normalize-space(fn:doc($uri)/*:book/*:part/*:info/*:title[ @*:style='n-PartTitle']/text()) )
then fn:concat(fn:doc($uri)/*:book/*:part/*:info/*:title[ @*:style='n-PartTitle']/text(), ': ' ,fn:doc($uri)/*:book/*:part/*:chapter[1]/*:info/*:title//text())
else (fn:doc($uri)//*:title//text())[1],
if(fn:doc($uri)//*:title) then () else fn:replace(fn:tokenize($uri,'/')[fn:last()],'.xml','')
}</title>
let $coid := <coid>{fn:tokenize($uri,'/')[fn:position()=5]}</coid>
let $uri := <uri>{$uri}</uri>
let $cid := <cid>{fn:tokenize($uri,'/')[fn:position()=4]}</cid>
let $isAlreadyCheckedOut := db:open($config:CoreDatabase,$config:LockDir)/locks/lock/files/file[uri=$uri]
let $chekout := <checkout>{if($isAlreadyCheckedOut) then 'true' else 'false'}</checkout>
let $userXml := db:open($config:CoreDatabase,fn:concat($config:UserDir,fn:substring-before(config:session-value($authorization),'$$$$'),'.xml'))
let $docuemnturi := fn:data($uri)
let $uritoken := fn:tokenize($docuemnturi,'/')[last()-4]
let $userDept := fn:concat('(',fn:string-join($userXml/user//department/text(),'|'),')')
let $infoXml := db:open($config:LooseleafDatabase,fn:concat($config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml))
let $department := <department>{$infoXml/info/area/text()}</department>
let $contenttype := <content-type>{fn:distinct-values(db:open($config:LooseleafDatabase,$config:ContentDir)/info[ctype=$ct]/ctype/string())}</content-type>
let $locked := <locked>{if(fn:matches($department,$userDept)) then fn:false() else fn:true()}</locked>
let $version := <version>{concat('v',$versions)}</version>
(:let $auditUri := fn:concat($config:LooseleafDatabase,$config:ContentDir,$cid,'/',fn:data($coid),'/',$config:AuditFileName):)
(:let $auditUri := fn:concat($config:LooseleafDatabase,$config:ContentDir,$cid,'/',fn:data($coid),'/',$config:AuditFileName):)
let $auditUri := fn:concat($config:AuditDatabase,'/',$ct,$config:ContentDir,fn:tokenize($uri,'/')[fn:position()=4],'/',fn:tokenize($uri,'/')[fn:position()=5],'/',$config:AuditFileName)
let $auditXml := fn:doc($auditUri)/audits/audit[type='Checkin'][fn:last()]
let $IngestAuditXml := fn:doc($auditUri)/audits/audit[type='Ingestion']
let $checkoutauditXml := fn:doc($auditUri)/audits/audit[type='Checkout'][fn:last()]
let $CheckedoutdbyUser := $checkoutauditXml/requester-id/string()
let $checkedusername := distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[id=$CheckedoutdbyUser][fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))]/name/string())
let $CheckedoutDate := <checkedout-date>{$checkoutauditXml/date-time/string()}</checkedout-date>
let $checkedoutby := <checkedout-by>{$checkedusername}</checkedout-by>
let $IngestedbyUser := $IngestAuditXml/requester-id/string()
let $lastCheckedUserId := $auditXml/requester-id/string()
let $username := distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[id=$lastCheckedUserId][fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))]/name/string())
let $Ingestusername := distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[id=$IngestedbyUser][fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))]/name/string())
let $Ingestdate := <ingested-date>{$IngestAuditXml/date-time/string()}</ingested-date>
let $Ingestedby := <ingested-by>{$Ingestusername}</ingested-by>
let $lastcheckedby := <last-checkedby>{$username}</last-checkedby>
let $lastcheckindate := <last-checkin-date>{$auditXml/date-time/string()}</last-checkin-date>
let $lastcheckincomment := <last-checkin-comment>{$auditXml/comment/string()}</last-checkin-comment>
order by $title/string()
return
<content>
{
$title,
$cid,
$coid,
$department,
$contenttype,
$version,
$uri,
$chekout,
$locked,
$Ingestedby,
$Ingestdate,
$lastcheckedby,
$lastcheckindate,
$lastcheckincomment,
$checkedoutby,
$CheckedoutDate,
<deleted>{if($infoXml/info/delete!='') then $infoXml/info/delete/text() else 'no'}</deleted>,
<print-ready>{if($infoXml/info/content-format='PRINT-READY') then 'yes' else 'no'}</print-ready>
}
</content>
return
if($Records)
then
(
<result><status>Success</status><total>{count($totalRecord)}</total><entities>{$Records}</entities></result>,
config:non-update-message("[Content Search][Done successfully]")
)
else
(
<result><status>Success</status><message>No result found</message></result>,
config:non-update-message("[Content Search][No result found]")
)
else()
,
if($ct!='looseleaf')
then
let $content-type-cid := fn:distinct-values(db:open(blcommon:get-db-name($ct),$config:ContentDir)/*:info[*:ctype=$ct]/*:cid/string())
let $department-cid := fn:distinct-values(db:open(blcommon:get-db-name($ct),$config:ContentDir)/*:info[*:area=$dept]/*:cid/string())
let $totalRecord := for $uri in fn:uri-collection(fn:concat(blcommon:get-db-name($ct),$config:ContentDir))[if($ct) then fn:tokenize(.,'/')[4]=$content-type-cid else(.)]
[if($dept) then fn:tokenize(.,'/')[4]=$department-cid else(.)]
[fn:not(fn:contains(.,$config:VersionControlFileName)
or fn:contains(.,$config:InfoXml)
or fn:contains(.,$config:VersionDir)
)]
return $uri
let $Records :=
let $content-type-cid := fn:distinct-values(db:open(blcommon:get-db-name($ct),$config:ContentDir)/*:info[*:ctype=$ct]/*:cid/string())
let $department-cid := fn:distinct-values(db:open(blcommon:get-db-name($ct),$config:ContentDir)/*:info[*:area=$dept]/*:cid/string())
let $uris := (
for $uri in $totalRecord
let $title := <title>{
if(normalize-space(fn:doc($uri)/*:book/*:part/*:info/*:title[ @*:style='n-PartTitle']/text()) )
then fn:concat(fn:doc($uri)/*:book/*:part/*:info/*:title[ @*:style='n-PartTitle']/text(), ': ' ,fn:doc($uri)/*:book/*:part/*:chapter[1]/*:info/*:title//text())
else (fn:doc($uri)//*:title)[1]//text(),
if(fn:doc($uri)//*:title) then () else fn:replace(fn:tokenize($uri,'/')[fn:last()],'.xml','')
}</title>
order by upper-case($title)
return $uri
)[position()= $start to $end]
for $uri in $uris
let $versions := let $versionControlUri := fn:concat(fn:substring-before($uri, 'content/latest/'),$config:VersionControlFileName)
return
if(fn:doc-available($versionControlUri))
then
let $versionDoc := doc($versionControlUri)
let $nextVersion := fn:sum(fn:max($versionDoc/versions/version/@number) + 1)
return $nextVersion
else 1
let $title := <title>{
if(normalize-space(fn:doc($uri)/*:book/*:part/*:info/*:title[ @*:style='n-PartTitle']/text()) )
then fn:concat(fn:doc($uri)/*:book/*:part/*:info/*:title[ @*:style='n-PartTitle']/text(), ': ' ,fn:doc($uri)/*:book/*:part/*:chapter[1]/*:info/*:title//text())
else (fn:doc($uri)//*:title)[1]//text(),
if(fn:doc($uri)//*:title) then () else fn:replace(fn:tokenize($uri,'/')[fn:last()],'.xml','')
}</title>
let $coid := <coid>{fn:tokenize($uri,'/')[fn:position()=5]}</coid>
let $uri := <uri>{$uri}</uri>
let $cid := <cid>{fn:tokenize($uri,'/')[fn:position()=4]}</cid>
let $isAlreadyCheckedOut := db:open($config:CoreDatabase,$config:LockDir)/locks/lock/files/file[uri=$uri]
let $chekout := <checkout>{if($isAlreadyCheckedOut) then 'true' else 'false'}</checkout>
let $userXml := db:open($config:CoreDatabase,fn:concat($config:UserDir,fn:substring-before(config:session-value($authorization),'$$$$'),'.xml'))
let $userDept := fn:concat('(',fn:string-join($userXml/user//department/text(),'|'),')')
let $infoXml := db:open(blcommon:get-db-name($ct),fn:concat($config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml))
let $department := <department>{$infoXml/info/area/text()}</department>
let $contenttype := <content-type>{fn:distinct-values(db:open(blcommon:get-db-name($ct),$config:ContentDir)/*:info[*:ctype=$ct]/*:ctype/string())}</content-type>
let $locked := <locked>{if(fn:matches($department,$userDept)) then fn:false() else fn:true()}</locked>
let $version := <version>{concat('v',$versions)}</version>
(:let $auditUri := fn:concat(blcommon:get-db-name($ct),$config:ContentDir,fn:tokenize($uri,'/')[fn:position()=4],'/',fn:tokenize($uri,'/')[fn:position()=5],'/',$config:AuditFileName):)
let $auditUri := fn:concat($config:AuditDatabase,'/',$ct,$config:ContentDir,fn:tokenize($uri,'/')[fn:position()=4],'/',fn:tokenize($uri,'/')[fn:position()=5],'/',$config:AuditFileName)
let $auditXml := fn:doc($auditUri)/audits/audit[type='Checkin'][fn:last()]
let $IngestAuditXml := fn:doc($auditUri)/audits/audit[type='Ingestion']
let $checkoutauditXml := fn:doc($auditUri)/audits/audit[type='Checkout'][fn:last()]
let $CheckedoutdbyUser := $checkoutauditXml/requester-id/string()
let $checkedusername := distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[id=$CheckedoutdbyUser][fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))]/name/string())
let $CheckedoutDate := <checkedout-date>{$checkoutauditXml/date-time/string()}</checkedout-date>
let $checkedoutby := <checkedout-by>{$checkedusername}</checkedout-by>
let $IngestedbyUser := $IngestAuditXml/requester-id/string()
let $lastCheckedUserId := $auditXml/requester-id/string()
let $username := distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[id=$lastCheckedUserId][fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))]/name/string())
let $Ingestusername := distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[id=$IngestedbyUser]/name/string())
let $Ingestdate := <ingested-date>{$IngestAuditXml/date-time/string()}</ingested-date>
let $Ingestedby := <ingested-by>{$Ingestusername}</ingested-by>
let $lastcheckedby := <last-checkedby>{$username}</last-checkedby>
let $lastcheckindate := <last-checkin-date>{$auditXml/date-time/string()}</last-checkin-date>
let $lastcheckincomment := <last-checkin-comment>{$auditXml/comment/string()}</last-checkin-comment>
return
<content>
{
$title,
$cid,
$coid,
$contenttype,
$department,
$version,
$uri,
$chekout,
$locked,
$Ingestedby,
$Ingestdate,
$lastcheckedby,
$lastcheckindate,
$lastcheckincomment,
$checkedoutby,
$CheckedoutDate
}
</content>
return
if($Records)
then
(
<result><status>Success</status><total>{count($totalRecord)}</total><entities>{$Records}</entities></result>,
config:non-update-message("[Content Search][Done successfully]")
)
else
(
<result><status>Success</status><message>No result found</message></result>,
config:non-update-message("[Content Search][No result found]")
)
else(),
if($dept)
then
let $departmentcid := (db:open($config:MonographDatabase),db:open($config:playDatabase))/info[area=$dept]/cid/string()
let $totalRecord := (((db:open($config:MonographDatabase),db:open($config:playDatabase))/*[@xml:id=$departmentcid]))
let $result :=
(
for $doc in $totalRecord
let $uri := $doc/base-uri()
let $versions := let $versionControlUri := fn:concat(fn:substring-before($uri, 'content/latest/'),$config:VersionControlFileName)
return
if(fn:doc-available($versionControlUri))
then
let $versionDoc := doc($versionControlUri)
let $nextVersion := fn:sum(fn:max($versionDoc/versions/version/@number) + 1)
return $nextVersion
else 1
let $title := <title>{
(fn:doc($uri)//*:title//text())[1],
if(fn:doc($uri)//*:title) then () else fn:replace(fn:tokenize($uri,'/')[fn:last()],'.xml','')
}</title>
let $coid := <coid>{fn:tokenize($uri,'/')[fn:position()=5]}</coid>
let $uri := <uri>{$uri}</uri>
let $ct := fn:tokenize($uri,'/')[fn:position()=2]
let $cid := <cid>{fn:tokenize($uri,'/')[fn:position()=4]}</cid>
let $isAlreadyCheckedOut := db:open($config:CoreDatabase,$config:LockDir)/locks/lock/files/file[uri=$uri]
let $chekout := <checkout>{if($isAlreadyCheckedOut) then 'true' else 'false'}</checkout>
let $userXml := db:open($config:CoreDatabase,fn:concat($config:UserDir,fn:substring-before(config:session-value($authorization),'$$$$'),'.xml'))
let $docuemnturi := fn:data($uri)
let $uritoken := fn:tokenize($docuemnturi,'/')[last()-4]
let $userDept := fn:concat('(',fn:string-join($userXml/user//department/text(),'|'),')')
let $infoXml := db:open(blcommon:get-db-name($ct),fn:concat($config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml))
let $department := <department>{$infoXml/info/area/text()}</department>
let $contenttype := <content-type>{$infoXml/*:info/*:ctype/text()}</content-type>
let $locked := <locked>{if(fn:matches($department,$userDept)) then fn:false() else fn:true()}</locked>
let $version := <version>{concat('v',$versions)}</version>
(:let $auditUri := fn:concat(blcommon:get-db-name($ct),$config:ContentDir,$cid,'/',fn:data($coid),'/',$config:AuditFileName):)
let $auditUri := fn:concat($config:AuditDatabase,'/',$ct,$config:ContentDir,$cid,'/', fn:data($coid),'/',$config:AuditFileName)
let $auditXml := fn:doc($auditUri)/audits/audit[type='Checkin'][fn:last()]
let $IngestAuditXml := fn:doc($auditUri)/audits/audit[type='Ingestion']
let $checkoutauditXml := fn:doc($auditUri)/audits/audit[type='Checkout'][fn:last()]
let $CheckedoutdbyUser := $checkoutauditXml/requester-id/string()
let $checkedusername := distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[id=$CheckedoutdbyUser][fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))]/name/string())
let $CheckedoutDate := <checkedout-date>{$checkoutauditXml/date-time/string()}</checkedout-date>
let $checkedoutby := <checkedout-by>{$checkedusername}</checkedout-by>
let $IngestedbyUser := $IngestAuditXml/requester-id/string()
let $lastCheckedUserId := $auditXml/requester-id/string()
let $username := distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[id=$lastCheckedUserId][fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))]/name/string())
let $Ingestusername := distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[id=$IngestedbyUser]/name/string())
let $Ingestdate := <ingested-date>{$IngestAuditXml/date-time/string()}</ingested-date>
let $Ingestedby := <ingested-by>{$Ingestusername}</ingested-by>
let $lastcheckedby := <last-checkedby>{$username}</last-checkedby>
let $lastcheckindate := <last-checkin-date>{$auditXml/date-time/string()}</last-checkin-date>
let $lastcheckincomment := <last-checkin-comment>{$auditXml/comment/string()}</last-checkin-comment>
order by upper-case($title)
return
<content>
{
$title,
$cid,
$coid,
$contenttype,
$department,
$version,
$uri,
$chekout,
$locked,
$Ingestedby,
$Ingestdate,
$lastcheckedby,
$lastcheckindate,
$lastcheckincomment,
$checkedoutby,
$CheckedoutDate
}
</content> )[position()= $start to $end]
return
if($result)
then
(
<result><status>Success</status><total>{count($totalRecord)}</total><entities>{$result}</entities></result>,
config:non-update-message("[Content Search][Done successfully]")
)
else
(
<result><status>Success</status><message>No result found</message></result>,
config:non-update-message("[Content Search][No result found]")
)
else()
)
else <result><status>Success</status><message>contnet not found against department or contenttype {$dept,$ct}</message></result>
else <result><status>Failure</status><message>Please supply the content-type</message></result>
}
catch *
{
admin:write-log("[Content Search][Error: " || $err:description || "]"),
admin:write-log("[Content Search][Error: " || $err:additional || "]"),
<result><status>Error</status><message>Error generated. Please check system log</message></result>
}
};
(::~
: To browse component.
: @param $ct Content Type
: @param $page Page number of the list optional
: @param $size Total number of records to display in a page optional
: @header $authorization Authorization key
: @return element(result)
:)
declare
%rest:path("/browsecomponent")
%rest:GET
%rest:query-param("ct", "{$ct}")
%rest:query-param("cid", "{$cid}")
%rest:header-param("Authorization", "{$authorization}", "none")
function contents:browse-component($cid as xs:string?,
$ct as xs:string,
$authorization as xs:string
)
{
config:session-check($authorization),
try
{
let $contentid := for $cid in fn:distinct-values(db:open(blcommon:get-db-name($ct),$config:ContentDir)/info[cid=$cid]/cid/string()) return $cid
let $headeruri := fn:uri-collection(fn:concat(blcommon:get-db-name($ct),$config:ContentDir))[contains(.,$config:HeaderXml)][fn:tokenize(.,'/')[4]=$contentid]
[fn:not(fn:contains(.,$config:AuditFileName)
or fn:contains(.,$config:VersionControlFileName)
or fn:contains(.,$config:VersionDir))]
let $documenturi := for $content in fn:uri-collection(fn:concat(blcommon:get-db-name($ct),$config:ContentDir))[fn:tokenize(.,'/')[4]=$cid]
[fn:not(fn:contains(.,$config:AuditFileName)
or fn:contains(.,$config:VersionControlFileName)
or fn:contains(.,$config:InfoXml)
or fn:contains(.,$config:VersionDir)
or fn:contains(.,$config:HeaderXml)
or fn:contains(.,$config:Metadata)
)]
return $content
let $uricount := fn:count($documenturi)
let $contentRecords := for $result in $documenturi
let $version := let $versionControlUri := fn:concat(fn:substring-before($result, 'content/latest/'),$config:VersionControlFileName)
return
if(fn:doc-available($versionControlUri))
then
let $versionDoc := doc($versionControlUri)
let $nextVersion := fn:sum(fn:max($versionDoc/versions/version/@number) + 1)
return $nextVersion
else 1
let $isAlreadyCheckedOut := db:open($config:CoreDatabase,$config:LockDir)/locks/lock/files/file[uri=$result]
let $chekout := <checkout>{if($isAlreadyCheckedOut) then 'true' else 'false'}</checkout>
let $uri := <uri>{$result}</uri>
let $title := <title>{
if(normalize-space(fn:doc($result)/*:document/*:info/*:title[ @*:style='n-PartTitle']/text()) )
then fn:concat(fn:doc($result)/*:document/*:info/*:title[ @*:style='n-PartTitle']/text(), ': ' ,string-join(fn:doc($result)/*:document/*:chapter[1]/*:info/*:title//text()))
else (fn:doc($result)//*:title//text())[1],
if(fn:doc($result)//*:title) then () else fn:replace(fn:tokenize($result,'/')[fn:last()],'.xml','')
}</title>
let $coid := <coid>{fn:tokenize($result,'/')[fn:position()=5]}</coid>
let $version := <version>{concat('v',$version)}</version>
let $cid := <cid>{fn:tokenize($result,'/')[fn:position()=4]}</cid>
let $userXml := db:open($config:CoreDatabase,fn:concat($config:UserDir,fn:substring-before(config:session-value($authorization),'$$$$'),'.xml'))
let $docuemnturi := fn:data($result)
let $uritoken := fn:tokenize($docuemnturi,'/')[last()-4]
let $userDept := fn:concat('(',fn:string-join($userXml/user//department/text(),'|'),')')
let $infoXml := db:open(blcommon:get-db-name($ct),fn:concat($config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml))
let $department := <department>{$infoXml/info/area/text()}</department>
let $locked := <locked>{if(fn:matches($department,$userDept)) then fn:false() else fn:true()}</locked>
let $contenttype := <content-type>{fn:distinct-values(db:open(blcommon:get-db-name($ct),$config:ContentDir)/info[cid=$cid]/ctype/string())}</content-type>
(:let $auditUri := fn:concat(blcommon:get-db-name($ct),$config:ContentDir,$cid,'/',fn:data($coid),'/',$config:AuditFileName):)
let $auditUri := fn:concat($config:AuditDatabase,'/',$ct,$config:ContentDir,$cid,'/',fn:data($coid),'/',$config:AuditFileName)
let $auditXml := fn:doc($auditUri)/audits/audit[type='Checkin'][fn:last()]
let $IngestAuditXml := fn:doc($auditUri)/audits/audit[type='Ingestion']
let $checkoutauditXml := fn:doc($auditUri)/audits/audit[type='Checkout'][fn:last()]
let $CheckedoutdbyUser := $checkoutauditXml/requester-id/string()
let $checkedusername := distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[id=$CheckedoutdbyUser][fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))]/name/string())
let $CheckedoutDate := <checkedout-date>{$checkoutauditXml/date-time/string()}</checkedout-date>
let $checkedoutby := <checkedout-by>{$checkedusername}</checkedout-by>
let $IngestedbyUser := $IngestAuditXml/requester-id/string()
let $lastCheckedUserId := $auditXml/requester-id/string()
let $username := distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[id=$lastCheckedUserId][fn:not(fn:matches(fn:base-uri(.),'(/version/|/audit/)'))]/name/string())
let $Ingestusername := distinct-values(db:open($config:CoreDatabase,$config:UserDir)/user[id=$IngestedbyUser]/name/string())
let $Ingestdate := <ingested-date>{$IngestAuditXml/date-time/string()}</ingested-date>
let $Ingestedby := <ingested-by>{$Ingestusername}</ingested-by>
let $lastcheckedby := <last-checkedby>{$username}</last-checkedby>
let $lastcheckindate := <last-checkin-date>{$auditXml/date-time/string()}</last-checkin-date>
let $lastcheckincomment := <last-checkin-comment>{$auditXml/comment/string()}</last-checkin-comment>
return <content>
{
$title,
$cid,
$coid,
$department,
$contenttype,
$version,
$uri,
$chekout,
$locked,
$Ingestdate,
$Ingestedby,
$lastcheckedby,
$lastcheckindate,
$lastcheckincomment,
$checkedoutby,
$CheckedoutDate,
<deleted>{if($infoXml/info/delete!='') then $infoXml/info/delete/text() else 'no'}</deleted>,
<print-ready>{if($infoXml/info/content-format='PRINT-READY') then 'yes' else 'no'}</print-ready>
}
</content>
return
if($contentRecords)
then
(
let $uri := $documenturi[1]
(:let $title := if($uricount > 1) then (fn:doc($headeruri)//*:title/text())[1] else (fn:doc($uri)//*:title/text())[1]:)
let $title := if($ct='looseleaf') then (fn:doc($headeruri)//*:title/text())[1] else (fn:doc($uri)//*:title/text())[1]
let $version := let $versionControlUri := fn:concat(fn:substring-before($headeruri, 'content/latest/'),$config:VersionControlFileName)
return
if(fn:doc-available($versionControlUri))
then
let $versionDoc := doc($versionControlUri)
let $nextVersion := fn:sum(fn:max($versionDoc/versions/version/@number) + 1)
return $nextVersion
else 1
let $isAlreadyCheckedOut := db:open($config:CoreDatabase,$config:LockDir)/locks/lock/files/file[uri=$headeruri]
let $chekout := <checkout>{if($isAlreadyCheckedOut) then 'true' else 'false'}</checkout>
let $version := <version>{concat('v',$version)}</version>
let $cid := <cid>{fn:tokenize($headeruri,'/')[fn:position()=4]}</cid>
let $coid := <coid>{fn:tokenize($headeruri,'/')[fn:position()=5]}</coid>
let $contenttype := <content-type>{fn:distinct-values(db:open(blcommon:get-db-name($ct),$config:ContentDir)/info[cid=fn:tokenize($headeruri,'/')[fn:position()=4]]/ctype/string())}</content-type>
return
<result>
<status>Success</status>
<entities>
<content>
<title>{$title}</title>
<uri>{$headeruri}</uri>{$cid,$coid,$contenttype,$version,$chekout,$contentRecords}
</content>
</entities>
</result>
,
config:non-update-message("[Content Search][Done successfully]")
)
else
(
<result><status>Success</status><message>No result found</message></result>,
config:non-update-message("[Content Search][No result found]")
)
}
catch *
{
admin:write-log("[Content Search][Error: " || $err:description || "]"),
admin:write-log("[Content Search][Error: " || $err:additional || "]"),
<result><status>Error</status><message>Error generated. Please check system log</message></result>
}
};
(:~
: To get content version information.
: @param $cid Content ID
: @param $coid Component ID
: @header $authorization Authorization key
: @return element(result)
:)
declare
%rest:path("/content/{$ct=.+}/{$cid=.+}/{$coid=.+}/versions")
%rest:GET
%rest:header-param("Authorization", "{$authorization}", "none")
function contents:get-version(
$ct as xs:string,
$cid as xs:string,
$coid as xs:string,
$authorization as xs:string
)
{
try
{
if($cid!='' or $coid!='')
then
let $records := for $versionUri in fn:uri-collection(fn:concat(blcommon:get-db-name($ct),$config:ContentDir))[fn:tokenize(.,'/')[4]=$cid]
[fn:tokenize(.,'/')[5]=$coid]
[fn:contains(.,$config:VersionControlFileName)]
[fn:not(fn:contains(.,$config:Metadata))]
let $versionDoc := fn:doc($versionUri)
let $getlatest := $versionDoc/versions/version[fn:last()]
let $version := fn:concat('v',fn:sum (fn:number($getlatest/@number/string()) +1))
return
<versions>
{
<latest>
<version>{$version}</version>
<uri>{fn:concat('/',blcommon:get-db-name($ct),'/',(db:list(blcommon:get-db-name($ct),fn:concat($config:ContentDir,$cid,'/',$coid,'/content/latest/'))[fn:not(fn:contains(.,$config:WordDir))])[1])}</uri>
<on>{$getlatest/@on/string()}</on>
</latest>
,
for $records in $versionDoc/versions/version
let $versions := <version>{fn:concat('v',$records/@number/string())}</version>
let $uri := <uri>{fn:concat('/',blcommon:get-db-name($ct),$records/@uri/string())}</uri>
let $datetime := <on>{$records/@on/string()}</on>
return <version>{$versions,$uri,$datetime}</version>
}
</versions>
return
if($records)
then
(
<result><status>Success</status>{$records}</result>,
config:non-update-message("[Version records][Done successfully]")
)
else
(
let $LatestRecord := let $LatestUri := fn:uri-collection(fn:concat(blcommon:get-db-name($ct),$config:ContentDir))[fn:tokenize(.,'/')[4]=$cid]
[fn:tokenize(.,'/')[5]=$coid]
[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)
)]
return
<versions>
{
<latest>
<version>v1</version>
<uri>{$LatestUri}</uri>
</latest>
}
</versions>
return
if($LatestRecord)
then
(
<result><status>Success</status>{$LatestRecord}</result>,
config:non-update-message("[Version records][Done successfully]")
)
else
(
<result><status>Success</status><message>No versions available</message></result>,
config:non-update-message("[Version records][No result found]")
)
)
else <result><status>Failure</status><message>Please supply the content-id and component-id</message></result>
}
catch *
{
admin:write-log("[Content Search][Error: " || $err:description || "]"),
admin:write-log("[Content Search][Error: " || $err:additional || "]"),
<result><status>Error</status><message>Error generated. Please check system log</message></result>
}
};
(:~
: To get content taxonomies information linked to content.
: @param $cid Content ID
: @param $coid Component ID
: @header $authorization Authorization key
: @return element(result)
:)
declare
%rest:path("/content/{$ct=.+}/{$cid=.+}/{$coid=.+}/taxonomies")
%rest:GET
%rest:header-param("Authorization", "{$authorization}", "none")
function contents:get-taxonomies(
$ct as xs:string,
$cid as xs:string,
$coid as xs:string,
$authorization as xs:string
)
{
config:session-check($authorization),
try
{ if($cid!='' or $coid!='')
then
if(db:open($config:CoreDatabase)/*:product/*:contents/*:content/*:item/@id/string()=$cid)
then
let $product := for $productURI in collection(fn:concat($config:CoreDatabase,'/products/'))/*:product[fn:not(@delete)]/base-uri()[fn:contains(.,'latest')]
for $taxonomyID in fn:distinct-values(fn:doc($productURI)/*:product[*:contents/*:content/*:item/@id/string()=$cid]/@taxonomyRef/string())
let $records := for $tyaxonomydoc in fn:doc(fn:concat($config:CoreDatabase,$config:TaxonomyDir,$taxonomyID,'.xml'))
return
if($tyaxonomydoc)
then
<taxonomy id= "{$tyaxonomydoc/taxonomy/@id/string()}" name="{$tyaxonomydoc/taxonomy/@name/string()}" releaseDate="{$tyaxonomydoc/taxonomy/@releaseDate/string()}">{$tyaxonomydoc/taxonomy/*[not(descendant-or-self::*:facet[@role='contentType'])] }</taxonomy>
else <error/> return $records
return
if($product[fn:local-name()='error'])
then <result><status>Success</status><message>Related taxonomies is not available.</message></result>
else <result><status>Success</status><entities>{$product}</entities></result>
else <result><status>Failure</status><message>Content/Component not linked to taxonomy</message></result>
else <result><status>Failure</status><message>Please supply the content-id and component-id</message></result>
}
catch *
{
admin:write-log("[Content Search][Error: " || $err:description || "]"),
admin:write-log("[Content Search][Error: " || $err:additional || "]"),
<result><status>Error</status><message>Error generated. Please check system log</message></result>
}
};
(:~
: Mark content for deletion at the the of check-in.
: @param $jobID ID of the Job to upload content
: @param $contentID ID of the content
: @param $headerLocation Header file location
: @param $sessionValue Session Value
: @return empty sequence
:)
declare %updating function contents:delete-content(
$ct as xs:string,
$jobID as xs:string,
$contentID as xs:string,
$headerLocation as xs:string,
$sessionValue as xs:string
)
{
let $headerPath := let $headerFile := file:list($headerLocation,fn:true())[fn:ends-with(.,$config:HeaderXml)]
return fn:concat($headerLocation,'/',$headerFile)
let $existingFile := for $uri in fn:uri-collection(fn:concat(blcommon:get-db-name($ct),$config:ContentDir,$contentID,'/'))[fn:contains(.,'/content/latest/')]
[fn:not(fn:contains(.,$config:HeaderXml))]
[fn:not(fn:contains(.,$config:Metadata))]
return fn:substring-before(fn:tokenize($uri,'/')[fn:last()],'.xml')
let $headerXML := copy $c := fetch:xml($headerPath,map{'xinclude':false()})
modify (
for $include in $c//*:include/@href
return
replace value of node $include with fn:replace($include,'.docx','.xml')
)
return $c
return
for $file in $existingFile
return
if($headerXML//*:include/@href[fn:replace(.,'.xml','')=$file])
then
let $coid := fn:concat($contentID,'_',$file)
let $docUri := fn:replace(fn:concat($config:ContentDir,$contentID,'/',$coid,$config:ContentDir,$config:LatestDir,fn:concat($file,'.xml')),'//','/')
let $infoUri := fn:concat($config:ContentDir,$contentID,'/',$coid,'/',$config:InfoXml)
let $infoXml := db:open(blcommon:get-db-name($ct),$infoUri)
return
(
if($infoXml/info/delete/text()='yes')
then
(
delete node $infoXml/info/delete,
audit:update($docUri,$ct,$sessionValue,'Un-Delete')
)
else ()
,
if($headerXML//*:include[fn:replace(@href,'.xml','')=$file][@outputformat='print'])
then
if($infoXml/info[fn:not(content-format)])
then
(
insert node <content-format>PRINT-READY</content-format> into $infoXml/info,
audit:update($docUri,$ct,$sessionValue,'Print-ready')
)
else ()
else ()
,
if($headerXML//*:include[fn:replace(@href,'.xml','')=$file][fn:not(@outputformat)])
then
if($infoXml/info[content-format])
then
(
delete node $infoXml/info/content-format,
audit:update($docUri,$ct,$sessionValue,'remove-print-ready')
)
else ()
else ()
)
else
let $coid := fn:concat($contentID,'_',$file)
let $docUri := fn:replace(fn:concat($config:ContentDir,$contentID,'/',$coid,$config:ContentDir,$config:LatestDir,fn:concat($file,'.xml')),'//','/')
let $infoUri := fn:concat($config:ContentDir,$contentID,'/',$coid,'/',$config:InfoXml)
return
(
if(db:open(blcommon:get-db-name($ct),$infoUri)/info[fn:not(delete)])
then insert node <delete>yes</delete> into db:open(blcommon:get-db-name($ct),$infoUri)/info
else ()
,
audit:update($docUri,$ct,$sessionValue,'Delete')
)
};
(:~
: Create/maintain history of the content.
: @param $cid Content ID
: @param $coid Component ID
: @param $outputFileName File name to save
: @param $inputContent A flag for input content (header/content)
: @return empty sequence
:)
declare %private %updating function contents:create-version(
$ct as xs:string,
$cid as xs:string,
$coid as xs:string,
$outputFileName as xs:string,
$inputContent as xs:string
)
{
let $inputContent := if(fn:replace($outputFileName,'.xml','')='header') then 'Header' else $inputContent
let $versionFileName := let $tstamp := fn:current-dateTime()
let $suffix := fn:format-dateTime($tstamp, "[Y1,4][M01][D01][H01][m01][s01][f01]")
return fn:concat(fn:replace($outputFileName,'.xml',''),'_version_',$suffix,'.xml')
let $latestFileName := if($inputContent='Header')
then $config:HeaderXml
else
if(fn:contains($coid,'_'))
then fn:concat(fn:substring-after($coid,'_'),'.xml')
else fn:concat($coid,'.xml')
let $targetUri := fn:concat($config:ContentDir,$cid,'/',$coid,'/content/latest/',$latestFileName)
let $versionControlUri := fn:concat(blcommon:get-db-name($ct),$cid,'/',$coid,'/',$config:VersionControlFileName)
let $nextVersion := if(fn:doc-available(fn:concat(blcommon:get-db-name($ct),$versionControlUri)))
then fn:sum(fn:max(db:open(blcommon:get-db-name($ct),$versionControlUri)/versions/version/@number) + 1)
else 1
let $versionUri := fn:replace(fn:concat(blcommon:get-db-name($ct),$cid,'/',$coid,$config:ContentDir,$config:VersionDir,'v',$nextVersion,'/',$versionFileName),'//','/')
return
(
(: copy old content into version directory :)
db:replace(blcommon:get-db-name($ct), $versionUri, db:open(blcommon:get-db-name($ct),$targetUri))
,
(: copy old docx into version directory :)
let $wordUri := fn:replace(fn:replace($targetUri,'/content/latest/','/content/latest/word/'),'.xml','.docx')
let $docxVersionUri := fn:replace(fn:concat($config:ContentDir,$cid,'/',$coid,$config:ContentDir,$config:VersionDir,'v',$nextVersion,$config:WordDir,fn:replace($outputFileName,'.xml','.docx')),'//','/')
return
if(db:exists(blcommon:get-db-name($ct),$wordUri))
then db:store(blcommon:get-db-name($ct), $docxVersionUri, db:retrieve(blcommon:get-db-name($ct),$wordUri))
else ()
,
config:update-message("[Content Checkin][Content version is created : " || $versionUri || "]")
,
if(fn:doc-available(fn:concat(blcommon:get-db-name($ct),$versionControlUri)))
then
(
insert node <version number="{$nextVersion}" uri="{$versionUri}" on="{fn:adjust-dateTime-to-timezone(fn:current-dateTime())}"/> into db:open(blcommon:get-db-name($ct),$versionControlUri)/versions,
config:update-message("[Content Checkin][Content version control updated : " || $versionUri || "]")
)
else
db:replace(blcommon:get-db-name($ct),$versionControlUri,<versions><version number="1" uri="{$versionUri}" on="{fn:adjust-dateTime-to-timezone(fn:current-dateTime())}"/></versions>)
)
};
(:~
: To get checkout information
: @param $uri The uri of the files which has been selected to checkin (db uri)
: @param $userID Current User ID who wants to checkin
: @return element (locks)
:)
declare function contents:lock-information(
$uri as xs:string,
$ct as xs:string,
$userID as xs:string
) as element(locks)
{
<locks>
{
let $lockDoc := db:open(blcommon:get-db-name($ct),fn:concat($config:LockDir,$userID,'.xml'))
for $eachUri in fn:tokenize($uri,'\|')
return
<lock>
<uri>{$eachUri}</uri>
{
$lockDoc/locks/lock/files[file/uri=$eachUri]/version,
$lockDoc/locks/lock/files[file/uri=$eachUri]/parent::lock/requester-id,
$lockDoc/locks/lock/files[file/uri=$eachUri]/parent::lock/requester-email
}
</lock>
}
</locks>
};
(:~
: Copy RelaxNG file into temporary directory.
: @return empty sequence
:)
declare %private %updating function contents:copy-relaxng(
$ct as xs:string
)
{
for $file in db:list(blcommon:get-db-name($ct),$config:ValidationDir)[fn:ends-with(fn:lower-case(.),'.rnc')]
let $fileName := fn:tokenize($file,'/')[fn:last()]
return
try
{
file:write-text(fn:concat(file:temp-dir(),$fileName), bin:decode-string(db:retrieve(blcommon:get-db-name($ct),fn:concat($config:ValidationDir,$fileName)),'UTF-8'))
}
catch *
{
admin:write-log("[Copy RelaxNG][Error: " || $err:description || "]"),
admin:write-log("[Copy RelaxNG][Error: " || $err:additional || "]"),
update:output('')
}
};
declare
%rest:path("/headerinfo")
%rest:GET
%rest:query-param("cid", "{$cid}")
%rest:query-param("ct", "{$ct}")
%rest:header-param("Authorization", "{$authorization}", "none")
function contents:get-header-title($cid as xs:string?,
$ct as xs:string,
$authorization as xs:string
)
{
config:session-check($authorization),
try
{
let $headerUri := fn:uri-collection(fn:concat(blcommon:get-db-name($ct),$config:ContentDir))[fn:tokenize(.,'/')[4]=$cid]
[fn:contains(.,$config:HeaderXml)]
[fn:not(fn:contains(.,$config:AuditFileName)
or fn:contains(.,$config:VersionDir)
or fn:contains(.,$config:Metadata))]
let $headerXML := <entities>{fn:doc($headerUri)//*:include}</entities>
return
if(fn:doc($headerUri)//*:include)
then
(
<result><status>Success</status><message>header XML available</message>{$headerXML}</result>,
config:non-update-message("[header xml][header xml has been sent successfully :]")
)
else
(
<result><status>Failure</status><message>header xml unavailable</message></result>,
admin:write-log("[header xml][header xml unavailable :]")
)
}
catch *
{
admin:write-log("[Content Search][Error: " || $err:description || "]"),
admin:write-log("[Content Search][Error: " || $err:additional || "]"),
<result><status>Error</status><message>Error generated. Please check system log</message></result>
}
};
declare
%rest:path("/title")
%rest:GET
%rest:header-param("Authorization", "{$authorization}", "none")
function contents:get-title(
$authorization as xs:string
)
{
config:session-check($authorization),
try
{
let $HeaderUri := for $db in db:list()[not( contains(.,$config:CoreDatabase) or contains(.,$config:ContentManagementDatabase) or contains(.,$config:AuditDatabase) or contains(.,$config:ContentMetadataDatabse) or contains(.,$config:URLsDatabse))]
for $uri in fn:uri-collection(fn:concat($db,'/content/'))[(contains(.,'header.xml')
and contains(.,'/content/latest/'))]
[fn:not(fn:contains(.,$config:AuditFileName)
or fn:contains(.,$config:VersionControlFileName)
or fn:contains(.,$config:InfoXml)
or fn:contains(.,$config:VersionDir)
or fn:contains(.,$config:Metadata)
)]
return $uri
let $TitleRecords := for $result in $HeaderUri
for $headerdoc in fn:doc($result)
let $title := <title>{$headerdoc/*:book/*:info/*:title/text()}</title>
let $cid := <cid>{fn:tokenize($result,'/')[4]}</cid>
let $coid := <coid>{fn:tokenize($result,'/')[5]}</coid>
let $ctype := <ctype>{fn:collection(fn:concat($config:CoreDatabase,'/jobs/'))/job[job-info/job-type='Ingest'][fn:contains(job-info/cid,$cid)]/job-info/content-type/string()}</ctype>
return
<content>{$title,$cid,$coid,$ctype}</content>
return
if($TitleRecords)
then
<result>
<status>Success</status>
<entities>{$TitleRecords}</entities>
</result>
else
<result>
<status>Success</status>
<message>Records not found</message>
</result>
}
catch *
{
admin:write-log("[Content Search][Error: " || $err:description || "]"),
admin:write-log("[Content Search][Error: " || $err:additional || "]"),
<result><status>Error</status><message>Error generated. Please check system log</message></result>
}
};
declare
%rest:path("/browsechunk")
%rest:GET
%rest:query-param("ct", "{$ct}")
%rest:query-param("cid", "{$cid}")
%rest:query-param("page", "{$page}")
%rest:query-param("size", "{$size}")
%rest:header-param("Authorization", "{$authorization}", "none")
function contents:browse-chunk($cid as xs:string?,
$ct as xs:string,
$page as xs:integer?,
$size as xs:integer?,
$authorization as xs:string
)
{
config:session-check($authorization),
try
{
let $page := if($page) then $page else $config:page
let $size := if($size) then $size else $config:size
let $start := if($page eq 1)
then $page
else if($page gt 1)
then fn:sum(($page * $size)+1) - $size
else fn:sum(($page * $size)) - $size
let $end := if($page eq 1)
then $size
else if($page gt 1)
then fn:sum(($start + $size)-1)
else fn:sum($start + $size)
let $result :=
for $uri in fn:uri-collection(fn:concat(blcommon:get-db-name($ct),$config:ContentDir))[fn:tokenize(.,'/')[4]=$cid]
[fn:not(fn:contains(.,$config:AuditFileName)
or fn:contains(.,$config:VersionControlFileName)
or fn:contains(.,$config:InfoXml)
or fn:contains(.,$config:VersionDir)
or fn:contains(.,$config:HeaderXml)
or fn:contains(.,$config:Metadata)
)]
let $doc := fn:doc($uri)
return
if($ct='play')
then
for $div in $doc//*:div[@type='play']
let $title := <title>{if($div/*:head/text()!='') then $div/*:head/text() else $div/ancestor::*:TEI/*:teiHeader/*:fileDesc/*:titleStmt/*:title[1]/data()}</title>
let $chunkid := data($div/@xml:id)
let $coid := fn:tokenize($uri,'/')[5]
return <content>{$title,<cid>{$cid}</cid>,<coid>{$coid}</coid>,<chunkid>{$chunkid}</chunkid>,<uri>{$uri}</uri>,<content-type>{$ct}</content-type>}</content>
else if($ct='monograph')
then
for $chunk in fn:doc($uri)/(*:book//(*:chapter|*:acknowledgements|*:preface|*:index | *:appendix | *:toc | *:dedication | *:article | *:section[@role='subArticle'])|*:book/*:glossary|*:book/bibliography|*:book/*:part[*:partintro]|*:book/*:part/(*:glossary|*:bibliography))
let $title := <title>{($chunk//*:title)[1]//text()}</title>
let $chunkid := data($chunk/@xml:id)
let $coid := fn:tokenize($uri,'/')[5]
return <content>{$title,<cid>{$cid}</cid>,<coid>{$coid}</coid>,<chunkid>{$chunkid}</chunkid>,<uri>{$uri}</uri>,<content-type>{$ct}</content-type>}</content>
else()
return
if($result!='')
then
(
for $uri in fn:uri-collection(fn:concat(blcommon:get-db-name($ct),$config:ContentDir))[fn:tokenize(.,'/')[4]=$cid]
[fn:not(fn:contains(.,$config:AuditFileName)
or fn:contains(.,$config:VersionControlFileName)
or fn:contains(.,$config:InfoXml)
or fn:contains(.,$config:VersionDir)
or fn:contains(.,$config:HeaderXml)
or fn:contains(.,$config:Metadata)
)]
let $doc := fn:doc($uri)
return
if($ct='play')
then
let $componentTitle := $doc/*:TEI/*:teiHeader/*:fileDesc/*:titleStmt/*:title[not(@type = 'sub')]/string()
let $coid := <coid>{fn:tokenize($uri,'/')[5]}</coid>
order by $componentTitle
return
<result>
<status>Success</status>
<total>{fn:count($result)}</total>
<entities>
<content>
{$coid}
<title>{$componentTitle}</title>
<cid>{$cid}</cid>
{$result[position()= $start to $end]}
</content>
</entities>
</result>
else if($ct='monograph')
then
let $componentTitle := $doc/*:book/*:info/*:title/string()
let $coid := <coid>{fn:tokenize($uri,'/')[5]}</coid>
order by $componentTitle
return
<result>
<status>Success</status>
<total>{fn:count($result)}</total>
<entities>
<content>
{$coid}
<title>{$componentTitle}</title>
<cid>{$cid}</cid>
{$result[position()= $start to $end]}
</content>
</entities>
</result>
else()
)
else
<result>
<status>Success</status>
<message>Records not found</message>
</result>
}
catch *
{
admin:write-log("[Content Search][Error: " || $err:description || "]"),
admin:write-log("[Content Search][Error: " || $err:additional || "]"),
<result><status>Error</status><message>Error generated. Please check system log</message></result>
}
};
declare
%rest:path("/browsemetadataonly")
%rest:GET
%rest:query-param("ct", "{$ct}")
%rest:query-param("page", "{$page}")
%rest:query-param("size", "{$size}")
%rest:header-param("Authorization", "{$authorization}", "none")
function contents:browse-metadata-only(
$ct as xs:string,
$page as xs:integer?,
$size as xs:integer?,
$authorization as xs:string
)
{
config:session-check($authorization),
try
{
let $page := if($page) then $page else $config:page
let $size := if($size) then $size else $config:size
let $start := if($page eq 1)
then $page
else if($page gt 1)
then fn:sum(($page * $size)+1) - $size
else fn:sum(($page * $size)) - $size
let $end := if($page eq 1)
then $size
else if($page gt 1)
then fn:sum(($start + $size)-1)
else fn:sum($start + $size)
let $result :=
let $Uris:=
( for $uri in fn:uri-collection(fn:concat($config:MetadataOnlyContentDatabase,'/',$ct))[fn:contains(.,$ct)]
[fn:not(fn:contains(.,'metadata.xml') or
fn:contains(.,'version')
or fn:contains(.,$config:ClassifyXml)
)]
let $title := <title>{fn:doc($uri)/*/*:item_title}</title>
order by upper-case($title)
return $uri
)[position()= $start to $end]
for $Uri in $Uris
let $doc := fn:doc($Uri)
let $records :=
for $items in $doc/*
let $title := <title>{$items/*:item_title//text()}</title>
let $cid := <cid>{$items/@id/string()}</cid>
let $coid := <coid>{fn:concat($cid ,'_', $cid)}</coid>
return (<content>{$title,$cid,$coid}</content>)
return $records
return
if($result!='')
then
(
let $totaluri := for $uri in fn:uri-collection(fn:concat($config:MetadataOnlyContentDatabase,'/',$ct))[fn:contains(.,$ct)]
[fn:not(fn:contains(.,'metadata.xml') or
fn:contains(.,'version')
or fn:contains(.,$config:ClassifyXml)
)
]
return $uri
return
<result>
<status>Success</status>
<total>{fn:count($totaluri)}</total>
<entities>
{$result}
</entities>
</result>
)
else
<result>
<status>Success</status>
<message>Records not found</message>
</result>
}
catch *
{
admin:write-log("[Content Search][Error: " || $err:description || "]"),
admin:write-log("[Content Search][Error: " || $err:additional || "]"),
<result><status>Error</status><message>Error generated. Please check system log</message></result>
}
};