*** empty log message ***

*** empty log message ***

svn path=/trunk/eXist-1.0/; revision=1211

(:
    Module: examples setup
:)
module namespace setup="http://exist-db.org/xquery/admin-interface/setup";

declare namespace xdb="http://exist-db.org/xquery/xmldb";
declare namespace request="http://exist-db.org/xquery/request";
declare namespace util="http://exist-db.org/xquery/util";

declare function setup:main() as element() {

Examples Setup

        {
            let $action := request:request-parameter("action", ())
            return
                if($action) then
                    if($action eq "Import Example Data") then
                        setup:importLocal()
                    else if($action eq "Import Remote Files") then
                        setup:importFromURLs()
                    else
                        setup:page3()
                else
                    setup:page1()
        }

};

declare function setup:importLocal() as element()+ {
	let $home := util:system-property("exist.home"),
		$pathSep := util:system-property("file.separator"),
		$dir :=
			if(ends-with($home, "WEB-INF")) then
				concat(substring-before($home, "WEB-INF"), "samples")
			else
				concat($home, $pathSep, "samples")
    return (
        setup:page2(),

Actions:

            {
                setup:create-collection("/db", "shakespeare"),
                setup:create-collection("/db/shakespeare", "plays"),
                setup:store-files("/db/shakespeare/plays", $dir,
                    ( "shakespeare/*.xml", "shakespeare/*.xsl" ),
                    "text/xml"
                ),
                setup:store-files("/db/shakespeare/plays", $dir,
                    "shakespeare/*.css", "text/css"),
                setup:create-collection("/db", "xinclude"),
                setup:store-files("/db/xinclude", $dir,
                    ( "xinclude/*.xsl", "xinclude/*.xml"), "text/xml"),
                setup:store-files("/db/xinclude", $dir,
                    "xinclude/*.xq", "application/xquery"),
                setup:store-files("/db/xinclude", $dir,
                    "xinclude/*.jpg", "image/jpeg"),
                setup:store-files("/db/xinclude", $dir,
                    "xinclude/*.css", "text/css"),
                setup:create-collection("/db", "library"),
                setup:store-files("/db/library", $dir, "*.rdf", "text/xml"),
                setup:create-collection("/db", "mods"),
                setup:store-files("/db/mods", $dir, "mods/*.xml", "text/xml"),
                setup:store-files("/db", $dir, "*.xml", "text/xml"),
				setup:create-collection("/db/system/config", "db"),
				setup:create-collection("/db/system/config/db", "mondial"),
				setup:store-files("/db/system/config/db/mondial", $dir,
					"mondial.xconf", "text/xml")
            }

    )
};

declare function setup:importFromURLs() as element()+ {
    (
        setup:page3(),

Actions:

            {
                let $includeXmlad := request:request-parameter("xmlad", ()),
                    $includeMondial := request:request-parameter("mondial", ())
                return (
                    if($includeXmlad) then (
                        setup:create-collection("/db", "xmlad"),
                        setup:load-URL("/db/xmlad",
                            "http://belnet.dl.sourceforge.net/sourceforge/xmlad/xmlad.xml",
                            "xmlad.xml")
                    ) else (),
                    if($includeMondial) then (
                        setup:create-collection("/db", "mondial"),
                        setup:load-URL("/db/mondial",
                            "http://dbis.informatik.uni-goettingen.de/Mondial/mondial-europe.xml",
                            "mondial.xml")
                    ) else ()
                )
            }

    )
};

declare function setup:load-URL($collection, $url, $docName) as element() {
	let $x := xdb:store($collection, $docName, xs:anyURI($url))
	return

File {$docName} imported from url: {$url}

};

declare function setup:store-files($collection, $home, $patterns, $mimeType) as element()* {
    let $stored := xdb:store-files-from-pattern($collection, $home, $patterns, $mimeType)
    for $doc in $stored
    return

Uploaded: {$doc}

};

declare function setup:create-collection($parent, $name) as element() {
    let $col := xdb:create-collection($parent, $name)
    return

Created collection: {util:collection-name($col)}

};

declare function setup:page1() as element() {
    <form action="{request:encode-url(request:request-uri())}" method="POST">

eXist ships with a number of XQuery examples. Some of these
        require certain documents to be stored in the database. Clicking on the button
        below will import the required data from the samples directory:

        <input type="submit" name="action" value="Import Example Data"/>
        <input type="hidden" name="panel" value="setup"/>
    </form>
};

