teacup/metadata.xqm

1570 lines
76 KiB
Plaintext

(:~
: Metadata Library.
:
: @author Rave Technologies, https://www.rave-tech.com/, 2017
:)
module namespace metadata = 'http://www.rave-tech.com/bloomsbury/metadata';
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 blcommon = 'http://www.rave-tech.com/bloomsbury/common' at 'common.xqm';
declare namespace clist = 'http://cms.bloomsbury.com/content-type';
declare namespace classify = 'http://cms.bloomsbury.com/classify';
(:~
: Add metadata into the system.
: @param $body metadata XML as document node <metadata><state></state><content-metadata></content-metadata><taxonomies></taxonomies></metadata>
: @param $cid Content ID
: @param $coid Component ID
: @header $authorization Authorization key
: @return element(result)
:)
declare
%updating
%rest:path("/content-metadata/{$ctype=[^/]+}/{$cid=[^/]+}/{$coid=[^/]+}")
%rest:POST("{$body}")
%rest:header-param("Authorization", "{$authorization}", "none")
%rest:consumes("application/xml", "text/xml")
function metadata:add(
$ctype as xs:string,
$cid as xs:string,
$coid as xs:string?,
$body as document-node(),
$authorization as xs:string
)
{
config:session-check($authorization),
try
{
let $meta := let $state := $body/metadata/state
let $meta := $body/metadata/content-metadata
return
<metadata id="{if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase)) then fn:concat($cid,'_',$coid) else $cid}">
{
$state,
let $result := for $node in $meta/*
let $nodename := fn:local-name($node)
return
if($nodename='item')
then
if($node/option)
then
for $option in $node/option[@selected='true']
return
element {$option/@name}
{
$option/@value/string()
}
else if($node/RelatedContents)
then
$node/RelatedContents
else element {$node/@name} {$node/@value/string()}
else if($nodename='group')
then
element {$node/@name/string()} {attribute title{'title'},
for $subgroup in $node/*:subgroup
return element{$subgroup/@name/string()}
{
for $item in $subgroup/*:item
return
if($item/*:option[@selected='true'])
then
element{$item/option[@selected='true']/@name/string()}
{
$item/*:option[@selected='true']/@value/string()
}
else if(not($item/*:option))
then
element {$item/@name/string()} {$item/@value/string()}
else()
}
}
else()
return $result
}
</metadata>
(:let $taxonomy := $body/metadata/taxonomies:)
let $userid := fn:substring-before(config:session-value($authorization),'$$$$')
let $userEmail := db:open($config:CoreDatabase,fn:concat($config:UserDir,$userid,'.xml'))/user/email/string()
let $Taxonomies := if ($body/metadata/taxonomies!='')
then
copy $c := $body/metadata/taxonomies
modify
(
insert node (attribute {'cid'} {$cid }) into $c,
for $taxonoy in $c/taxonomy
return
insert node (attribute{'who'}{$userid},attribute{'when'}{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}) into $taxonoy
)
return $c
else $body/metadata/taxonomies
let $state := $body/metadata/state
(:let $targetURI := fn:concat($config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,$coid,'_',$config:MetaXml) :)
let $targetURI := if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then
fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,$coid,'_',$config:MetaXml)
else
fn:concat('/',$ctype,'/',$cid,$config:Metadata,$config:LatestDir,$cid,'_',$config:MetaXml)
let $infoUri := if(($ctype = $config:LooseleafDatabase ) or ($ctype = $config:playDatabase ) or ($ctype=$config:MonographDatabase )) then fn:concat($config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml) else()
return
(:Step 1: Check if Metadata is already exist :)
if( fn:doc-available(fn:concat($config:ContentMetadataDatabse,fn:concat('/',$ctype,$targetURI))))
then
(
update:output(<result><status>Failure</status><message>Metadata is already available</message></result>),
config:update-message("[Metadata Add][Metadata is already available : " || $coid || "]")
)
else
(
db:replace($config:ContentMetadataDatabse ,$targetURI,$meta)
,
if(($ctype = $config:LooseleafDatabase ) or ($ctype = $config:playDatabase ) or ($ctype = $config:MonographDatabase ))
then
db:replace($config:ContentMetadataDatabse,fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,$coid,'_',$config:ClassifyXml),$Taxonomies)
else if( ($ctype = $config:Audio) or ($ctype = $config:Person) or ($ctype = $config:Image)
or ($ctype= $config:Video) or ($ctype = $config:Organisation)
or ($ctype = $config:Publisher) or ($ctype = $config:Series))
then
db:replace($config:ContentMetadataDatabse,fn:concat('/',$ctype,'/',$cid,$config:Metadata,$config:LatestDir,$cid,'_',$config:ClassifyXml),$Taxonomies)
else(),
if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase ) or ($ctype = $config:MonographDatabase))
then
audit:add-update-metadata($ctype,$cid,$coid, 'Add metadata',config:session-value($authorization))
else()
,
if(($ctype= $config:LooseleafDatabase ) or ($ctype = $config:playDatabase ) or ($ctype = $config:MonographDatabase))
then
config:update-message("[Metadata Add][Metadata added into the system : " || $coid || "]")
else()
,
update:output(<result><status>Success</status><message>Metadata added into the system</message></result>)
)
}
catch *
{
admin:write-log("[Metadata Add][Error: " || $err:description || "]"),
admin:write-log("[Metadata Add][Error: " || $err:additional || "]"),
update:output(<result><status>Error</status><message>Error generated. Please check system log</message></result>)
}
};
(:~
: Update metadata into the system.
: @param $body metadata XML as document node <metadata>....</<metadata>
: @param $cid Content ID
: @param $coid Component ID
: @header $authorization Authorization key
: @return element(result)
:)
declare
%updating
%rest:path("/content-metadata/{$ctype=[^/]+}/{$cid=[^/]+}/{$coid=[^/]+}")
%rest:PUT("{$body}")
%rest:header-param("Authorization", "{$authorization}", "none")
%rest:consumes("application/xml", "text/xml")
function metadata:update(
$ctype as xs:string,
$cid as xs:string,
$coid as xs:string,
$body as document-node(),
$authorization as xs:string
)
{
config:session-check($authorization),
try
{
let $meta := let $state := $body/metadata/state
let $meta := $body/metadata/content-metadata
return
<metadata id="{if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase)) then fn:concat($cid,'_',$coid) else $cid}">
{ $state,
let $result := for $node in $meta/*
let $nodename := fn:local-name($node)
return
if($nodename='item')
then
if($node/option)
then
for $option in $node/option[@selected='true']
return
element {$option/@name}
{
$option/@value/string()
}
else if($node/RelatedContents)
then
$node/RelatedContents
else element {$node/@name} {$node/@value/string()}
else if($nodename='group')
then
element {$node/@name/string()} {attribute title{'title'},
for $subgroup in $node/*:subgroup
return element{$subgroup/@name/string()}
{
for $item in $subgroup/*:item
return
if($item/*:option[@selected='true'])
then
element{$item/option[@selected='true']/@name/string()}
{
$item/*:option[@selected='true']/@value/string()
}
else if(not($item/*:option))
then
element {$item/@name/string()} {$item/@value/string()}
else()
}
}
else()
return $result
}
</metadata>
(:let $taxonomy := $body/metadata/taxonomies:)
let $userid := fn:substring-before(config:session-value($authorization),'$$$$')
let $userEmail := db:open($config:CoreDatabase,fn:concat($config:UserDir,$userid,'.xml'))/user/email/string()
let $Taxonomies := if ($body/metadata/taxonomies!='')
then
copy $c := $body/metadata/taxonomies
modify
(
insert node (attribute {'cid'} {$cid}) into $c,
for $taxonoy in $c/taxonomy
return
insert node (attribute{'who'}{$userid},attribute{'when'}{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}) into $taxonoy
)
return $c
else $body/metadata/taxonomies
let $state := $body/metadata/state
let $targetURI := if(($ctype = $config:LooseleafDatabase ) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then
fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,$coid,'_',$config:MetaXml)
else
fn:concat('/',$ctype,'/',$cid,$config:Metadata,$config:LatestDir,$cid,'_',$config:MetaXml)
let $ClassifyURI := if(($ctype = $config:LooseleafDatabase ) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then
fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,'latest/',$coid,'_',$config:ClassifyXml)
else
fn:concat('/',$ctype,'/',$cid,$config:Metadata,$config:LatestDir,$cid,'_',$config:ClassifyXml)
let $infoUri := if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase)) then fn:concat($config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml) else()
return
(:Step 1: Check if Metadata is already exist :)
if( fn:doc-available(fn:concat($config:ContentMetadataDatabse,$targetURI)) or fn:doc-available(fn:concat($config:ContentMetadataDatabse,$ClassifyURI)))
then
(
update:output(<result><status>Success</status><message>Metadata Updated into the system</message></result>)
,
metadata:create-version($ctype,(),$cid,$coid,())
,
db:replace($config:ContentMetadataDatabse ,$targetURI,$meta)
,
if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then
if($Taxonomies!='')
then
db:replace($config:ContentMetadataDatabse,fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,$coid,'_',$config:ClassifyXml),$Taxonomies)
else()
else if( ($ctype = $config:Audio) or ($ctype = $config:Person) or ($ctype = $config:Image)
or ($ctype = $config:Video) or ($ctype = $config:Organisation)
or ($ctype = $config:Publisher) or ($ctype = $config:Series))
then
db:replace($config:ContentMetadataDatabse,fn:concat('/',$ctype,'/',$cid,$config:Metadata,$config:LatestDir,$cid,'_',$config:ClassifyXml),$Taxonomies)
else()
,
if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then
audit:add-update-metadata($ctype,$cid,$coid, 'Update metadata',config:session-value($authorization))
else()
)
else
(
update:output(<result><status>Failure</status><message>Metadata is not available to update</message></result>),
config:update-message("[Metadata Update][Metadata is not available to update : " || $coid || "]")
)
}
catch *
{
admin:write-log("[Metadata Add][Error: " || $err:description || "]"),
admin:write-log("[Metadata Add][Error: " || $err:additional || "]"),
update:output(<result><status>Error</status><message>Error generated. Please check system log</message></result>)
}
};
(:~
: To get latest content metadata information.
: @param $cid Content ID
: @param $coid Component ID
: @header $authorization Authorization key
: @return element(result)
:)
declare
%rest:path("/content-metadata")
%rest:GET
%rest:query-param("ctype", "{$ctype}")
%rest:query-param("type", "{$type}")
%rest:query-param("cid", "{$cid}")
%rest:query-param("coid", "{$coid}")
%rest:query-param("chunkid", "{$chunkid}")
%rest:header-param("Authorization", "{$authorization}", "none")
function metadata:get-configuration(
$ctype as xs:string,
$type as xs:string,
$cid as xs:string,
$coid as xs:string?,
$chunkid as xs:string?,
$authorization as xs:string
)
{
config:session-check($authorization),
try
{ if($cid!='' or $coid!='')
then
let $uri := if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then
fn:uri-collection(fn:concat(blcommon:get-db-name($ctype),$config:ContentDir,$cid,'/',$coid))[fn:contains(.,$config:InfoXml)]
else ()
let $ctype := if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase)) then fn:doc($uri)/info/ctype/text() else $ctype
let $ContentTypeXml := db:open($config:CoreDatabase,$config:ContentType)
let $metaTemplate := if($type='volume') then $ContentTypeXml/clist:controlledList/clist:name[@xml:id=$ctype]/@volume-meta-template/string()
else $ContentTypeXml/clist:controlledList/clist:name[@xml:id=$ctype]/@chunk-meta-template/string()
return
if($metaTemplate!='')
then
if(db:exists($config:CoreDatabase,fn:concat($config:ConfigDir,$metaTemplate)))
then
let $metaUri := if($type='volume')
then
if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,'latest/',$coid,'_',$config:MetaXml)
else fn:concat('/',$ctype,'/',$cid,$config:Metadata,$config:LatestDir,$cid,'_',$config:MetaXml)
else fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,'latest/',if($chunkid) then $chunkid else $coid,'_',$config:MetaXml)
let $classifyUri := if($type='volume')
then
if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,'latest/',$coid,'_',$config:ClassifyXml)
else fn:concat('/',$ctype,'/',$cid,$config:Metadata,$config:LatestDir,$cid,'_',$config:ClassifyXml)
else fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,'latest/',if($chunkid) then $chunkid else $coid,'_',$config:ClassifyXml)
return
if( db:exists($config:ContentMetadataDatabse,$metaUri))
then
let $metaDoc := db:open($config:ContentMetadataDatabse,$metaUri)
let $metaTemplate := db:open($config:CoreDatabase,fn:concat($config:ConfigDir,$metaTemplate))
let $state := $metaDoc/metadata/state/string()
let $metaContent :=
for $node in $metaTemplate/formTemplate/*
let $nodename := fn:local-name($node)
return
if($nodename='item')
then
for $item in $node[fn:not(@name="taxonomy")]
let $xpath := if($item/@name='RelatedContents')
then "fn:doc('bloomsbury/config/content-types.xml')/*:controlledList/*:name/@xml:id"
else $item/@xpath/string()
return
(
element item {
for $att in $item/@*[fn:not(fn:name()='xpath')]
return
attribute {fn:local-name($att)} {$att},
attribute value {if($item/@type='relatedcontent') then () else $metaDoc/metadata/*[name()=$item/@name]},
if(($item/@type='checkbox') or ($item/@type='dropdown') or ($item/@type='relatedcontent') or ($item/@type='content-type-dropdown'))
then
let $docUri := if(($ctype='looseleaf' ) or ($ctype='play' ) or ($ctype='monograph' ))
then
fn:uri-collection(fn:concat(blcommon:get-db-name($ctype),$config:ContentDir,$cid,'/',$coid,'/content/latest/'))
else fn:uri-collection(fn:concat($config:MetadataOnlyContentDatabase,'/',$ctype,'/',$cid))[fn:not(fn:contains(.,'metadata')
)]
let $doc := fn:doc($docUri)
let $value := metadata:get-path($xpath,$doc)
let $ControledListPath := if($item/@ControlledList) then $item/@ControlledList/string() else ()
let $ControledListDoc := if($ControledListPath!='') then metadata:get-item-ControledList($ControledListPath) else()
let $ItemValue := $item/@ItemValue/string()
let $ItemText := $item/@ItemText/string()
let $xpath := '/*:controlledList/*'
for $name in metadata:get-path($xpath,$ControledListDoc)
return
element option {attribute name{$item/@name/string()},
attribute value {$name/@*[name()=$ItemValue]/string()},
attribute title {$name/@*[name()=$ItemText]/string()},
attribute selected{if($item/@type='relatedcontent') then 'false' else if(fn:matches(string-join($name/@*[name()=$ItemValue]/string(),'|'),$metaDoc/metadata/*[name()=$item/@name]/string())) then 'true' else 'false'},
if($item/@type='relatedcontent')
then
attribute metadata {if(
($name/@*[name()=$ItemValue]/string()='audio') or ($name/@*[name()=$ItemValue]/string()='video') or
($name/@*[name()=$ItemValue]/string()='person') or ($name/@*[name()=$ItemValue]/string()='organisation')or
($name/@*[name()=$ItemValue]/string()='image') or ($name/@*[name()=$ItemValue]/string()='publisher') or
($name/@*[name()=$ItemValue]/string()='series')
) then 'true' else 'false'
}
else()
}
else(),
if($item/@type='relatedcontent')
then
$metaDoc/metadata/RelatedContents
else if($item/@type='content-type-dropdown')
then
if($metaDoc/metadata/*[name()=$item/@name]/string()!='')
then
element option {attribute name{$item/@name/string()},
attribute value {$metaDoc/metadata/*[name()=$item/@name]/string()},
attribute title {$item/@title/string()},
attribute selected{if($metaDoc/metadata/*[name()=$item/@name]/string()!='') then 'true' else 'false'}
}
else()
else()
}
)
else if($nodename='group')
then
let $group := $node
return
element group { for $att in $group/@*[fn:not(fn:local-name(.)='xpath' or fn:local-name(.)='subgroup' or fn:local-name(.)='docstructure') ]
return
attribute {fn:local-name($att)} {$att},
let $docUri := if(($ctype='looseleaf' ) or ($ctype='play' ))
then
fn:uri-collection(fn:concat(blcommon:get-db-name($ctype),$config:ContentDir,$cid,'/',$coid,'/content/latest/'))
else fn:uri-collection(fn:concat($config:MetadataOnlyContentDatabase,'/',$ctype,'/',$cid))[fn:not(fn:contains(.,'metadata')
)]
let $doc := fn:doc($docUri)
return
let $groupName := $group/@name/string()
let $subgroupname := $group/@subgroup/string()
let $xpath := fn:concat('/metadata/',$groupName)
for $values in metadata:get-path($xpath,$metaDoc)
for $items in $values/*
return
element subgroup
{ attribute name{$subgroupname},
for $item in $group/*:item[fn:not(@name="taxonomy")]
let $ControledListPath := $item/@ControlledList/string()
return
element item
{
for $att in $item/@*[fn:not(fn:name()='xpath' or fn:name()='ControlledList')]
return
attribute {fn:local-name($att)} {$att},
if($item/@type='dropdown' or $item/@type='checkbox')
then
let $ControledListPath := $item/@ControlledList/string()
let $ControledListDoc := metadata:get-item-ControledList($ControledListPath)
let $ItemValue := $item/@ItemValue/string()
let $ItemText := $item/@ItemText/string()
let $xpath := '/*:controlledList/*'
for $name in metadata:get-path($xpath,$ControledListDoc)
return element option{
attribute name{$item/@name/string()},
attribute value {$name/@*[name()=$ItemValue]/string()},
attribute title {$name/@*[name()=$ItemText]/string()},
(:attribute selected{if($items/*[name()=$item/@name]!='') then if (fn:matches(string-join($name/@*[name()=$ItemValue]/string(),'|'),$items/*[name()=$item/@name])) then 'true' else 'false' else 'false'}:)
attribute selected{if($items/*[name()=$item/@name]!='') then if ($name/@*[name()=$ItemValue]/string()=$items/*[name()=$item/@name]) then 'true' else 'false' else 'false'}
}
else if($item/@type='content-type-dropdown')
then
element option{
attribute name{$item/@name/string()},
attribute title{$item/@title/string()},
attribute value {$items/*[name()=$item/@name]},
attribute selected{if($items/*[name()=$item/@name]!='') then 'true' else 'false'}
}
else
attribute value {$items/*[name()=$item/@name]}
}
}
}
else()
return
<results>
<result>
<status>Success</status>
<isMetadataExist>{if( db:exists($config:ContentMetadataDatabse,$metaUri)) then 'yes' else 'no'}</isMetadataExist>
<metadata>
<state>{$state}</state>
<content-metadata>{$metaContent}</content-metadata>
{
let $classify:= if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then db:open($config:ContentMetadataDatabse,$classifyUri)
else db:open($config:ContentMetadataDatabse,$classifyUri)
let $TaxonomyFacetXml := <taxonomies>{
for $taxonomy in $classify/*:taxonomies/*:taxonomy
let $taxonomyid := $taxonomy/@id/string()
let $taxonomydoc := db:open($config:CoreDatabase,fn:concat($config:TaxonomyDir,$taxonomyid,'.xml'))
return
<taxonomy id="{$taxonomyid}" who="{$taxonomy/@who/string()}" when="{$taxonomy//@when/string()}">
{
for $facet in $taxonomy/*:facet/string()
return
<classify:facet group="{$taxonomydoc/*:taxonomy/*:facet[descendant::*:facet/@xml:id=$facet]/@xml:id}">
{
$facet
}
</classify:facet>
}
</taxonomy>
}
</taxonomies>
let $TaxonomyGroupXml := <taxonomies>
{
for $taxonomy in $TaxonomyFacetXml/*:taxonomy
return
element {local-name($taxonomy)}
{
attribute id{$taxonomy/@id/string()},attribute who{$taxonomy/@who/string()},attribute when{$taxonomy/@when/string()},
for $facets in $taxonomy/*:facet
let $group := $facets/@group
group by $group
return <classify:facets group="{$group}">
{
$facets
}
</classify:facets>
}
}
</taxonomies>
return $TaxonomyGroupXml
}
</metadata>
</result>
</results>
else
let $templateDoc := db:open($config:CoreDatabase,fn:concat($config:ConfigDir,$metaTemplate))
let $docUri := if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then fn:uri-collection(fn:concat(blcommon:get-db-name($ctype),$config:ContentDir,$cid,'/',$coid,'/content/latest/'))[fn:not(contains(.,'metadata.xml') or contains(.,'classify.xml'))][fn:not(contains(.,'/version/') or contains(.,'version.xml'))]
else fn:uri-collection(fn:concat($config:MetadataOnlyContentDatabase,'/',$ctype,'/',$cid))[fn:not(contains(.,'metadata.xml') or contains(.,'classify.xml'))][fn:not(contains(.,'/version/') or contains(.,'version.xml'))]
let $doc := fn:doc($docUri)
return
if(db:exists(blcommon:get-db-name($ctype),fn:substring-after($docUri,blcommon:get-db-name($ctype))) or db:exists($config:MetadataOnlyContentDatabase,substring-after($docUri,$config:MetadataOnlyContentDatabase)))
then
let $stateUri := fn:concat($config:CoreDatabase,$config:StatusFile)
let $state := fn:doc($stateUri)/*:workflow/*:status/@xml:id[.='publishable']/string()
let $MetaTemplateValidation :=
let $result :=
for $node in $templateDoc/formTemplate/*
let $nddname := name($node)
return
if($nddname='group')
then
let $group := $node
return
if($node/@subgroup)
then
let $subgroupname := $node/@subgroup/string()
let $IssubgroupnameSameAsItem := for $item in $node/item
return
if($item/@name/string()=$subgroupname) then 'true' else 'false'
return
if(fn:matches( string-join($IssubgroupnameSameAsItem,'|') ,'true') )
then
<result><status>Failure</status><message>{fn:concat('Group',' ',$group/@name/string(),' ', 'Item name should not be as subgroup name.')}</message></result>
else ()
else <result><status>Failure</status><message>{fn:concat('Group' ,' ',$group/@name/string() , ' ', 'must contains attribute subgroup.')}</message></result>
else()
return $result
let $validationstatus := string-join($MetaTemplateValidation/status,'|')
return
if(fn:matches($validationstatus,'Failure','i'))
then <results>{$MetaTemplateValidation}</results>
else
let $metaContent := (
let $result := for $node in $templateDoc/formTemplate/*
let $nodename := fn:local-name($node)
return
if($nodename='item')
then
for $item in $node[fn:not(@name="taxonomy")]
let $xpath := if($item/@name='play_title')
then
fn:concat( substring-before($item/@xpath/string(),'/*:head') , '[','@xml:id=',"'",$chunkid,"'",']',substring-after($item/@xpath/string() ,']'))
else if($item/@name='chunktitle')
then
fn:concat( substring-before($item/@xpath/string(),'/*:info/*:title') , ' [','@xml:id=',"'",$chunkid,"'",']',substring-after($item/@xpath/string() ,'bibliography))'))
else if($item/@name='chunkid')
then
fn:concat( substring-before($item/@xpath/string(),'/@*:id/string()') , ' [','@xml:id=',"'",$chunkid,"'",']',substring-after($item/@xpath/string() ,'bibliography))'))
else if($item/@name='doi' and $type="chunk")
then
fn:concat( substring-before($item/@xpath/string(),'/*:info/*:biblioid') , ' [','@xml:id=',"'",$chunkid,"'",']',substring-after($item/@xpath/string() ,'bibliography))'))
else $item/@xpath/string()
let $value := metadata:get-path($xpath,$doc)
return
(
element item {
for $att in $item/@*[fn:not(fn:name()='xpath' or fn:name()='ControlledList')]
return
attribute {fn:local-name($att)} {$att},
attribute value { if(($item/@type='dropdown') or ($item/@type='checkbox') or ($item/@type='relatedcontent')) then() else if($item/@name='territorialrestriction') then fn:normalize-space(fn:string-join(data($value), ' ')) else fn:normalize-space(fn:string-join(data($value), ' '))},
if(($item/@type='dropdown') or ($item/@type='checkbox') or ($item/@type='relatedcontent'))
then
(:for $eachitems in $value:)
let $ControledListPath := if($item/@ControlledList) then $item/@ControlledList/string() else ()
let $ControledListDoc := if($ControledListPath!='') then metadata:get-item-ControledList($ControledListPath) else()
let $ItemValue := $item/@ItemValue/string()
let $ItemText := $item/@ItemText/string()
let $xpath := '/*:controlledList/*'
for $name in metadata:get-path($xpath,$ControledListDoc)
return
element option {attribute name{$item/@name/string()},
attribute value {$name/@*[name()=$ItemValue]/string()},
attribute title {$name/@*[name()=$ItemText]/string()},
attribute selected{if($value!='') then if(fn:matches(string-join($name/@*[name()=$ItemValue]/string(),'|'),$value)) then 'true' else 'false' else 'false'},
if($item/@type='relatedcontent')
then
attribute metadata {if(
($name/@*[name()=$ItemValue]/string()='audio') or ($name/@*[name()=$ItemValue]/string()='video') or
($name/@*[name()=$ItemValue]/string()='person') or ($name/@*[name()=$ItemValue]/string()='organisation')or
($name/@*[name()=$ItemValue]/string()='image') or ($name/@*[name()=$ItemValue]/string()='publisher') or
($name/@*[name()=$ItemValue]/string()='series')
) then 'true' else 'false'
}
else()
}
else()
}
)
else if($nodename='group')
then
let $group := $node
return
element group { for $att in $group/@*[fn:not(fn:local-name(.)='xpath' or fn:local-name(.)='subgroup' or fn:local-name(.)='docstructure') ]
return
attribute {fn:local-name($att)} {$att},
let $groupxpath := $group/@xpath/string()
let $seq :=
if(metadata:get-path($group/@xpath/string(),$doc))
then
metadata:get-path($group/@xpath/string(),$doc)
else ""
for $value at $pos in $seq
return
element subgroup { attribute {fn:local-name($group/@name)} {if($group/@subgroup) then $group/@subgroup/string() else $group/@name},
for $item in $group/*:item
let $xpath :=
if($item/@xpath/string()='.')
then $groupxpath
else if(fn:contains(lower-case($item/@xpath/string()),'sibling'))
then concat($groupxpath,'/', $item/@xpath/string())
else if(
(
fn:contains(lower-case($item/@xpath/string()),'let ') or
fn:contains(lower-case($item/@xpath/string()),'fn:doc') or
fn:contains(lower-case($item/@xpath/string()),'fn:collection')
)
)
then $item/@xpath/string()
else concat($groupxpath,'/', $item/@xpath/string())
let $value := metadata:get-path($xpath,$doc)[$pos]
return
element item
{
for $att in $item/@*[fn:not(fn:name()='xpath' or fn:name()='ControlledList')]
return
attribute {fn:local-name($att)} {$att},
attribute value{$value[not( ($item/@type='dropdown') or ($item/@type='content-type-dropdown') or ($item/@type='checkbox') or ($item/@type='relatedcontent') )]},
if( ($item/@type='dropdown') or ($item/@type='checkbox') or ($item/@type='relatedcontent') )
then
let $ControledListPath := $item/@ControlledList/string()
let $ControledListDoc := metadata:get-item-ControledList($ControledListPath)
let $ItemValue := $item/@ItemValue/string()
let $ItemText := $item/@ItemText/string()
let $xpath := '/*:controlledList/*'
for $name in metadata:get-path($xpath,$ControledListDoc)
return element option{
attribute name{$item/@name/string()},
attribute value {$name/@*[name()=$ItemValue]/string()},
attribute title {$name/@*[name()=$ItemText]/string()},
attribute selected{if ($item/@xpath!='')then if(fn:matches(string-join($value,'|'),$name/@*[name()=$ItemValue]/string())) then 'true' else 'false' else 'false'}
}
else()
}
}
}
else()
return $result
)
return
<results>
<result>
<status>Success</status>
<isMetadataExist>{if(db:exists($config:ContentMetadataDatabse,$metaUri) or db:exists($config:ContentMetadataDatabse,$classifyUri)) then 'yes' else 'no'}</isMetadataExist>
<metadata>
<state>{$state}</state>
<content-metadata>{$metaContent}</content-metadata>
{let $classify:= if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then db:open($config:ContentMetadataDatabse,$classifyUri)
else db:open($config:ContentMetadataDatabse,$classifyUri)
let $TaxonomyFacetXml := <taxonomies>{
for $taxonomy in $classify/*:taxonomies/*:taxonomy
let $taxonomyid := $taxonomy/@id/string()
let $taxonomydoc := db:open($config:CoreDatabase,fn:concat($config:TaxonomyDir,$taxonomyid,'.xml'))
return
<taxonomy id="{$taxonomyid}" who="{$taxonomy/@who/string()}" when="{$taxonomy//@when/string()}">
{
for $facet in $taxonomy/*:facet/string()
return
<classify:facet group="{$taxonomydoc/*:taxonomy/*:facet[descendant::*:facet/@xml:id=$facet]/@xml:id}">
{
$facet
}
</classify:facet>
}
</taxonomy>
}
</taxonomies>
let $TaxonomyGroupXml := <taxonomies>
{
for $taxonomy in $TaxonomyFacetXml/*:taxonomy
return
element {local-name($taxonomy)}
{
attribute id{$taxonomy/@id/string()},attribute who{$taxonomy/@who/string()},attribute when{$taxonomy/@when/string()},
for $facets in $taxonomy/*:facet
let $group := $facets/@group
group by $group
return <classify:facets group="{$group}">
{
$facets
}
</classify:facets>
}
}
</taxonomies>
return $TaxonomyGroupXml}
</metadata>
</result>
</results>
else <result><status>Failure</status><message>{$docUri}No document available to fetch metadata information.</message></result>
else <result><status>Failure</status><message>Assigned metadata is not available in the system.</message></result>
else <result><status>Failure</status><message>No metadata template is available for this content type</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>
}
};
(:~
: To specific version of the metadata.
: @param $cid Content ID
: @param $coid Component ID
: @header $authorization Authorization key
: @return element(result)
:)
declare
%rest:path("/content-metadata-version")
%rest:GET
%rest:query-param("ctype", "{$ctype}")
%rest:query-param("type", "{$type}")
%rest:query-param("cid", "{$cid}")
%rest:query-param("coid", "{$coid}")
%rest:query-param("chunkid", "{$chunkid}")
%rest:query-param("version", "{$version}")
%rest:header-param("Authorization", "{$authorization}", "none")
function metadata:get-metadata-version(
$ctype as xs:string,
$type as xs:string,
$cid as xs:string,
$coid as xs:string?,
$chunkid as xs:string?,
$version as xs:integer,
$authorization as xs:string
)
{
config:session-check($authorization),
try
{ if($cid!='' or $coid!='')
then
let $metadataversionURI := if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then
if((($ctype = $config:playDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase)) and $type='chunk')
then
fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$chunkid,'_',$config:VersionControlFileName)
else fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$coid,'_',$config:VersionControlFileName)
else fn:concat('/',$ctype,'/',$cid,'/metadata/',$cid,'_',$config:VersionControlFileName)
let $versionXML := db:open($config:ContentMetadataDatabse,$metadataversionURI)
let $versionUri := if($version=$versionXML/versions/version/@number)
then $versionXML/versions/version[@number=$version]/@uri/string()
else
if(fn:sum(max($versionXML/versions/version/@number) + 1) eq fn:number($version))
then fn:concat($config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,$config:MetaXml)
else <result><status>Failure</status><message>Related metadata version is not available.</message></result>
return
if($versionUri instance of element())
then $versionUri
else
let $ContentTypeXml := db:open($config:CoreDatabase,$config:ContentType)
let $metaTemplate := if($type='volume') then $ContentTypeXml/clist:controlledList/clist:name[@xml:id=$ctype]/@volume-meta-template/string()
else $ContentTypeXml/clist:controlledList/clist:name[@xml:id=$ctype]/@chunk-meta-template/string()
return
if($metaTemplate!='')
then
if(db:exists($config:CoreDatabase,fn:concat($config:ConfigDir,$metaTemplate)))
then
let $metaUri := $versionUri
let $classifyUri := fn:replace($versionUri,'metadata_version_','classify_version_')
return
if(db:exists($config:ContentMetadataDatabse,$metaUri))
then
let $metaDoc := db:open($config:ContentMetadataDatabse,$metaUri)
let $metaTemplate := db:open($config:CoreDatabase,fn:concat($config:ConfigDir,$metaTemplate))
let $state := $metaDoc/state
let $metaContent :=
for $node in $metaTemplate/formTemplate/*
let $nodename := fn:local-name($node)
return
if($nodename='item')
then
for $item in $node[fn:not(@name="taxonomy")]
let $xpath := if($item/@name='RelatedContents')
then "fn:doc('bloomsbury/config/content-types.xml')/*:controlledList/*:name/@xml:id"
else $item/@xpath/string()
return
(
element item {
for $att in $item/@*[fn:not(fn:name()='xpath')]
return
attribute {fn:local-name($att)} {$att},
attribute value {if($item/@type='relatedcontent') then () else $metaDoc/metadata/*[name()=$item/@name]},
if(($item/@type='checkbox') or ($item/@type='dropdown') or ($item/@type='relatedcontent') or ($item/@type='content-type-dropdown'))
then
let $docUri := if(($ctype='looseleaf' ) or ($ctype='play' ) or ($ctype='monograph' ))
then
fn:uri-collection(fn:concat(blcommon:get-db-name($ctype),$config:ContentDir,$cid,'/',$coid,'/content/latest/'))
else fn:uri-collection(fn:concat($config:MetadataOnlyContentDatabase,'/',$ctype,'/',$cid))[fn:not(fn:contains(.,'metadata')
)]
let $doc := fn:doc($docUri)
let $value := metadata:get-path($xpath,$doc)
let $ControledListPath := if($item/@ControlledList) then $item/@ControlledList/string() else ()
let $ControledListDoc := if($ControledListPath!='') then metadata:get-item-ControledList($ControledListPath) else()
let $ItemValue := $item/@ItemValue/string()
let $ItemText := $item/@ItemText/string()
let $xpath := '/*:controlledList/*'
for $name in metadata:get-path($xpath,$ControledListDoc)
return
element option {attribute name{$item/@name/string()},
attribute value {$name/@*[name()=$ItemValue]/string()},
attribute title {$name/@*[name()=$ItemText]/string()},
attribute selected{if($item/@type='relatedcontent') then 'false' else if(fn:matches(string-join($name/@*[name()=$ItemValue]/string(),'|'),$metaDoc/metadata/*[name()=$item/@name]/string())) then 'true' else 'false'},
if($item/@type='relatedcontent')
then
attribute metadata {if(
($name/@*[name()=$ItemValue]/string()='audio') or ($name/@*[name()=$ItemValue]/string()='video') or
($name/@*[name()=$ItemValue]/string()='person') or ($name/@*[name()=$ItemValue]/string()='organisation')or
($name/@*[name()=$ItemValue]/string()='image') or ($name/@*[name()=$ItemValue]/string()='publisher') or
($name/@*[name()=$ItemValue]/string()='series')
) then 'true' else 'false'
}
else()
}
else(),
if($item/@type='relatedcontent')
then
$metaDoc/metadata/RelatedContents
else if($item/@type='content-type-dropdown')
then
element option {attribute name{$item/@name/string()},
attribute value {$metaDoc/metadata/*[name()=$item/@name]/string()},
attribute title {$item/@title/string()},
attribute selected{if($metaDoc/metadata/*[name()=$item/@name]/string()!='') then 'true' else 'false'}
}
else()
}
)
else if($nodename='group')
then
let $group := $node
return
element group { for $att in $group/@*[fn:not(fn:local-name(.)='xpath' or fn:local-name(.)='subgroup' or fn:local-name(.)='docstructure') ]
return
attribute {fn:local-name($att)} {$att},
let $docUri := if(($ctype='looseleaf' ) or ($ctype='play' ) or ($ctype='monograph' ))
then
fn:uri-collection(fn:concat(blcommon:get-db-name($ctype),$config:ContentDir,$cid,'/',$coid,'/content/latest/'))
else fn:uri-collection(fn:concat($config:MetadataOnlyContentDatabase,'/',$ctype,'/',$cid))[fn:not(fn:contains(.,'metadata')
)]
let $doc := fn:doc($docUri)
return
let $groupName := $group/@name/string()
let $subgroupname := $group/@subgroup/string()
let $xpath := fn:concat('/metadata/',$groupName)
for $values in metadata:get-path($xpath,$metaDoc)
for $items in $values/*
return
element subgroup
{ attribute name{$subgroupname},
for $item in $group/*:item[fn:not(@name="taxonomy")]
let $ControledListPath := $item/@ControlledList/string()
return
element item
{
for $att in $item/@*[fn:not(fn:name()='xpath' or fn:name()='ControlledList')]
return
attribute {fn:local-name($att)} {$att},
if($item/@type='dropdown' or $item/@type='checkbox')
then
let $ControledListPath := $item/@ControlledList/string()
let $ControledListDoc := metadata:get-item-ControledList($ControledListPath)
let $ItemValue := $item/@ItemValue/string()
let $ItemText := $item/@ItemText/string()
let $xpath := '/*:controlledList/*'
for $name in metadata:get-path($xpath,$ControledListDoc)
return element option{
attribute name{$item/@name/string()},
attribute value {$name/@*[name()=$ItemValue]/string()},
attribute title {$name/@*[name()=$ItemText]/string()},
attribute selected{if($items/*[name()=$item/@name]!='') then if (fn:matches(string-join($name/@*[name()=$ItemValue]/string(),'|'),$items/*[name()=$item/@name])) then 'true' else 'false' else 'false'}
}
else if($item/@type='content-type-dropdown')
then
element option{
attribute name{$item/@name/string()},
attribute title{$item/@title/string()},
attribute value {$items/*[name()=$item/@name]},
attribute selected{if($items/*[name()=$item/@name]!='') then 'true' else 'false'}
}
else
attribute value {$items/*[name()=$item/@name]}
}
}
}
else()
return
<results>
<result>
<status>Success</status>
<metadata>
<state>{$state}</state>
<content-metadata>{$metaContent}</content-metadata>
{
let $classify:= db:open($config:ContentMetadataDatabse,$classifyUri)
let $TaxonomyFacetXml := <taxonomies>{
for $taxonomy in $classify/*:taxonomies/*:taxonomy
let $taxonomyid := $taxonomy/@id/string()
let $taxonomydoc := db:open($config:CoreDatabase,fn:concat($config:TaxonomyDir,$taxonomyid,'.xml'))
return
<taxonomy id="{$taxonomyid}" who="{$taxonomy/@who/string()}" when="{$taxonomy//@when/string()}">
{
for $facet in $taxonomy/*:facet/string()
return
<classify:facet group="{$taxonomydoc/*:taxonomy/*:facet[descendant::*:facet/@xml:id=$facet]/@xml:id}">
{
$facet
}
</classify:facet>
}
</taxonomy>
}
</taxonomies>
let $TaxonomyGroupXml := <taxonomies>
{
for $taxonomy in $TaxonomyFacetXml/taxonomy
return
element {local-name($taxonomy)}
{
attribute id{$taxonomy/@id/string()},attribute who{$taxonomy/@who/string()},attribute when{$taxonomy/@when/string()},
for $facets in $taxonomy/*:facet
let $group := $facets/@group
group by $group
return <classify:facets group="{$group}">
{
$facets
}
</classify:facets>
}
}
</taxonomies>
return $TaxonomyGroupXml
}
</metadata>
</result>
</results>
else()
else <result><status>Failure</status><message>Assigned metadata is not available in the system.</message></result>
else <result><status>Failure</status><message>No metadata template is available for this content type{$metadataversionURI }</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>
}
};
(:~
: To get content-metadata version information.
: @param $cid Content ID
: @param $coid Component ID
: @header $authorization Authorization key
: @return element(result)
:)
declare
%rest:path("/content-metadata-versions")
%rest:GET
%rest:query-param("ctype", "{$ctype}")
%rest:query-param("cid", "{$cid}")
%rest:query-param("coid", "{$coid}")
%rest:query-param("chunkid", "{$chunkid}")
%rest:header-param("Authorization", "{$authorization}", "none")
function metadata:get-versions(
$ctype as xs:string,
$cid as xs:string,
$coid as xs:string?,
$chunkid as xs:string?,
$authorization as xs:string
)
{
config:session-check($authorization),
try
{ if($cid!='' or $coid!='')
then
let $records := let $uri := if(($ctype = $config:Audio) or ($ctype = $config:Person) or ($ctype = $config:Image)
or ($ctype= $config:Video) or ($ctype = $config:Organisation)
or ($ctype = $config:Publisher) or ($ctype = $config:Series))
then
(:Need to work for metadatacontent only:)
for $metadataversionURI in fn:uri-collection(fn:concat($config:ContentMetadataDatabse,'/',$ctype,'/',$cid))
[fn:contains(.,$config:Metadata)]
[fn:contains(.,fn:concat($cid,'_',$config:VersionControlFileName))]
return $metadataversionURI
else
for $metadataversionURI in fn:uri-collection(fn:concat($config:ContentMetadataDatabse,fn:concat('/',$ctype,$config:ContentDir)))[fn:tokenize(.,'/')[5]=$cid]
[fn:tokenize(.,'/')[6]=$coid]
[fn:contains(.,$config:Metadata)]
[if($chunkid!='') then fn:contains(.,fn:concat($chunkid,'_',$config:VersionControlFileName)) else fn:contains(.,fn:concat($coid,'_',$config:VersionControlFileName))]
return $metadataversionURI
let $versionDoc := fn:doc($uri)
let $getlatest := $versionDoc/versions/version[fn:last()]
let $version := fn:concat('v',fn:sum(fn:max($versionDoc/versions/version/@number) + 1))
return
<versions>
{
<latest>
<version>{$version}</version>
<uri>{fn:concat($config:ContentMetadataDatabse,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,$config:MetaXml)}</uri>
<on>{$getlatest/@on/string()}</on>
<cid>{$cid}</cid>
<coid>{$coid}</coid>
{if($chunkid!='') then <chunkid>{$chunkid}</chunkid> else()}
</latest>
,
for $records in $versionDoc/versions/version
let $versions := <version>{$records/@number/string()}</version>
let $uri := <uri>{$records/@uri/string()}</uri>
let $datetime := <on>{$records/@on/string()}</on>
let $cid := <cid>{fn:tokenize($records/@uri/string(),'/')[3]}</cid>
let $coid := <coid>{fn:tokenize($records/@uri/string(),'/')[4]}</coid>
let $chunkid := if($chunkid!='') then <chunkid>{$chunkid}</chunkid> else()
return <version>{$versions,$uri,$datetime,$cid,$coid,$chunkid,$uri}</version>
}
</versions>
return
if($records)
then
(
<result><status>Success</status>{$records}</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>
}
};
(:~
: Create/maintain history of the metadata.
: @param $cid Content ID
: @param $coid Component ID
: @param $outputFileName File name to save
: @return empty sequence
:)
declare %private %updating function metadata:create-version(
$ctype as xs:string,
$type as xs:string?,
$cid as xs:string,
$coid as xs:string,
$chunkid as xs:string?
)
{
let $versionFileName := let $tstamp := fn:current-dateTime()
let $suffix := fn:format-dateTime($tstamp, "[Y1,4][M01][D01][H01][m01][s01][f01]")
return fn:concat("metadata",'_version_',$suffix,'.xml')
let $latestFileName := $config:MetaXml
let $MetaUri := if($type='chunk')
then fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,if($chunkid) then $chunkid else $coid,'_',$config:MetaXml)
else
if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,$coid,'_',$config:MetaXml)
else fn:concat('/',$ctype,'/',$cid,$config:Metadata,$config:LatestDir,$cid,'_',$config:MetaXml)
let $classifyUri := if($type='chunk')
then
fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,$chunkid,'_',$config:ClassifyXml)
else
if(($ctype = $config:LooseleafDatabase ) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then
fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,'latest/',$coid,'_',$config:ClassifyXml)
else
fn:concat('/',$ctype,'/',$cid,$config:Metadata,$config:LatestDir,$cid,'_',$config:ClassifyXml)
let $targetUri := if( fn:doc-available(fn:concat($config:ContentMetadataDatabse,$MetaUri)))
then $MetaUri
else if( fn:doc-available(fn:concat($config:ContentMetadataDatabse,$classifyUri)))
then $classifyUri
else()
(:let $targetUri := if($type='chunk')
then fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,if($chunkid) then $chunkid else $coid,'_',$config:MetaXml)
else
if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,$coid,'_',$config:MetaXml)
else fn:concat('/',$ctype,'/',$cid,$config:Metadata,$config:LatestDir,$cid,'_',$config:MetaXml):)
let $versionUri := if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,'/metadata',$config:VersionDir,$versionFileName)
else fn:concat('/',$ctype,'/',$cid,'/metadata',$config:VersionDir,$versionFileName)
return
(
db:replace($config:ContentMetadataDatabse, $versionUri, db:open($config:ContentMetadataDatabse,$targetUri))
,
let $versionFileName := let $tstamp := fn:current-dateTime()
let $suffix := fn:format-dateTime($tstamp, "[Y1,4][M01][D01][H01][m01][s01][f01]")
return fn:concat("classify",'_version_',$suffix,'.xml')
let $targetUri := if($type='chunk')
then fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,if($chunkid) then $chunkid else $coid,'_',$config:ClassifyXml)
else
if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,$coid,'_',$config:ClassifyXml)
else fn:concat('/',$ctype,'/',$cid,$config:Metadata,$config:LatestDir,$cid,'_',$config:ClassifyXml)
let $versionUri := if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,'/metadata',$config:VersionDir,$versionFileName)
else fn:concat('/',$ctype,'/',$cid,'/metadata',$config:VersionDir,$versionFileName)
return
if( fn:doc-available(fn:concat($config:ContentMetadataDatabse,$targetUri)))
then
db:replace($config:ContentMetadataDatabse, $versionUri, db:open($config:ContentMetadataDatabse,$targetUri))
else()
,
config:update-message("[Content Checkin][Content version is created : " || $versionUri || "]")
,
let $versionControlUri := if(($ctype = $config:LooseleafDatabase) or ($ctype = $config:playDatabase) or ($ctype = $config:MonographDatabase))
then
if((($ctype = $config:playDatabase) or ($ctype=$config:MonographDatabase)) and $type='chunk')
then
fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,if($chunkid) then $chunkid else $coid,'_',$config:VersionControlFileName)
else fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$coid,'_',$config:VersionControlFileName)
else fn:concat('/',$ctype,'/',$cid,'/metadata/',$cid,'_',$config:VersionControlFileName)
return
if(fn:doc-available(fn:concat($config:ContentMetadataDatabse,$versionControlUri)))
then
let $versionDoc := db:open($config:ContentMetadataDatabse,$versionControlUri)
let $nextVersion := fn:sum(max($versionDoc/versions/version/@number) + 1)
return
(
insert node <version number="{$nextVersion}" uri="{$versionUri}" on="{fn:adjust-dateTime-to-timezone(fn:current-dateTime())}"/> into db:open($config:ContentMetadataDatabse,$versionControlUri)/versions,
config:update-message("[Content Checkin][Content version control updated : " || $versionUri || "]")
)
else
db:replace($config:ContentMetadataDatabse,$versionControlUri,<versions><version number="1" uri="{$versionUri}" on="{fn:adjust-dateTime-to-timezone(fn:current-dateTime())}"/></versions>)
)
};
declare
%updating
%rest:path("/content-chunk-metadata/{$ctype=[^/]+}/{$type=[^/]+}/{$cid=[^/]+}/{$coid=[^/]+}/{$chunkid=[^/]+}")
%rest:POST("{$body}")
%rest:header-param("Authorization", "{$authorization}", "none")
%rest:consumes("application/xml", "text/xml")
function metadata:chunk-add(
$ctype as xs:string,
$type as xs:string,
$cid as xs:string,
$coid as xs:string,
$chunkid as xs:string?,
$body as document-node(),
$authorization as xs:string
)
{
config:session-check($authorization),
try
{
let $meta := let $state := $body/metadata/state
let $meta := $body/metadata/content-metadata
return
<metadata id="{fn:concat($cid,'_',$coid,'_',$chunkid) }">
{ $state,
let $result := for $node in $meta/*
let $nodename := fn:local-name($node)
return
if($nodename='item')
then
if($node/option)
then
for $option in $node/option[@selected='true']
return
element {$option/@name}
{
$option/@value/string()
}
else if($node/RelatedContents)
then
$node/RelatedContents
else element {$node/@name} {$node/@value/string()}
else if($nodename='group')
then
element {$node/@name/string()} {attribute title{'title'},
for $subgroup in $node/*:subgroup
return element{$subgroup/@name/string()}
{
for $item in $subgroup/*:item
return
if($item/*:option[@selected='true'])
then
element{$item/option[@selected='true']/@name/string()}
{
$item/*:option[@selected='true']/@value/string()
}
else if(not($item/*:option))
then
element {$item/@name/string()} {$item/@value/string()}
else()
}
}
else()
return $result
}
</metadata>
let $userid := fn:substring-before(config:session-value($authorization),'$$$$')
let $username := db:open($config:CoreDatabase,fn:concat($config:UserDir,$userid,'.xml'))/user/name/string()
let $Taxonomies := if ($body/metadata/taxonomies!='')
then
copy $c := $body/metadata/taxonomies
modify
(
insert node (attribute {'cid'} {$chunkid }) into $c,
for $taxonoy in $c/taxonomy
return
insert node (attribute{'who'}{$userid},attribute{'when'}{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}) into $taxonoy
)
return $c
else $body/metadata/taxonomies
let $state := $body/metadata/state
let $targetURI := fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,$chunkid,'_',$config:MetaXml)
let $infoUri := fn:concat($config:ContentDir,$cid,'/',$coid,'/',$config:InfoXml)
return
(:Step 1: Check if Metadata is already exist :)
if(fn:doc-available(fn:concat($config:ContentMetadataDatabse,$targetURI)))
then
(
update:output(<result><status>Failure</status><message>Metadata is already available</message></result>),
config:update-message("[Metadata Add][Metadata is already available : " || $coid || "]")
)
else
(
db:replace($config:ContentMetadataDatabse,$targetURI,$meta)
,
if($Taxonomies!='')
then
db:replace($config:ContentMetadataDatabse,fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,$chunkid,'_',$config:ClassifyXml),$Taxonomies)
else()
,
audit:add-update-metadata($ctype,$cid,$coid, 'Add metadata',config:session-value($authorization))
,
config:update-message("[Metadata Add][Metadata added into the system : " || $coid || "]")
,
update:output(<result><status>Success</status><message>Metadata added into the system</message></result>)
)
}
catch *
{
admin:write-log("[Metadata Add][Error: " || $err:description || "]"),
admin:write-log("[Metadata Add][Error: " || $err:additional || "]"),
update:output(<result><status>Error</status><message>Error generated. Please check system log</message></result>)
}
};
declare
%updating
%rest:path("/content-chunk-metadata/{$ctype=[^/]+}/{$type=[^/]+}/{$cid=[^/]+}/{$coid=[^/]+}/{$chunkid=[^/]+}")
%rest:PUT("{$body}")
%rest:header-param("Authorization", "{$authorization}", "none")
%rest:consumes("application/xml", "text/xml")
function metadata:update(
$ctype as xs:string,
$type as xs:string,
$cid as xs:string,
$coid as xs:string,
$chunkid as xs:string,
$body as document-node(),
$authorization as xs:string
)
{
config:session-check($authorization),
try
{
let $meta := let $state := $body/metadata/state
let $meta := $body/metadata/content-metadata
return
<metadata id="{fn:concat($cid,'_',$coid,'_',$chunkid) }">
{ $state,
let $result := for $node in $meta/*
let $nodename := fn:local-name($node)
return
if($nodename='item')
then
if($node/option)
then
for $option in $node/option[@selected='true']
return
element {$option/@name}
{
$option/@value/string()
}
else if($node/RelatedContents)
then
$node/RelatedContents
else element {$node/@name} {$node/@value/string()}
else if($nodename='group')
then
element {$node/@name/string()} {attribute title{'title'},
for $subgroup in $node/*:subgroup
return element{$subgroup/@name/string()}
{
for $item in $subgroup/*:item
return
if($item/*:option[@selected='true'])
then
element{$item/option[@selected='true']/@name/string()}
{
$item/*:option[@selected='true']/@value/string()
}
else if(not($item/*:option))
then
element {$item/@name/string()} {$item/@value/string()}
else()
}
}
else()
return $result
}
</metadata>
(:let $taxonomy := $body/metadata/taxonomies:)
let $userid := fn:substring-before(config:session-value($authorization),'$$$$')
let $username := db:open($config:CoreDatabase,fn:concat($config:UserDir,$userid,'.xml'))/user/name/string()
let $Taxonomies := if ($body/metadata/taxonomies!='')
then
copy $c := $body/metadata/taxonomies
modify
(
insert node (attribute {'cid'} {$chunkid }) into $c,
for $taxonoy in $c/taxonomy
return
insert node (attribute{'who'}{$userid},attribute{'when'}{fn:adjust-dateTime-to-timezone(convert:integer-to-dateTime(prof:current-ms()))}) into $taxonoy
)
return $c
else $body/metadata/taxonomies
let $state := $body/metadata/state
let $targetURI := fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,$chunkid,'_',$config:MetaXml)
let $ClassifytURI := fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,$chunkid,'_',$config:ClassifyXml)
return
(:Step 1: Check if Metadata is already exist :)
if(fn:doc-available(fn:concat($config:ContentMetadataDatabse,$targetURI)) or fn:doc-available(fn:concat($config:ContentMetadataDatabse,$ClassifytURI)))
then
(
update:output(<result><status>Success</status><message>Metadata Updated into the system</message></result>)
,
metadata:create-version($ctype,$type,$cid,$coid,$chunkid)
,
db:replace($config:ContentMetadataDatabse,$targetURI,$meta)
,
if($Taxonomies!='')
then
db:replace($config:ContentMetadataDatabse,fn:concat('/',$ctype,$config:ContentDir,$cid,'/',$coid,$config:Metadata,$config:LatestDir,$chunkid,'_',$config:ClassifyXml),$Taxonomies)
else()
)
else
(
update:output(<result><status>Failure</status><message>Metadata is not available to update</message></result>),
config:update-message("[Metadata Update][Metadata is not available to update : " || $coid || "]")
)
}
catch *
{
admin:write-log("[Metadata Add][Error: " || $err:description || "]"),
admin:write-log("[Metadata Add][Error: " || $err:additional || "]"),
update:output(<result><status>Error</status><message>Error generated. Please check system log</message></result>)
}
};
(:~
: To get content on the basis of XPATH
: @param $path The XPATH
: @book the document itself
:)
declare %private function metadata:get-path(
$path as xs:string?,
$book
)
{
if($path)
then
xquery:eval('declare variable $bookId := "' || $book/@xml:id || '"; ' || $path,
map{'':$book}
)
else ()
};
declare function metadata:eval-item-xpath($item as element(), $groupInstance as element(), $roleMapping as element()) as xs:string
{
let $xslt :=
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:variable name="context">
{$groupInstance/(@*|*)}
</xsl:variable>
<xsl:variable name="roleMapping">
{$roleMapping/*:name}
</xsl:variable>
<xsl:template match="*">
<output>
<xsl:value-of select="{$item/@xpath}"/>
</output>
</xsl:template>
</xsl:stylesheet>
return data(xslt:transform($xslt, $xslt))
};
declare function metadata:get-item-ControledList($path as xs:string)
{
let $ControledListDoc := fn:doc($path)
(:for $name at $pos in $ControledListDoc/*:name/@xml:id/string():)
return
$ControledListDoc
};