declare function setup:page2() as element() {
    <form action="{request:encode-url(request:request-uri())}" method="POST">

The XQuery examples also use some XML data not included with the distribution.
        I can try to download the corresponding data. Do you want me to do so?

        <input type="checkbox" name="xmlad" checked="true"/>
        The XML Acronym Demystifier
        (approx. 384K)

        <input type="checkbox" name="mondial"/>
        The Mondial Database (Europe)
        (approx. 410K)

<input type="submit" name="action" value="Import Remote Files"/>
        <input type="submit" name="action" value="Skip"/>

        <input type="hidden" name="panel" value="setup"/>
    </form>
};

declare function setup:page3() as element() {

Files have been loaded. You can now go to the
    examples page.

};

(:
    Module: examples setup
:)
module namespace setup="http://exist-db.org/xquery/admin-interface/setup";

declare namespace xdb="http://exist-db.org/xquery/xmldb";
declare namespace request="http://exist-db.org/xquery/request";
declare namespace util="http://exist-db.org/xquery/util";

declare function setup:main() as element() {

Examples Setup

        {
            let $action := request:request-parameter("action", ())
            return
                if($action) then
                    if($action eq "Import Example Data") then
                        setup:importLocal()
                    else if($action eq "Import Remote Files") then
                        setup:importFromURLs()
                    else
                        setup:page3()
                else
                    setup:page1()
        }

};

declare function setup:importLocal() as element()+ {
	let $home := util:system-property("exist.home"),
		$pathSep := util:system-property("file.separator"),
		$dir :=
			if(ends-with($home, "WEB-INF")) then
				concat(substring-before($home, "WEB-INF"), "samples")
			else
				concat($home, $pathSep, "samples")
    return (
        setup:page2(),

Actions:

            {
                setup:create-collection("/db", "shakespeare"),
                setup:create-collection("/db/shakespeare", "plays"),
                setup:store-files("/db/shakespeare/plays", $dir,
                    ( "shakespeare/*.xml", "shakespeare/*.xsl" ),
                    "text/xml"
                ),
                setup:store-files("/db/shakespeare/plays", $dir,
                    "shakespeare/*.css", "text/css"),
                setup:create-collection("/db", "xinclude"),
                setup:store-files("/db/xinclude", $dir,
                    ( "xinclude/*.xsl", "xinclude/*.xml"), "text/xml"),
                setup:store-files("/db/xinclude", $dir,
                    "xinclude/*.xq", "application/xquery"),
                setup:store-files("/db/xinclude", $dir,
                    "xinclude/*.jpg", "image/jpeg"),
                setup:store-files("/db/xinclude", $dir,
                    "xinclude/*.css", "text/css"),
                setup:create-collection("/db", "library"),
                setup:store-files("/db/library", $dir, "*.rdf", "text/xml"),
                setup:create-collection("/db", "mods"),
                setup:store-files("/db/mods", $dir, "mods/*.xml", "text/xml"),
                setup:store-files("/db", $dir, "*.xml", "text/xml"),
				setup:create-collection("/db/system/config", "db"),
				setup:create-collection("/db/system/config/db", "mondial"),
				setup:store-files("/db/system/config/db/mondial", $dir,
					"mondial.xconf", "text/xml")
            }

    )
};

declare function setup:importFromURLs() as element()+ {
    (
        setup:page3(),

Actions:

            {
                let $includeXmlad := request:request-parameter("xmlad", ()),
                    $includeMondial := request:request-parameter("mondial", ())
                return (
                    if($includeXmlad) then (
                        setup:create-collection("/db", "xmlad"),
                        setup:load-URL("/db/xmlad",
                            "http://belnet.dl.sourceforge.net/sourceforge/xmlad/xmlad.xml",
                            "xmlad.xml")
                    ) else (),
                    if($includeMondial) then (
                        setup:create-collection("/db", "mondial"),
                        setup:load-URL("/db/mondial",
                            "http://dbis.informatik.uni-goettingen.de/Mondial/mondial-europe.xml",
                            "mondial.xml")
                    ) else ()
                )
            }

    )
};

declare function setup:load-URL($collection, $url, $docName) as element() {
    xdb:store($collection, $docName, xs:anyURI($url)),

File {$docName} imported from url: {$url}

};

declare function setup:store-files($collection, $home, $patterns, $mimeType) as element()* {
    let $stored := xdb:store-files-from-pattern($collection, $home, $patterns, $mimeType)
    for $doc in $stored
    return

Uploaded: {$doc}

};

declare function setup:create-collection($parent, $name) as element() {
    let $col := xdb:create-collection($parent, $name)
    return

Created collection: {util:collection-name($col)}

};

declare function setup:page1() as element() {
    <form action="{request:encode-url(request:request-uri())}" method="POST">

eXist ships with a number of XQuery examples. Some of these
        require certain documents to be stored in the database. Clicking on the button
        below will import the required data from the samples directory:

        <input type="submit" name="action" value="Import Example Data"/>
        <input type="hidden" name="panel" value="setup"/>
    </form>
};

declare function setup:page2() as element() {
    <form action="{request:encode-url(request:request-uri())}" method="POST">

The XQuery examples also use some XML data not included with the distribution.
        I can try to download the corresponding data. Do you want me to do so?

        <input type="checkbox" name="xmlad" checked="true"/>
        The XML Acronym Demystifier
        (approx. 384K)

        <input type="checkbox" name="mondial"/>
        The Mondial Database (Europe)
        (approx. 410K)

<input type="submit" name="action" value="Import Remote Files"/>
        <input type="submit" name="action" value="Skip"/>

        <input type="hidden" name="panel" value="setup"/>
    </form>
};

declare function setup:page3() as element() {

Files have been loaded. You can now go to the
    examples page.

};


Added Special Character Encoding for DTS Translations

(:
 : Copyright (C) [2013] [The FURTHeR Project]
 :
 : Licensed under the Apache License, Version 2.0 (the "License");
 : you may not use this file except in compliance with the License.
 : You may obtain a copy of the License at
 :
 :         http://www.apache.org/licenses/LICENSE-2.0
 :
 : Unless required by applicable law or agreed to in writing, software
 : distributed under the License is distributed on an "AS IS" BASIS,
 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 : See the License for the specific language governing permissions and
 : limitations under the License.
 :)

module namespace further='http://further.utah.edu/xquery-functions-module';
declare namespace dts='http://further.utah.edu/dts';
declare namespace xmi='http://schema.omg.org/spec/XMI/2.1';

(: Change the location of constants.xq when working locally :)
(: import module namespace const = 'http://further.utah.edu/constants' at 'constants.xq'; :)
import module namespace const = 'http://further.utah.edu/constants'
    at '${server.mdr.ws}${path.mdr.ws.resource.path}/fqe/further/xq/constants.xq';

declare function further:getConceptTranslationRestUrl(
  $srcNmspc as xs:string,
  $srcPropNm as xs:string,
  $srcPropVal as xs:string,
  $tgNmspc as xs:string,
  $tgPropNm as xs:string)
{
  (: EXAMPLE: http://dev-esb.further.utah.edu:9000/dts/rest/translate/UUEDW/DWID/106386/SNOMED CT/Code in Source?view=HUMAN :)
  (:          http://dev-esb.further.utah.edu:9000/dts/rest/translate/{namespace}/{propertyName}/{propertyValue}/{targetNamespace}/{targetPropertyName}?view={view} :)
  (: Sometimes we have values that contain special characters, such as a % for unitOfMeasure.
     Therefore, we need to escape these special characters with the encode-for-uri function.
     The call to iri-to-uri function does not espace these special characters.
     And the reason why we do not simply replace iri-to-uri with encode-for-uri is because
     the encode-for-uri function escapes special characters such as : and /
     which are valid parts of a http://url that we DO NOT want to escape. :)
  let $srcPropertyVal := if (fn:string-length( $srcPropVal ) = 0) then '0' else fn:encode-for-uri($srcPropVal)
  let $fixedSrcNamespace := further:replaceBracketsWithHexCodes( $srcNmspc )
  let $fixedTgNamespace := further:replaceBracketsWithHexCodes( $tgNmspc )
  let $docUrl := fn:concat($const:restServer, $const:dtsRestService, '/', $fixedSrcNamespace, '/', $srcPropNm, '/', $srcPropertyVal, '/', $fixedTgNamespace, '/', $tgPropNm, '?view=HUMAN')

  let $parsedDocUrl := iri-to-uri( $docUrl )

  return $parsedDocUrl

};

declare function further:replaceBracketsWithHexCodes( $inString as xs:string ) as xs:string* {

  let $str := replace( $inString, '\[', '%5B' )
  let $str := replace( $str, '\]', '%5D' )

  return $str
};

declare function further:getTranslatedConcept(
  $srcNmspc as xs:string,
  $srcPropNm as xs:string,
  $srcPropVal as xs:string,
  $tgNmspc as xs:string,
  $tgPropName as xs:string)
{

  let $restUrl := further:getConceptTranslationRestUrl( $srcNmspc, $srcPropNm, $srcPropVal, $tgNmspc, $tgPropName )
  return doc( $restUrl )

};

declare function further:getConceptNamespace( $concept as node()? ) as xs:string*
{
  let $nmspc := $concept/dts:concepts/dts:conceptId/namespace/text()
  return $nmspc
};

declare function further:getConceptPropertyName( $concept as node()? ) as xs:string*
{
  let $propertyName := $concept/dts:concepts/dts:conceptId/propertyName/text()
  return $propertyName
};

declare function further:getConceptPropertyValue( $concept as node()? ) as xs:string*
{
  let $propertyValue := $concept/dts:concepts/dts:conceptId/propertyValue/text()
  return $propertyValue
};

declare function further:getValueDomains()
{
  let $fmdrRestUrl := fn:concat( $const:fmdrRestServer, $const:fmdrRestService, $const:fmdrPathValueDomainsXmi)

  return doc( $fmdrRestUrl )/xmi:XMI/xmi:Extension/elements

};

declare function further:getValueDomainPropertyValue( $valueDomains as node(), $valueDomainName as xs:string, $propertyName as xs:string )
{
  let $val := string($valueDomains/element[@name=$valueDomainName]/tags/tag[@name=$propertyName]/@value)
  return $val
};

declare function further:getValueDomainNamespaceName( $valueDomains as node(), $valueDomainName as xs:string )
{
  let $nmspc := further:getValueDomainPropertyValue( $valueDomains, $valueDomainName,'DTSNamespace')
  return $nmspc

};

declare function further:getValueDomainPropertyName( $valueDomains as node(), $valueDomainName as xs:string )
{
  let $propertyName := further:getValueDomainPropertyValue( $valueDomains, $valueDomainName,'DTSPropertyName')
  return $propertyName

};

declare function further:getValueDomainPropertyValue( $valueDomains as node(), $valueDomainName as xs:string )
{
  let $propertyValue :=  further:getValueDomainPropertyValue( $valueDomains, $valueDomainName,'DTSPropertyValue')
  return $propertyValue

};

(:==================================================================:)
(: Return DTS namespace name by namespace ID                        :)
(:==================================================================:)
declare function further:getNamespaceName(
  $namespaceId as xs:string)
{
  (: Form the DTS web service request URL :)
  (: EXAMPLE: http://dev-esb.further.utah.edu:9000/dts/rest/search/ns/32779 :)
  let $docUrl := fn:concat($const:restServer, $const:dtsSearchService, '/ns/', $namespaceId)

  (: Get the DTS web service response :)
  let $parsedDocUrl := iri-to-uri( $docUrl )

  (: Find the namespace name in the XML response document :)
  return doc( $parsedDocUrl )/dts:namespace/name/text()
};

(:
 : Copyright (C) [2013] [The FURTHeR Project]
 :
 : Licensed under the Apache License, Version 2.0 (the "License");
 : you may not use this file except in compliance with the License.
 : You may obtain a copy of the License at
 :
 :         http://www.apache.org/licenses/LICENSE-2.0
 :
 : Unless required by applicable law or agreed to in writing, software
 : distributed under the License is distributed on an "AS IS" BASIS,
 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 : See the License for the specific language governing permissions and
 : limitations under the License.
 :)

module namespace further='http://further.utah.edu/xquery-functions-module';
declare namespace dts='http://further.utah.edu/dts';
declare namespace xmi='http://schema.omg.org/spec/XMI/2.1';

(: Change the location of constants.xq when working locally :)
(: import module namespace const = 'http://further.utah.edu/constants' at 'constants.xq'; :)
import module namespace const = 'http://further.utah.edu/constants'
    at '${server.mdr.ws}${path.mdr.ws.resource.path}/fqe/further/xq/constants.xq';

declare function further:getConceptTranslationRestUrl(
  $srcNmspc as xs:string,
  $srcPropNm as xs:string,
  $srcPropVal as xs:string,
  $tgNmspc as xs:string,
  $tgPropNm as xs:string)
{
  (: EXAMPLE: http://dev-esb.further.utah.edu:9000/dts/rest/translate/UUEDW/DWID/106386/SNOMED CT/Code in Source?view=HUMAN :)
  (:          http://dev-esb.further.utah.edu:9000/dts/rest/translate/{namespace}/{propertyName}/{propertyValue}/{targetNamespace}/{targetPropertyName}?view={view} :)
  let $srcPropertyVal := if (fn:string-length( $srcPropVal ) = 0) then '0' else $srcPropVal
  let $fixedSrcNamespace := further:replaceBracketsWithHexCodes( $srcNmspc )
  let $fixedTgNamespace := further:replaceBracketsWithHexCodes( $tgNmspc )
  let $docUrl := fn:concat($const:restServer, $const:dtsRestService, '/', $fixedSrcNamespace, '/', $srcPropNm, '/', $srcPropertyVal, '/', $fixedTgNamespace, '/', $tgPropNm, '?view=HUMAN')

  let $parsedDocUrl := iri-to-uri( $docUrl )

  return $parsedDocUrl

};

declare function further:replaceBracketsWithHexCodes( $inString as xs:string ) as xs:string* {

  let $str := replace( $inString, '\[', '%5B' )
  let $str := replace( $str, '\]', '%5D' )

  return $str
};

declare function further:getTranslatedConcept(
  $srcNmspc as xs:string,
  $srcPropNm as xs:string,
  $srcPropVal as xs:string,
  $tgNmspc as xs:string,
  $tgPropName as xs:string)
{

  let $restUrl := further:getConceptTranslationRestUrl( $srcNmspc, $srcPropNm, $srcPropVal, $tgNmspc, $tgPropName )
  return doc( $restUrl )

};

declare function further:getConceptNamespace( $concept as node()? ) as xs:string*
{
  let $nmspc := $concept/dts:concepts/dts:conceptId/namespace/text()
  return $nmspc
};

declare function further:getConceptPropertyName( $concept as node()? ) as xs:string*
{
  let $propertyName := $concept/dts:concepts/dts:conceptId/propertyName/text()
  return $propertyName
};

declare function further:getConceptPropertyValue( $concept as node()? ) as xs:string*
{
  let $propertyValue := $concept/dts:concepts/dts:conceptId/propertyValue/text()
  return $propertyValue
};

declare function further:getValueDomains()
{
  let $fmdrRestUrl := fn:concat( $const:fmdrRestServer, $const:fmdrRestService, $const:fmdrPathValueDomainsXmi)

  return doc( $fmdrRestUrl )/xmi:XMI/xmi:Extension/elements

};

declare function further:getValueDomainPropertyValue( $valueDomains as node(), $valueDomainName as xs:string, $propertyName as xs:string )
{
  let $val := string($valueDomains/element[@name=$valueDomainName]/tags/tag[@name=$propertyName]/@value)
  return $val
};

declare function further:getValueDomainNamespaceName( $valueDomains as node(), $valueDomainName as xs:string )
{
  let $nmspc := further:getValueDomainPropertyValue( $valueDomains, $valueDomainName,'DTSNamespace')
  return $nmspc

};

declare function further:getValueDomainPropertyName( $valueDomains as node(), $valueDomainName as xs:string )
{
  let $propertyName := further:getValueDomainPropertyValue( $valueDomains, $valueDomainName,'DTSPropertyName')
  return $propertyName

};

declare function further:getValueDomainPropertyValue( $valueDomains as node(), $valueDomainName as xs:string )
{
  let $propertyValue :=  further:getValueDomainPropertyValue( $valueDomains, $valueDomainName,'DTSPropertyValue')
  return $propertyValue

};

(:==================================================================:)
(: Return DTS namespace name by namespace ID                        :)
(:==================================================================:)
declare function further:getNamespaceName(
  $namespaceId as xs:string)
{
  (: Form the DTS web service request URL :)
  (: EXAMPLE: http://dev-esb.further.utah.edu:9000/dts/rest/search/ns/32779 :)
  let $docUrl := fn:concat($const:restServer, $const:dtsSearchService, '/ns/', $namespaceId)

  (: Get the DTS web service response :)
  let $parsedDocUrl := iri-to-uri( $docUrl )

  (: Find the namespace name in the XML response document :)
  return doc( $parsedDocUrl )/dts:namespace/name/text()
};


prevent a document from getting added multiple times in the document manager

(:~
: This is the Care Services Discovery stored query registry
: @version 1.0
: @see https://github.com/openhie/openinfoman
:
:)
module namespace csd_dm = "https://github.com/openhie/openinfoman/csd_dm";

declare namespace csd = "urn:ihe:iti:csd:2013";
declare default element  namespace   "urn:ihe:iti:csd:2013";

declare variable $csd_dm:document_manager := 'csd_docs.xml';

declare function csd_dm:blank_directory()
{
<CSD xmlns:csd="urn:ihe:iti:csd:2013" xmlns="urn:ihe:iti:csd:2013">
  <organizationDirectory/>
  <serviceDirectory/>
  <facilityDirectory/>
  <providerDirectory/>
</CSD>
};

declare  function csd_dm:document_source_exists($db,$name) {
  let $source := csd_dm:document_source($name)
  return  if ($source) then (db:is-xml($db,$source)) else false()

};

declare  function csd_dm:open_document($db,$name) {
  if (csd_dm:document_source_exists($db,$name)) then
    db:open($db,csd_dm:document_source($name))
  else
    csd_dm:blank_directory()
};

declare updating function csd_dm:add($db,$doc,$name) {
  csd_dm:empty($db,$name,$doc)
};

declare updating function csd_dm:delete($db,$name) {
  db:delete($db,csd_dm:document_source($name))
};

declare updating function csd_dm:empty($db,$name) {
  csd_dm:empty($db,$name,csd_dm:blank_directory())
};

declare updating function csd_dm:empty($db,$name,$doc) {
  let $source := csd_dm:document_source($name)
  return
    if (csd_dm:document_source_exists($db,$name)) then
      db:replace($db,$source,$doc)
    else
      db:add($db,$doc,$source)

};

declare function csd_dm:registered_documents($db) {
(:  db:list($db,"service_directories/*") :)
  for $doc in db:list($db,"service_directories")
  let $name := csd_dm:fn_base_name($doc,'.xml')
  return $name
};

declare function csd_dm:document_source($name) {
  concat("service_directories/",$name,".xml")
};

declare function csd_dm:fn_base_name($file,$ext) {
  let $old_base_name := fn:function-lookup(xs:QName("file:base-name"), 2)
  return
    if (not(exists($old_base_name))) then
      fn:replace(fn:function-lookup(xs:QName("file:name"), 1)($file), fn:concat($ext, "$"), "")
    else
      $old_base_name($file,$ext)
};

(:~
: This is the Care Services Discovery stored query registry
: @version 1.0
: @see https://github.com/openhie/openinfoman
:
:)
module namespace csd_dm = "https://github.com/openhie/openinfoman/csd_dm";

declare namespace csd = "urn:ihe:iti:csd:2013";
declare default element  namespace   "urn:ihe:iti:csd:2013";

declare variable $csd_dm:document_manager := 'csd_docs.xml';

declare function csd_dm:blank_directory()
{
<CSD xmlns:csd="urn:ihe:iti:csd:2013" xmlns="urn:ihe:iti:csd:2013">
  <organizationDirectory/>
  <serviceDirectory/>
  <facilityDirectory/>
  <providerDirectory/>
</CSD>
};

declare  function csd_dm:document_source_exists($db,$name) {
  let $source := csd_dm:document_source($name)
  return  if ($source) then (db:is-xml($db,$source)) else false()

};

declare  function csd_dm:open_document($db,$name) {
  if (csd_dm:document_source_exists($db,$name)) then
    db:open($db,csd_dm:document_source($name))
  else
    csd_dm:blank_directory()
};

declare updating function csd_dm:add($db,$doc,$name) {
  db:add($db, $doc, csd_dm:document_source($name))
};

declare updating function csd_dm:delete($db,$name) {
  db:delete($db,csd_dm:document_source($name))
};

declare updating function csd_dm:empty($db,$name) {
  csd_dm:empty($db,$name,csd_dm:blank_directory())
};

declare updating function csd_dm:empty($db,$name,$doc) {
  let $source := csd_dm:document_source($name)
  return
    if (csd_dm:document_source_exists($db,$name)) then
      db:replace($db,$source,$doc)
    else
      db:add($db,$doc,$source)

};

declare function csd_dm:registered_documents($db) {
(:  db:list($db,"service_directories/*") :)
  for $doc in db:list($db,"service_directories")
  let $name := csd_dm:fn_base_name($doc,'.xml')
  return $name
};

declare function csd_dm:document_source($name) {
  concat("service_directories/",$name,".xml")
};

declare function csd_dm:fn_base_name($file,$ext) {
  let $old_base_name := fn:function-lookup(xs:QName("file:base-name"), 2)
  return
    if (not(exists($old_base_name))) then
      fn:replace(fn:function-lookup(xs:QName("file:name"), 1)($file), fn:concat($ext, "$"), "")
    else
      $old_base_name($file,$ext)
};