fixed issue in JSON encoding of practitioner

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

(:Import other namespaces.  Set default namespace  to os :)
import module namespace csd_webconf =  "https://github.com/openhie/openinfoman/csd_webconf";
import module namespace csr_proc = "https://github.com/openhie/openinfoman/csr_proc";
import module namespace csd_dm = "https://github.com/openhie/openinfoman/csd_dm";

declare namespace csd = "urn:ihe:iti:csd:2013";
declare namespace atom = "http://www.w3.org/2005/Atom";
declare namespace fhir = "http://hl7.org/fhir";

declare function fadpt:is_fhir_function($search_name) {
  let $function := csr_proc:get_function_definition($csd_webconf:db,$search_name)
  let $ext := $function//csd:extension[  @urn='urn:openhie.org:openinfoman:adapter' and @type='fhir']
  return (count($ext) > 0)
};

declare function fadpt:has_feed($search_name,$doc_name) {
  (fadpt:is_fhir_function($search_name) and csd_dm:document_source_exists($csd_webconf:db ,$doc_name))
};

declare function fadpt:get_base_url($search_name) {
  fadpt:get_base_url($search_name,$csd_webconf:baseurl)
};
declare function fadpt:get_base_url($search_name,$base_url) {
  concat($base_url,'CSD/adapter/fhir/' ,$search_name)
};

declare function fadpt:format_entities($doc,$entities,$entityType,$format) {
  switch ($entityType)
  case "Practitioner"
    return
      if ($format = ('application/json+fhir' ,  'application/json' ,'json'))
      then for $entity in $entities return fadpt:represent_provider_as_practitioner_JSON($doc,$entity)
      else for $entity in $entities return fadpt:represent_provider_as_practitioner($doc,$entity)
  case "Location"
    return
      if ($format = ('application/json+fhir' ,  'application/json' ,'json'))
      then for $entity in $entities return  fadpt:represent_facility_as_location_JSON($doc,$entity)
      else for $entity in $entities return  fadpt:represent_facility_as_location($doc,$entity)
  case "Organization"
    return
	if ($format = ('application/json+fhir' ,  'application/json' ,'json'))
	then for $entity in $entities return  fadpt:represent_organization_as_organization_JSON($doc,$entity)
	else for $entity in $entities return  fadpt:represent_organization_as_organization($doc,$entity)
  default return ()
};

declare function fadpt:create_feed_from_entities($entities,$requestParams) {
  let $search_name := string($requestParams/@function)
  let $doc_name := string($requestParams/@resource)
  let $base_url := string($requestParams/@base_url)
  let $function := csr_proc:get_function_definition($csd_webconf:db,$search_name)
  let $entity := string(($function/csd:extension[ @urn='urn:openhie.org:openinfoman:adapter:fhir:read']/@type)[1])
  let $link := concat(fadpt:get_base_url($search_name,$base_url),'/' , $doc_name ,'/',$entity )
  let $title := concat("CSD entity as FHIR ",$entity)
  return
  <atom:feed>
    <atom:title>{$title}</atom:title>
    <atom:link href="{$link}" rel="self"/>
    <atom:updated>{current-dateTime()}</atom:updated>
     {
       for $entity in $entities
       let $ent_link := concat($link,"/", ($entity//fhir:identifier)[1])
       return
         <atom:entry>
	   <atom:link href="{$ent_link}"/>
	   <atom:content type="text/xml">{$entity}</atom:content>
	 </atom:entry>
     }
  </atom:feed>

};

declare function fadpt:create_feed_from_entities_JSON($entities,$requestParams) {
  let $search_name := string($requestParams/@function)
  let $doc_name := string($requestParams/@resource)
  let $base_url := string($requestParams/@base_url)
  let $function := csr_proc:get_function_definition($csd_webconf:db,$search_name)
  let $entity := string(($function/csd:extension[ @urn='urn:openhie.org:openinfoman:adapter:fhir:read']/@type)[1])
  let $link := concat(fadpt:get_base_url($search_name,$base_url),'/' , $doc_name ,'/',$entity )
  let $title := concat("CSD entity as FHIR ",$entity)
  return
  <atom:feed>
    <atom:title>{$title}</atom:title>
    <atom:link href="{$link}" rel="self"/>
    <atom:updated>{current-dateTime()}</atom:updated>
     {
       for $entity in $entities
       return
         <atom:entry>
	   <atom:content type="application/json">{$entity}</atom:content>
	 </atom:entry>
     }
  </atom:feed>

};

(:
   Function to turn a CSD Organization entity into a FHIR Organization
:)

declare function fadpt:represent_organization_as_organization($doc,$organization)
{
  (: See http://www.hl7.org/implement/standards/fhir/organization.html :)
  <fhir:Organization >
    <fhir:identifier>{string($organization/@urn)}</fhir:identifier>
    <fhir:name>{($organization/csd:primaryName)[1]/text()}</fhir:name>
    {
      (
       (: Note: nothing readily apparent for description :)
       (:Note:  FHIR allows only one facility type:)
       for $type in  ($organization/csd:codedType)[1]
       return  <fhir:type><fhir:coding><fhir:system>urn:oid:{string($type/@codingScheme)}</fhir:system><fhir:code>{string($type/@code)}</fhir:code></fhir:coding></fhir:type>
       ,
       for $contact in  $organization/csd:contactPoint/csd:codedType
       return
        <fhir:telecom>
	  <fhir:system value="urn:oid:{string($contact/@code)}"/>
	  <fhir:value value="{$contact/text()}"/>
	</fhir:telecom>
       ,
       (: Note: address is a bit weird.. which address? FHIR only allows for one. In CSD a provider
          can have a practice address as well as be assocaited to multiple facilities, each with their own address:)
       let $address :=  ($organization/csd:address[@type='Practice'])[1]
       return
	 if (exists($address))
	 then
	   <fhir:address>
	     {(
	       for $al in $address/csd:addressLine[@component = 'streetAddress']
	       return <fhir:line>{$al/text()}</fhir:line>
	       ,
	       for $city in ($address/csd:addressLine[@component = 'city'])[1]
	       return <fhir:city>{$city/text()}</fhir:city>
	       ,
	       for $state in ($address/csd:addressLine[@component = 'stateProvince'])[1]
	       return <fhir:state>{$state/text()}</fhir:state>
	       ,
	       for $zip in ($address/csd:addressLine[@component = 'postalCode'])[1]
	       return <fhir:zip>{$zip/text()}</fhir:zip>
	       ,
	       for $country in ($address/csd:addressLine[@component = 'country'])[1]
	       return <fhir:country>{$country /text()}</fhir:country>
	     )}
           </fhir:address>
	 else ()
	,
	(:  Note: FHIR only permits one managinh organization but CSD has many :)
	for $org in ($organization/csd:parent)[1]
	   (: Note: base for URL for reference should maybe be handled by stored function extension metadata   :)
	   return <fhir:partOf><fhir:reference>{string($org/@urn)}</fhir:reference></fhir:partOf>
	,
	(:May need to map codes :)
        <fhir:status>{string($organization/csd:record/@status)}</fhir:status>
	(:Note nothing immediately obvious for FHIR partOf or for FHIR mode :)
     )
    }

  </fhir:Organization>
};

(:
   Function to turn a CSD Facility entity into a FHIR Location
:)

declare function fadpt:represent_facility_as_location($doc,$facility)
{
  (: See http://www.hl7.org/implement/standards/fhir/location.html :)
  <fhir:Location >
    <fhir:identifier>{string($facility/@urn)}</fhir:identifier>
    <fhir:name>{($facility/csd:primaryName)[1]/text()}</fhir:name>
    {
      (
       (: Note: nothing readily apparent for description :)
       (:Note:  FHIR allows only one facility type:)
       for $type in  ($facility/csd:codedType)[1]
       return  <fhir:type><fhir:coding><fhir:system>urn:oid:{string($type/@codingScheme)}</fhir:system><fhir:code>{string($type/@code)}</fhir:code></fhir:coding></fhir:type>
       ,
       for $contact in  $facility/csd:contactPoint/csd:codedType
       return
        <fhir:telecom>
	  <fhir:system value="urn:oid:{string($contact/@code)}"/>
	  <fhir:value value="{$contact/text()}"/>
	</fhir:telecom>
       ,
       (: Note: address is a bit weird.. which address? FHIR only allows for one. In CSD a provider
          can have a practice address as well as be assocaited to multiple facilities, each with their own address:)
       let $address :=  ($facility/csd:address[@type='Practice'])[1]
       return
	 if (exists($address))
	 then
	   <fhir:address>
	     {(
	       for $al in $address/csd:addressLine[@component = 'streetAddress']
	       return <fhir:line>{$al/text()}</fhir:line>
	       ,
	       for $city in ($address/csd:addressLine[@component = 'city'])[1]
	       return <fhir:city>{$city/text()}</fhir:city>
	       ,
	       for $state in ($address/csd:addressLine[@component = 'stateProvince'])[1]
	       return <fhir:state>{$state/text()}</fhir:state>
	       ,
	       for $zip in ($address/csd:addressLine[@component = 'postalCode'])[1]
	       return <fhir:zip>{$zip/text()}</fhir:zip>
	       ,
	       for $country in ($address/csd:addressLine[@component = 'country'])[1]
	       return <fhir:country>{$country /text()}</fhir:country>
	     )}
           </fhir:address>
	 else ()
	,
        (: Note: nothing immediate for Physical type :)
	if (exists($facility/csd:geocode)) then
	  <fhir:position>
	    <fhir:longitude>{$facility/csd:geocode/csd:longitude}</fhir:longitude>
	    <fhir:latitude>{$facility/csd:geocode/csd:latitude}</fhir:latitude>
	    <fhir:altitude>{$facility/csd:geocode/csd:altitude}</fhir:altitude>
	  </fhir:position>
	else ()
	,
	(:  Note: FHIR only permits one managinh organization but CSD has many :)
	for $org in ($facility/csd:organizations/csd:organization)[1]
	   (: Note: base for URL for reference should maybe be handled by stored function extension metadata   :)
	   return <fhir:managingOrganization><fhir:reference>{string($org/@urn)}</fhir:reference></fhir:managingOrganization>
	,
	(:May need to map codes :)
        <fhir:status>{string($facility/csd:record/@status)}</fhir:status>
	(:Note nothing immediately obvious for FHIR partOf or for FHIR mode :)
     )
    }

  </fhir:Location>
};

(:
   Function to turn a CSD Provider entity into a FHIR Practitioner
:)

declare function fadpt:represent_provider_as_practitioner($doc,$provider)
{
  (: See http://www.hl7.org/implement/standards/fhir/practitioner.html :)
  <fhir:Practitioner >
    <fhir:identifier><fhir:value>{string($provider/@urn)}</fhir:value><fhir:assigner>{string($provider/csd:record/@sourceDirectory)}</fhir:assigner></fhir:identifier>
    {
      for $otherID in $provider/csd:otherID
      let $auth := string($otherID/@assigningAuthorityName)
      let $code := string($otherID/@code)
      return <fhir:identifier><fhir:value>{$code}</fhir:value><fhir:assigner>{$auth}</fhir:assigner></fhir:identifier>
    }
    {
        for $name in ($provider/csd:demographic/csd:name)[1] (:why does FHIR only allow one fhir:text and name element :)
	let $cn := ($name/csd:commonName)[1]/text()
	let $sn := ($name/csd:surname)[1]/text()
	let $gn := ($name/csd:forename)[1]/text()
	let $hon := ($name/csd:honorific)[1]/text()
	return
	  <fhir:name>
	    <fhir:text value="{$cn}"/>
	    <fhir:family value="{$sn}"/>
	    <fhir:given value="{$gn}"/>
	    <fhir:prefix value="{$hon}"/>
	  </fhir:name>
    }
    {
      (
       for $contact in  $provider/csd:demographic/csd:contactPoint/csd:codedType
       return
        <fhir:telecom>
	  <fhir:system value="urn:oid:{string($contact/@code)}"/>
	  <fhir:value value="{$contact/text()}"/>
	</fhir:telecom>
       ,
       (: Note: address is a bit weird.. which address? FHIR only allows for one. In CSD a provider
          can have a practice address as well as be assocaited to multiple facilities, each with their own address:)
       let $address :=  ($provider/csd:demographic/csd:address[@type='Practice'])[1]
       return
	 if (exists($address))
	 then
	   <fhir:address>
	     {(
	       for $al in $address/csd:addressLine[@component = 'streetAddress']
	       return <fhir:line>{$al/text()}</fhir:line>
	       ,
	       for $city in ($address/csd:addressLine[@component = 'city'])[1]
	       return <fhir:city>{$city/text()}</fhir:city>
	       ,
	       for $state in ($address/csd:addressLine[@component = 'stateProvince'])[1]
	       return <fhir:state>{$state/text()}</fhir:state>
	       ,
	       for $zip in ($address/csd:addressLine[@component = 'postalCode'])[1]
	       return <fhir:zip>{$zip/text()}</fhir:zip>
	       ,
	       for $country in ($address/csd:addressLine[@component = 'country'])[1]
	       return <fhir:country>{$country /text()}</fhir:country>
	     )}
           </fhir:address>
	 else ()
	,
	(: Note: what code set should we use in our output? :)
	let $gender := ($provider/csd:demographic/csd:gender)[1]
	return
	  if (exists($gender))  then
	    <fhir:gender>{$gender/text()}
	      <fhir:coding>
		<fhir:system>urn:oid:2.25.309768652999692686176651983274504471835.999.403</fhir:system>
		<fhir:code>{$gender/text()}</fhir:code>
	      </fhir:coding>
	    </fhir:gender>
	  else ()
	,
	let $dob := ($provider/csd:demographic/csd:dateOfBirth)[1]
	return
	  if (exists($dob))  then  <fhir:birthDate>{$dob/text()}</fhir:birthDate>
	  else ()
	,
	(:  Note: note supported under standard CSD   <photo><!-- 0..* Attachment Image of the person --></photo>  :)
	for $org in ($provider/csd:organizations/csd:organization)
	  (: Note: base for URL for reference should maybe be handled by stored function extension metadata   :)
	  (:              see http://www.hl7.org/implement/standards/fhir/base-definitions.html#ResourceReference.reference :)
	return <fhir:organization><fhir:reference>{string($org/@urn)}</fhir:reference></fhir:organization>
	,
	(: Note: perhaps this should be for services -- see remark below on <fhir:period/> :)
	for $role in ($provider/csd:codedType)
	return <fhir:role><fhir:coding><fhir:system>urn:oid:{string($role/@codingScheme)}</fhir:system><fhir:code>{string($role/@code)}</fhir:code></fhir:coding></fhir:role>
	,
	for $specialty in ($provider/csd:specialty)
	return <fhir:specialty><fhir:coding><fhir:system>{string($specialty/@codingScheme)}</fhir:system><fhir:code>{string($specialty/@code)}</fhir:code></fhir:coding></fhir:specialty>
	,
	(: Note: note supported <period><!-- 0..1 Period      The period during which the practitioner is authorized to perform in these role(s) § --></period>
           unless we interpret the <fhir:role/> element as a service
	:)
	for $fac in ($provider/csd:facilities/csd:facility)
	   (: Note: base for URL for reference should maybe be handled by stored function extension metadata   :)
	  (:              see http://www.hl7.org/implement/standards/fhir/base-definitions.html#ResourceReference.reference :)
	return <fhir:location><fhir:reference>{string($fac/@urn)}</fhir:reference></fhir:location>
	,
	for $qual in ($provider/csd:credential)
	return
	  <fhir:qualification>
	    <fhir:code><fhir:coding><fhir:system>urn:oid:{string($qual/@codingScheme)}</fhir:system><fhir:code>{string($qual/@code)}</fhir:code></fhir:coding></fhir:code>
	    <fhir:period>
	       {if (exists($qual/csd:credenitalIssueDate)) then   <fhir:start>{$qual/csd:credenitalIssueDate}</fhir:start> else ()}
	       {if (exists($qual/csd:credentialRenewalDate)) then  <fhir:end>{$qual/csd:credentialRenewalDate}</fhir:end> else ()}
	    </fhir:period>
	    {
	      (:Note: I don't think this is quite correct.  It wants it to be an organization ID :)
	      if (exists($qual/csd:issuingAuthority)) then <fhir:issuer><fhir:reference>{$qual/csd:issuingAuthority/text()}</fhir:reference></fhir:issuer> else ()
	    }
	  </fhir:qualification>
       ,
       for $lang in $provider/csd:language
       return  <fhir:communication><fhir:coding><fhir:system>urn:oid:{string($lang/@codingScheme)}</fhir:system><fhir:code>{string($lang/@code)}</fhir:code></fhir:coding></fhir:communication>
     )
    }

  </fhir:Practitioner>
};

(:
   Function to turn a CSD Facility  entity into a FHIR Location as JSON
:)

declare function fadpt:represent_facility_as_location_JSON($doc,$facility) {
  fadpt:represent_facility_as_location_JSON($doc,$facility,false())
};

declare function fadpt:represent_facility_as_location_JSON($doc,$facility,$as_xml)
{
  let $xml:=
    <json  type="object">
      <resourceType>Location</resourceType>
      <identifier type="array">
      <_ type="object">
	<value>{string($facility/@urn)}</value>
	<assigner>{string($facility/csd:record/@sourceDirectory)}</assigner>
	</_>
	{
	  for $otherID in $facility/csd:otherID
	  let $auth := string($otherID/@assigningAuthorityName)
	  let $code := string($otherID/@code)
	  return
	    <_ type="object">
	      <value>{$code}</value>
	      <assigner>{$auth}</assigner>
	    </_>
	}
      </identifier>
      <name>{($facility/csd:primaryName)[1]/text()}</name>
      <type type="array">
	{
	  for $role in ($facility/csd:codedType)
	  return
	    <_ type="object">
	      <coding type="array">
	        <_ type="object">
		  <system>urn:oid:{string($role/@codingScheme)}</system>
		  <code>{string($role/@code)}</code>
		</_>
	      </coding>
	    </_>
	}
      </type>
      <telecom type="array">
	{
	  for $contact in  $facility/csd:contactPoint/csd:codedType
	  return
	    <_ type="object">
	      <system>urn:oid:{string($contact/@code)}</system>
	      <value>{$contact/text()}</value>
	    </_>
	}
      </telecom>
      {
	for $address in ($facility/csd:demographic/csd:address[@type='Practice'])[1]
	return
	   <address type="object">
	     <use>{string($address/@type)}</use>
	     <line type="array">
	       {
		 for $al in $address/csd:addressLine[@component = 'streetAddress']
		 return <_>{$al/text()}</_>
	       }
	     </line>
	     {
	       for $city in ($address/csd:addressLine[@component = 'city'])[1]
	       return <city>{$city/text()}</city>
	     }
	     {
	       for $state in ($address/csd:addressLine[@component = 'stateProvince'])[1]
	       return <state>{$state/text()}</state>
	     }
	     {
	       for $zip in ($address/csd:addressLine[@component = 'postalCode'])[1]
	       return <zip>{$zip/text()}</zip>
	     }
	     {
	       for $country in ($address/csd:addressLine[@component = 'country'])[1]
	       return <country>{$country /text()}</country>
	     }
           </address>
      }
      {
	for $org in ($facility/csd:organizations/csd:organization)[1]
	   (: Note: base for URL for reference should maybe be handled by stored function extension metadata   :)
	   return <managingOrganization type="object"><reference>{string($org/@urn)}</reference></managingOrganization>
      }
      {
	switch ($facility/csd:record/@status)
	case "106-001" return <status>active</status>
	case "106-002" return <status>Inactive</status>
	default return ()
      }
    </json>

  return
    if ($as_xml)
    then $xml
    else json:serialize($xml,map{"format":"direct"})

};

(:
   Function to turn a CSD Organization entity into a FHIR Organization as JSON
:)

declare function fadpt:represent_organization_as_organization_JSON($doc,$organization) {
  fadpt:represent_organization_as_organization_JSON($doc,$organization,false())
};

declare function fadpt:represent_organization_as_organization_JSON($doc,$organization,$as_xml)
{
  let $xml:=
    <json  type="object">
      <resourceType>Organization</resourceType>
      <identifier type="array">
      <_ type="object">
	<value>{string($organization/@urn)}</value>
	<assigner>{string($organization/csd:record/@sourceDirectory)}</assigner>
	</_>
	{
	  for $otherID in $organization/csd:otherID
	  let $auth := string($otherID/@assigningAuthorityName)
	  let $code := string($otherID/@code)
	  return
	    <_ type="object">
	      <value>{$code}</value>
	      <assigner>{$auth}</assigner>
	    </_>
	}
      </identifier>
      <name>{($organization/csd:primaryName)[1]/text()}</name>
      <type type="array">
	{
	  for $role in ($organization/csd:codedType)
	  return
	    <_ type="object">
	      <coding type="array">
	        <_ type="object">
		  <system>urn:oid:{string($role/@codingScheme)}</system>
		  <code>{string($role/@code)}</code>
		</_>
	      </coding>
	    </_>
	}
      </type>
      <telecom type="array">
	{
	  for $contact in  $organization/csd:contactPoint/csd:codedType
	  return
	    <_ type="object">
	      <system>urn:oid:{string($contact/@code)}</system>
	      <value>{$contact/text()}</value>
	    </_>
	}
      </telecom>
      {
	for $address in ($organization/csd:demographic/csd:address[@type='Practice'])[1]
	return
	   <address type="object">
	     <use>{string($address/@type)}</use>
	     <line type="array">
	       {
		 for $al in $address/csd:addressLine[@component = 'streetAddress']
		 return <_>{$al/text()}</_>
	       }
	     </line>
	     {
	       for $city in ($address/csd:addressLine[@component = 'city'])[1]
	       return <city>{$city/text()}</city>
	     }
	     {
	       for $state in ($address/csd:addressLine[@component = 'stateProvince'])[1]
	       return <state>{$state/text()}</state>
	     }
	     {
	       for $zip in ($address/csd:addressLine[@component = 'postalCode'])[1]
	       return <zip>{$zip/text()}</zip>
	     }
	     {
	       for $country in ($address/csd:addressLine[@component = 'country'])[1]
	       return <country>{$country /text()}</country>
	     }
           </address>
      }
      {
	for $org in ($organization/csd:parent)[1]
	   (: Note: base for URL for reference should maybe be handled by stored function extension metadata   :)
	   return <partOf type="object"><reference>{string($org/@urn)}</reference></partOf>
      }
      {
	if ($organization/csd:record/@status = '106-001')
        then <status>1</status>
        else <status>0</status>
      }
    </json>

  return
    if ($as_xml)
    then $xml
    else json:serialize($xml,map{"format":"direct"})

};

(:
   Function to turn a CSD Provider entity into a FHIR Practitioner
:)

declare function fadpt:represent_provider_as_practitioner_JSON($doc,$provider) {
  fadpt:represent_provider_as_practitioner_JSON($doc,$provider,false())
};

declare function fadpt:represent_provider_as_practitioner_JSON($doc,$provider,$as_xml)
{
  let $xml:=
    <json  type="object">
      <resourceType>Practitioner</resourceType>
      <identifier type="array">
      <_ type="object">
	<value>{string($provider/@urn)}</value>
	<assigner>{string($provider/csd:record/@sourceDirectory)}</assigner>
	</_>
	{
	  for $otherID in $provider/csd:otherID
	  let $auth := string($otherID/@assigningAuthorityName)
	  let $code := string($otherID/@code)
	  return
	    <_ type="object">
	      <value>{$code}</value>
	      <assigner>{$auth}</assigner>
	    </_>
	}
      </identifier>
      {
        for $name in ($provider/csd:demographic/csd:name)[1] (:why does FHIR only allow one fhir:text and name element :)
	let $cn := ($name/csd:commonName)[1]/text()
	let $sn := ($name/csd:surname)[1]/text()
	let $gn := ($name/csd:forename)[1]/text()
	let $hon := ($name/csd:honorific)[1]/text()
	return
	  <name type="object">
	    {if ($cn != '') then <text>{$cn}</text> else () }
	    {if ($sn != '') then <family type="array"><_>{$sn}</_></family> else () }
	    { if ($gn != '') then <given type="array"><_>{$gn}</_></given> else ()}
	    { if ($hon != '') then  <prefix type="array"><_>{$hon}</_></prefix> else ()}
	  </name>
      }
      {
	if (count($provider/csd:demographic/csd:contactPoint/csd:codedType) >0)
	then
  	  <telecom type="array">
	    {
	      for $contact in  $provider/csd:demographic/csd:contactPoint/csd:codedType
	      return
		<_ type="object">
		  <system>{string($contact/@code)}</system>
		  <value>{$contact/text()}</value>
		  </_>
	    }
	  </telecom>
	else ()
      }
      {
	for $address in ($provider/csd:demographic/csd:address[@type='Practice'])[1]
	return
	   <address type="object">
	     <use>{string($address/@type)}</use>
	     {
	       if (count( $address/csd:addressLine[@component = 'streetAddress']) > 0)
	       then
	         <line type="array">
		   {
		     for $al in $address/csd:addressLine[@component = 'streetAddress']
		     return <_>{$al/text()}</_>
		   }
		 </line>
	       else ()
             }
	     {
	       for $city in ($address/csd:addressLine[@component = 'city'])[1]
	       return <city>{$city/text()}</city>
	     }
	     {
	       for $state in ($address/csd:addressLine[@component = 'stateProvince'])[1]
	       return <state>{$state/text()}</state>
	     }
	     {
	       for $zip in ($address/csd:addressLine[@component = 'postalCode'])[1]
	       return <zip>{$zip/text()}</zip>
	     }
	     {
	       for $country in ($address/csd:addressLine[@component = 'country'])[1]
	       return <country>{$country /text()}</country>
	     }
           </address>
      }
      {
	for  $gender in ($provider/csd:demographic/csd:gender)[1]
	return
	<gender type="object">
	  <coding type="array">
	    <_ type="object">
	      <system>urn:oid:2.25.309768652999692686176651983274504471835.999.403</system>
	      <code>{$gender/text()}</code>
	    </_>
	  </coding>
	</gender>
      }
      {
	for $dob in ($provider/csd:demographic/csd:dateOfBirth)[1]
	return  <birthDate>{$dob/text()}</birthDate>
      }
      {
	(: Note: base for URL for reference should maybe be handled by stored function extension metadata   :)
	(:              see http://www.hl7.org/implement/standards/fhir/base-definitions.html#ResourceReference.reference :)
	(: maybe we should use cross-referenced /CSD/organizationDirectory/organization/primaryName ? :)
	(: FHIR only allows one :)
	for $org in ($provider/csd:organizations/csd:organization)[1]
	return
	  <organization type="object">
	    <reference>{string($org/@urn)}</reference>
	  </organization>

      }
      {
	if (count($provider/csd:codedType) > 0)
	then
	  <role type="array">
	    {
	      for $role in ($provider/csd:codedType)
	      return
		<_ type="object">
		  <coding type="array">
	          <_ type="object">
		    <system>urn:oid:{string($role/@codingScheme)}</system>
		    <code>{string($role/@code)}</code>
		    </_>
		  </coding>
	    </_>
	    }
	  </role>
	else ()
      }
      {
	if (count($provider/csd:specialty) > 0)
	then <specialty type="array">
          {
	    for $specialty in ($provider/csd:specialty)
	    return
	      <_ type="object">
		<coding type="array">
	        <_ type="object">
		  <system>urn:oid{string($specialty/@codingScheme)}</system>
		  <code>{string($specialty/@code)}</code>
		  </_>
		</coding>
		</_>
	    }
	  </specialty>
	else ()
      }
      {
	if (count($provider/csd:facilities/csd:facility) > 0)
	then <location type="array">
	  {
	    (: Note: base for URL for reference should maybe be handled by stored function extension metadata
             see http://www.hl7.org/implement/standards/fhir/base-definitions.html#ResourceReference.reference
	     :)
	     for $fac in ($provider/csd:facilities/csd:facility)
	     return
	       <_ type="object">
		 <reference>{string($fac/@urn)}</reference>
		 </_>
	    }
	    </location>
	  else ()
       }
       {
	 if (count($provider/csd:credential) > 0)
	 then <qualification type="array">
	    {
	      for $qual in ($provider/csd:credential)
	      return
		<_ type="object">
		  <code type="object">
		    <coding type="array">
	            <_ type="object">
		      <system>urn:oid:{string($qual/@codingScheme)}</system>
		      <code>{string($qual/@code)}</code>
		      </_>
		    </coding>
		  </code>
		  <period type="object">
                    {if (exists($qual/csd:credenitalIssueDate)) then   <start>{$qual/csd:credenitalIssueDate/text()}</start> else ()}
		    {if (exists($qual/csd:credentialRenewalDate)) then  <end>{$qual/csd:credentialRenewalDate/text()}</end> else ()}
		  </period>
	       {
		(:Note: I don't think this is quite correct.  It wants it to be an organization ID :)
		if (exists($qual/csd:issuingAuthority[1]))
		then
	          <issuer type="object">
		    <reference>Assigning Authority/{$qual/csd:issuingAuthority[1]/text()}</reference>
		  </issuer>
		else ()
	        }
	      </_>
	    }
	  </qualification>
	else ()
      }
      {
        if (count($provider/csd:language) > 0)
	then <communication type="array">
	  {
	    for $lang in $provider/csd:language
	    return
	      <_ type="object">
		<coding type="array">
	        <_ type="object">
		  <system>urn:oid:{string($lang/@codingScheme)}</system>
		  <code>{string($lang/@code)}</code>
		  </_>
		</coding>
		</_>
	    }
  	  </communication>
	else ()
       }

    </json>

  return
    if ($as_xml)
    then $xml
    else json:serialize($xml,map{"format":"direct"})
};

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

(:Import other namespaces.  Set default namespace  to os :)
import module namespace csd_webconf =  "https://github.com/openhie/openinfoman/csd_webconf";
import module namespace csr_proc = "https://github.com/openhie/openinfoman/csr_proc";
import module namespace csd_dm = "https://github.com/openhie/openinfoman/csd_dm";

declare namespace csd = "urn:ihe:iti:csd:2013";
declare namespace atom = "http://www.w3.org/2005/Atom";
declare namespace fhir = "http://hl7.org/fhir";

declare function fadpt:is_fhir_function($search_name) {
  let $function := csr_proc:get_function_definition($csd_webconf:db,$search_name)
  let $ext := $function//csd:extension[  @urn='urn:openhie.org:openinfoman:adapter' and @type='fhir']
  return (count($ext) > 0)
};

declare function fadpt:has_feed($search_name,$doc_name) {
  (fadpt:is_fhir_function($search_name) and csd_dm:document_source_exists($csd_webconf:db ,$doc_name))
};

declare function fadpt:get_base_url($search_name) {
  fadpt:get_base_url($search_name,$csd_webconf:baseurl)
};
declare function fadpt:get_base_url($search_name,$base_url) {
  concat($base_url,'CSD/adapter/fhir/' ,$search_name)
};

declare function fadpt:format_entities($doc,$entities,$entityType,$format) {
  switch ($entityType)
  case "Practitioner"
    return
      if ($format = ('application/json+fhir' ,  'application/json' ,'json'))
      then for $entity in $entities return fadpt:represent_provider_as_practitioner_JSON($doc,$entity)
      else for $entity in $entities return fadpt:represent_provider_as_practitioner($doc,$entity)
  case "Location"
    return
      if ($format = ('application/json+fhir' ,  'application/json' ,'json'))
      then for $entity in $entities return  fadpt:represent_facility_as_location_JSON($doc,$entity)
      else for $entity in $entities return  fadpt:represent_facility_as_location($doc,$entity)
  case "Organization"
    return
	if ($format = ('application/json+fhir' ,  'application/json' ,'json'))
	then for $entity in $entities return  fadpt:represent_organization_as_organization_JSON($doc,$entity)
	else for $entity in $entities return  fadpt:represent_organization_as_organization($doc,$entity)
  default return ()
};

declare function fadpt:create_feed_from_entities($entities,$requestParams) {
  let $search_name := string($requestParams/@function)
  let $doc_name := string($requestParams/@resource)
  let $base_url := string($requestParams/@base_url)
  let $function := csr_proc:get_function_definition($csd_webconf:db,$search_name)
  let $entity := string(($function/csd:extension[ @urn='urn:openhie.org:openinfoman:adapter:fhir:read']/@type)[1])
  let $link := concat(fadpt:get_base_url($search_name,$base_url),'/' , $doc_name ,'/',$entity )
  let $title := concat("CSD entity as FHIR ",$entity)
  return
  <atom:feed>
    <atom:title>{$title}</atom:title>
    <atom:link href="{$link}" rel="self"/>
    <atom:updated>{current-dateTime()}</atom:updated>
     {
       for $entity in $entities
       let $ent_link := concat($link,"/", ($entity//fhir:identifier)[1])
       return
         <atom:entry>
	   <atom:link href="{$ent_link}"/>
	   <atom:content type="text/xml">{$entity}</atom:content>
	 </atom:entry>
     }
  </atom:feed>

};

declare function fadpt:create_feed_from_entities_JSON($entities,$requestParams) {
  let $search_name := string($requestParams/@function)
  let $doc_name := string($requestParams/@resource)
  let $base_url := string($requestParams/@base_url)
  let $function := csr_proc:get_function_definition($csd_webconf:db,$search_name)
  let $entity := string(($function/csd:extension[ @urn='urn:openhie.org:openinfoman:adapter:fhir:read']/@type)[1])
  let $link := concat(fadpt:get_base_url($search_name,$base_url),'/' , $doc_name ,'/',$entity )
  let $title := concat("CSD entity as FHIR ",$entity)
  return
  <atom:feed>
    <atom:title>{$title}</atom:title>
    <atom:link href="{$link}" rel="self"/>
    <atom:updated>{current-dateTime()}</atom:updated>
     {
       for $entity in $entities
       return
         <atom:entry>
	   <atom:content type="application/json">{$entity}</atom:content>
	 </atom:entry>
     }
  </atom:feed>

};

(:
   Function to turn a CSD Organization entity into a FHIR Organization
:)

declare function fadpt:represent_organization_as_organization($doc,$organization)
{
  (: See http://www.hl7.org/implement/standards/fhir/organization.html :)
  <fhir:Organization >
    <fhir:identifier>{string($organization/@urn)}</fhir:identifier>
    <fhir:name>{($organization/csd:primaryName)[1]/text()}</fhir:name>
    {
      (
       (: Note: nothing readily apparent for description :)
       (:Note:  FHIR allows only one facility type:)
       for $type in  ($organization/csd:codedType)[1]
       return  <fhir:type><fhir:coding><fhir:system>urn:oid:{string($type/@codingScheme)}</fhir:system><fhir:code>{string($type/@code)}</fhir:code></fhir:coding></fhir:type>
       ,
       for $contact in  $organization/csd:contactPoint/csd:codedType
       return
        <fhir:telecom>
	  <fhir:system value="urn:oid:{string($contact/@code)}"/>
	  <fhir:value value="{$contact/text()}"/>
	</fhir:telecom>
       ,
       (: Note: address is a bit weird.. which address? FHIR only allows for one. In CSD a provider
          can have a practice address as well as be assocaited to multiple facilities, each with their own address:)
       let $address :=  ($organization/csd:address[@type='Practice'])[1]
       return
	 if (exists($address))
	 then
	   <fhir:address>
	     {(
	       for $al in $address/csd:addressLine[@component = 'streetAddress']
	       return <fhir:line>{$al/text()}</fhir:line>
	       ,
	       for $city in ($address/csd:addressLine[@component = 'city'])[1]
	       return <fhir:city>{$city/text()}</fhir:city>
	       ,
	       for $state in ($address/csd:addressLine[@component = 'stateProvince'])[1]
	       return <fhir:state>{$state/text()}</fhir:state>
	       ,
	       for $zip in ($address/csd:addressLine[@component = 'postalCode'])[1]
	       return <fhir:zip>{$zip/text()}</fhir:zip>
	       ,
	       for $country in ($address/csd:addressLine[@component = 'country'])[1]
	       return <fhir:country>{$country /text()}</fhir:country>
	     )}
           </fhir:address>
	 else ()
	,
	(:  Note: FHIR only permits one managinh organization but CSD has many :)
	for $org in ($organization/csd:parent)[1]
	   (: Note: base for URL for reference should maybe be handled by stored function extension metadata   :)
	   return <fhir:partOf><fhir:reference>{string($org/@urn)}</fhir:reference></fhir:partOf>
	,
	(:May need to map codes :)
        <fhir:status>{string($organization/csd:record/@status)}</fhir:status>
	(:Note nothing immediately obvious for FHIR partOf or for FHIR mode :)
     )
    }

  </fhir:Organization>
};

(:
   Function to turn a CSD Facility entity into a FHIR Location
:)

declare function fadpt:represent_facility_as_location($doc,$facility)
{
  (: See http://www.hl7.org/implement/standards/fhir/location.html :)
  <fhir:Location >
    <fhir:identifier>{string($facility/@urn)}</fhir:identifier>
    <fhir:name>{($facility/csd:primaryName)[1]/text()}</fhir:name>
    {
      (
       (: Note: nothing readily apparent for description :)
       (:Note:  FHIR allows only one facility type:)
       for $type in  ($facility/csd:codedType)[1]
       return  <fhir:type><fhir:coding><fhir:system>urn:oid:{string($type/@codingScheme)}</fhir:system><fhir:code>{string($type/@code)}</fhir:code></fhir:coding></fhir:type>
       ,
       for $contact in  $facility/csd:contactPoint/csd:codedType
       return
        <fhir:telecom>
	  <fhir:system value="urn:oid:{string($contact/@code)}"/>
	  <fhir:value value="{$contact/text()}"/>
	</fhir:telecom>
       ,
       (: Note: address is a bit weird.. which address? FHIR only allows for one. In CSD a provider
          can have a practice address as well as be assocaited to multiple facilities, each with their own address:)
       let $address :=  ($facility/csd:address[@type='Practice'])[1]
       return
	 if (exists($address))
	 then
	   <fhir:address>
	     {(
	       for $al in $address/csd:addressLine[@component = 'streetAddress']
	       return <fhir:line>{$al/text()}</fhir:line>
	       ,
	       for $city in ($address/csd:addressLine[@component = 'city'])[1]
	       return <fhir:city>{$city/text()}</fhir:city>
	       ,
	       for $state in ($address/csd:addressLine[@component = 'stateProvince'])[1]
	       return <fhir:state>{$state/text()}</fhir:state>
	       ,
	       for $zip in ($address/csd:addressLine[@component = 'postalCode'])[1]
	       return <fhir:zip>{$zip/text()}</fhir:zip>
	       ,
	       for $country in ($address/csd:addressLine[@component = 'country'])[1]
	       return <fhir:country>{$country /text()}</fhir:country>
	     )}
           </fhir:address>
	 else ()
	,
        (: Note: nothing immediate for Physical type :)
	if (exists($facility/csd:geocode)) then
	  <fhir:position>
	    <fhir:longitude>{$facility/csd:geocode/csd:longitude}</fhir:longitude>
	    <fhir:latitude>{$facility/csd:geocode/csd:latitude}</fhir:latitude>
	    <fhir:altitude>{$facility/csd:geocode/csd:altitude}</fhir:altitude>
	  </fhir:position>
	else ()
	,
	(:  Note: FHIR only permits one managinh organization but CSD has many :)
	for $org in ($facility/csd:organizations/csd:organization)[1]
	   (: Note: base for URL for reference should maybe be handled by stored function extension metadata   :)
	   return <fhir:managingOrganization><fhir:reference>{string($org/@urn)}</fhir:reference></fhir:managingOrganization>
	,
	(:May need to map codes :)
        <fhir:status>{string($facility/csd:record/@status)}</fhir:status>
	(:Note nothing immediately obvious for FHIR partOf or for FHIR mode :)
     )
    }

  </fhir:Location>
};

(:
   Function to turn a CSD Provider entity into a FHIR Practitioner
:)

declare function fadpt:represent_provider_as_practitioner($doc,$provider)
{
  (: See http://www.hl7.org/implement/standards/fhir/practitioner.html :)
  <fhir:Practitioner >
    <fhir:identifier><fhir:value>{string($provider/@urn)}</fhir:value><fhir:assigner>{string($provider/csd:record/@sourceDirectory)}</fhir:assigner></fhir:identifier>
    {
      for $otherID in $provider/csd:otherID
      let $auth := string($otherID/@assigningAuthorityName)
      let $code := string($otherID/@code)
      return <fhir:identifier><fhir:value>{$code}</fhir:value><fhir:assigner>{$auth}</fhir:assigner></fhir:identifier>
    }
    {
        for $name in ($provider/csd:demographic/csd:name)[1] (:why does FHIR only allow one fhir:text and name element :)
	let $cn := ($name/csd:commonName)[1]/text()
	let $sn := ($name/csd:surname)[1]/text()
	let $gn := ($name/csd:forename)[1]/text()
	let $hon := ($name/csd:honorific)[1]/text()
	return
	  <fhir:name>
	    <fhir:text value="{$cn}"/>
	    <fhir:family value="{$sn}"/>
	    <fhir:given value="{$gn}"/>
	    <fhir:prefix value="{$hon}"/>
	  </fhir:name>
    }
    {
      (
       for $contact in  $provider/csd:demographic/csd:contactPoint/csd:codedType
       return
        <fhir:telecom>
	  <fhir:system value="urn:oid:{string($contact/@code)}"/>
	  <fhir:value value="{$contact/text()}"/>
	</fhir:telecom>
       ,
       (: Note: address is a bit weird.. which address? FHIR only allows for one. In CSD a provider
          can have a practice address as well as be assocaited to multiple facilities, each with their own address:)
       let $address :=  ($provider/csd:demographic/csd:address[@type='Practice'])[1]
       return
	 if (exists($address))
	 then
	   <fhir:address>
	     {(
	       for $al in $address/csd:addressLine[@component = 'streetAddress']
	       return <fhir:line>{$al/text()}</fhir:line>
	       ,
	       for $city in ($address/csd:addressLine[@component = 'city'])[1]
	       return <fhir:city>{$city/text()}</fhir:city>
	       ,
	       for $state in ($address/csd:addressLine[@component = 'stateProvince'])[1]
	       return <fhir:state>{$state/text()}</fhir:state>
	       ,
	       for $zip in ($address/csd:addressLine[@component = 'postalCode'])[1]
	       return <fhir:zip>{$zip/text()}</fhir:zip>
	       ,
	       for $country in ($address/csd:addressLine[@component = 'country'])[1]
	       return <fhir:country>{$country /text()}</fhir:country>
	     )}
           </fhir:address>
	 else ()
	,
	(: Note: what code set should we use in our output? :)
	let $gender := ($provider/csd:demographic/csd:gender)[1]
	return
	  if (exists($gender))  then
	    <fhir:gender>{$gender/text()}
	      <fhir:coding>
		<fhir:system>urn:oid:2.25.309768652999692686176651983274504471835.999.403</fhir:system>
		<fhir:code>{$gender/text()}</fhir:code>
	      </fhir:coding>
	    </fhir:gender>
	  else ()
	,
	let $dob := ($provider/csd:demographic/csd:dateOfBirth)[1]
	return
	  if (exists($dob))  then  <fhir:birthDate>{$dob/text()}</fhir:birthDate>
	  else ()
	,
	(:  Note: note supported under standard CSD   <photo><!-- 0..* Attachment Image of the person --></photo>  :)
	for $org in ($provider/csd:organizations/csd:organization)
	  (: Note: base for URL for reference should maybe be handled by stored function extension metadata   :)
	  (:              see http://www.hl7.org/implement/standards/fhir/base-definitions.html#ResourceReference.reference :)
	return <fhir:organization><fhir:reference>{string($org/@urn)}</fhir:reference></fhir:organization>
	,
	(: Note: perhaps this should be for services -- see remark below on <fhir:period/> :)
	for $role in ($provider/csd:codedType)
	return <fhir:role><fhir:coding><fhir:system>urn:oid:{string($role/@codingScheme)}</fhir:system><fhir:code>{string($role/@code)}</fhir:code></fhir:coding></fhir:role>
	,
	for $specialty in ($provider/csd:specialty)
	return <fhir:specialty><fhir:coding><fhir:system>{string($specialty/@codingScheme)}</fhir:system><fhir:code>{string($specialty/@code)}</fhir:code></fhir:coding></fhir:specialty>
	,
	(: Note: note supported <period><!-- 0..1 Period      The period during which the practitioner is authorized to perform in these role(s) § --></period>
           unless we interpret the <fhir:role/> element as a service
	:)
	for $fac in ($provider/csd:facilities/csd:facility)
	   (: Note: base for URL for reference should maybe be handled by stored function extension metadata   :)
	  (:              see http://www.hl7.org/implement/standards/fhir/base-definitions.html#ResourceReference.reference :)
	return <fhir:location><fhir:reference>{string($fac/@urn)}</fhir:reference></fhir:location>
	,
	for $qual in ($provider/csd:credential)
	return
	  <fhir:qualification>
	    <fhir:code><fhir:coding><fhir:system>urn:oid:{string($qual/@codingScheme)}</fhir:system><fhir:code>{string($qual/@code)}</fhir:code></fhir:coding></fhir:code>
	    <fhir:period>
	       {if (exists($qual/csd:credenitalIssueDate)) then   <fhir:start>{$qual/csd:credenitalIssueDate}</fhir:start> else ()}
	       {if (exists($qual/csd:credentialRenewalDate)) then  <fhir:end>{$qual/csd:credentialRenewalDate}</fhir:end> else ()}
	    </fhir:period>
	    {
	      (:Note: I don't think this is quite correct.  It wants it to be an organization ID :)
	      if (exists($qual/csd:issuingAuthority)) then <fhir:issuer><fhir:reference>{$qual/csd:issuingAuthority/text()}</fhir:reference></fhir:issuer> else ()
	    }
	  </fhir:qualification>
       ,
       for $lang in $provider/csd:language
       return  <fhir:communication><fhir:coding><fhir:system>urn:oid:{string($lang/@codingScheme)}</fhir:system><fhir:code>{string($lang/@code)}</fhir:code></fhir:coding></fhir:communication>
     )
    }

  </fhir:Practitioner>
};

(:
   Function to turn a CSD Facility  entity into a FHIR Location as JSON
:)

declare function fadpt:represent_facility_as_location_JSON($doc,$facility) {
  fadpt:represent_facility_as_location_JSON($doc,$facility,false())
};

declare function fadpt:represent_facility_as_location_JSON($doc,$facility,$as_xml)
{
  let $xml:=
    <json  type="object">
      <resourceType>Location</resourceType>
      <identifier type="array">
      <_ type="object">
	<value>{string($facility/@urn)}</value>
	<assigner>{string($facility/csd:record/@sourceDirectory)}</assigner>
	</_>
	{
	  for $otherID in $facility/csd:otherID
	  let $auth := string($otherID/@assigningAuthorityName)
	  let $code := string($otherID/@code)
	  return
	    <_ type="object">
	      <value>{$code}</value>
	      <assigner>{$auth}</assigner>
	    </_>
	}
      </identifier>
      <name>{($facility/csd:primaryName)[1]/text()}</name>
      <type type="array">
	{
	  for $role in ($facility/csd:codedType)
	  return
	    <_ type="object">
	      <coding type="array">
	        <_ type="object">
		  <system>urn:oid:{string($role/@codingScheme)}</system>
		  <code>{string($role/@code)}</code>
		</_>
	      </coding>
	    </_>
	}
      </type>
      <telecom type="array">
	{
	  for $contact in  $facility/csd:contactPoint/csd:codedType
	  return
	    <_ type="object">
	      <system>urn:oid:{string($contact/@code)}</system>
	      <value>{$contact/text()}</value>
	    </_>
	}
      </telecom>
      {
	for $address in ($facility/csd:demographic/csd:address[@type='Practice'])[1]
	return
	   <address type="object">
	     <use>{string($address/@type)}</use>
	     <line type="array">
	       {
		 for $al in $address/csd:addressLine[@component = 'streetAddress']
		 return <_>{$al/text()}</_>
	       }
	     </line>
	     {
	       for $city in ($address/csd:addressLine[@component = 'city'])[1]
	       return <city>{$city/text()}</city>
	     }
	     {
	       for $state in ($address/csd:addressLine[@component = 'stateProvince'])[1]
	       return <state>{$state/text()}</state>
	     }
	     {
	       for $zip in ($address/csd:addressLine[@component = 'postalCode'])[1]
	       return <zip>{$zip/text()}</zip>
	     }
	     {
	       for $country in ($address/csd:addressLine[@component = 'country'])[1]
	       return <country>{$country /text()}</country>
	     }
           </address>
      }
      {
	for $org in ($facility/csd:organizations/csd:organization)[1]
	   (: Note: base for URL for reference should maybe be handled by stored function extension metadata   :)
	   return <managingOrganization type="object"><reference>{string($org/@urn)}</reference></managingOrganization>
      }
      {
	switch ($facility/csd:record/@status)
	case "106-001" return <status>active</status>
	case "106-002" return <status>Inactive</status>
	default return ()
      }
    </json>

  return
    if ($as_xml)
    then $xml
    else json:serialize($xml,map{"format":"direct"})

};

(:
   Function to turn a CSD Organization entity into a FHIR Organization as JSON
:)

declare function fadpt:represent_organization_as_organization_JSON($doc,$organization) {
  fadpt:represent_organization_as_organization_JSON($doc,$organization,false())
};

declare function fadpt:represent_organization_as_organization_JSON($doc,$organization,$as_xml)
{
  let $xml:=
    <json  type="object">
      <resourceType>Organization</resourceType>
      <identifier type="array">
      <_ type="object">
	<value>{string($organization/@urn)}</value>
	<assigner>{string($organization/csd:record/@sourceDirectory)}</assigner>
	</_>
	{
	  for $otherID in $organization/csd:otherID
	  let $auth := string($otherID/@assigningAuthorityName)
	  let $code := string($otherID/@code)
	  return
	    <_ type="object">
	      <value>{$code}</value>
	      <assigner>{$auth}</assigner>
	    </_>
	}
      </identifier>
      <name>{($organization/csd:primaryName)[1]/text()}</name>
      <type type="array">
	{
	  for $role in ($organization/csd:codedType)
	  return
	    <_ type="object">
	      <coding type="array">
	        <_ type="object">
		  <system>urn:oid:{string($role/@codingScheme)}</system>
		  <code>{string($role/@code)}</code>
		</_>
	      </coding>
	    </_>
	}
      </type>
      <telecom type="array">
	{
	  for $contact in  $organization/csd:contactPoint/csd:codedType
	  return
	    <_ type="object">
	      <system>urn:oid:{string($contact/@code)}</system>
	      <value>{$contact/text()}</value>
	    </_>
	}
      </telecom>
      {
	for $address in ($organization/csd:demographic/csd:address[@type='Practice'])[1]
	return
	   <address type="object">
	     <use>{string($address/@type)}</use>
	     <line type="array">
	       {
		 for $al in $address/csd:addressLine[@component = 'streetAddress']
		 return <_>{$al/text()}</_>
	       }
	     </line>
	     {
	       for $city in ($address/csd:addressLine[@component = 'city'])[1]
	       return <city>{$city/text()}</city>
	     }
	     {
	       for $state in ($address/csd:addressLine[@component = 'stateProvince'])[1]
	       return <state>{$state/text()}</state>
	     }
	     {
	       for $zip in ($address/csd:addressLine[@component = 'postalCode'])[1]
	       return <zip>{$zip/text()}</zip>
	     }
	     {
	       for $country in ($address/csd:addressLine[@component = 'country'])[1]
	       return <country>{$country /text()}</country>
	     }
           </address>
      }
      {
	for $org in ($organization/csd:parent)[1]
	   (: Note: base for URL for reference should maybe be handled by stored function extension metadata   :)
	   return <partOf type="object"><reference>{string($org/@urn)}</reference></partOf>
      }
      {
	if ($organization/csd:record/@status = '106-001')
        then <status>1</status>
        else <status>0</status>
      }
    </json>

  return
    if ($as_xml)
    then $xml
    else json:serialize($xml,map{"format":"direct"})

};

(:
   Function to turn a CSD Provider entity into a FHIR Practitioner
:)

declare function fadpt:represent_provider_as_practitioner_JSON($doc,$provider) {
  fadpt:represent_provider_as_practitioner_JSON($doc,$provider,false())
};

declare function fadpt:represent_provider_as_practitioner_JSON($doc,$provider,$as_xml)
{
  let $xml:=
    <json  type="object">
      <resourceType>Practitioner</resourceType>
      <identifier type="array">
      <_ type="object">
	<value>{string($provider/@urn)}</value>
	<assigner>{string($provider/csd:record/@sourceDirectory)}</assigner>
	</_>
	{
	  for $otherID in $provider/csd:otherID
	  let $auth := string($otherID/@assigningAuthorityName)
	  let $code := string($otherID/@code)
	  return
	    <_ type="object">
	      <value>{$code}</value>
	      <assigner>{$auth}</assigner>
	    </_>
	}
      </identifier>
      {
        for $name in ($provider/csd:demographic/csd:name)[1] (:why does FHIR only allow one fhir:text and name element :)
	let $cn := ($name/csd:commonName)[1]/text()
	let $sn := ($name/csd:surname)[1]/text()
	let $gn := ($name/csd:forename)[1]/text()
	let $hon := ($name/csd:honorific)[1]/text()
	return
	  <name type="object">
	    <text>{$cn}</text>
	    <family type="array">
	      <_>{$sn}</_>
	    </family>
	    <given type="array">
	      <_>{$gn}</_>
	    </given>
	    <prefix type="array">
	      <_>{$hon}</_>
	    </prefix>
	  </name>
      }
      <telecom type="array">
	{
	  for $contact in  $provider/csd:demographic/csd:contactPoint/csd:codedType
	  return
	    <_ type="object">
	      <system>{string($contact/@code)}</system>
	      <value>{$contact/text()}</value>
	    </_>
	}
      </telecom>
      {
	for $address in ($provider/csd:demographic/csd:address[@type='Practice'])[1]
	return
	   <address type="object">
	     <use>{string($address/@type)}</use>
	     <line type="array">
	       {
		 for $al in $address/csd:addressLine[@component = 'streetAddress']
		 return <_>{$al/text()}</_>
	       }
	     </line>
	     {
	       for $city in ($address/csd:addressLine[@component = 'city'])[1]
	       return <city>{$city/text()}</city>
	     }
	     {
	       for $state in ($address/csd:addressLine[@component = 'stateProvince'])[1]
	       return <state>{$state/text()}</state>
	     }
	     {
	       for $zip in ($address/csd:addressLine[@component = 'postalCode'])[1]
	       return <zip>{$zip/text()}</zip>
	     }
	     {
	       for $country in ($address/csd:addressLine[@component = 'country'])[1]
	       return <country>{$country /text()}</country>
	     }
           </address>
      }
      {
	for  $gender in ($provider/csd:demographic/csd:gender)[1]
	return
	<gender type="object">
	  <coding type="array">
	    <_ type="object">
	      <system>urn:oid:2.25.309768652999692686176651983274504471835.999.403</system>
	      <code>{$gender/text()}</code>
	    </_>
	  </coding>
	</gender>
      }
      {
	for $dob in ($provider/csd:demographic/csd:dateOfBirth)[1]
	return  <birthDate>{$dob/text()}</birthDate>
      }
      {
	(: Note: base for URL for reference should maybe be handled by stored function extension metadata   :)
	(:              see http://www.hl7.org/implement/standards/fhir/base-definitions.html#ResourceReference.reference :)
	(: maybe we should use cross-referenced /CSD/organizationDirectory/organization/primaryName ? :)
	(: FHIR only allows one :)
	for $org in ($provider/csd:organizations/csd:organization)[1]
	return
	  <organization type="object">
	    <reference>{string($org/@urn)}</reference>
	  </organization>

      }
      <role type="array">
	{
	  for $role in ($provider/csd:codedType)
	  return
	    <_ type="object">
	      <coding type="array">
	        <_ type="object">
		  <system>urn:oid:{string($role/@codingScheme)}</system>
		  <code>{string($role/@code)}</code>
		</_>
	      </coding>
	    </_>
	}
      </role>
      <specialty type="array">
        {
	  for $specialty in ($provider/csd:specialty)
	  return
	    <_ type="object">
	      <coding type="array">
	        <_ type="object">
		  <system>urn:oid{string($specialty/@codingScheme)}</system>
		  <code>{string($specialty/@code)}</code>
		</_>
	      </coding>
	    </_>
	}
      </specialty>
      <location type="array">
	{
	  (: Note: base for URL for reference should maybe be handled by stored function extension metadata
             see http://www.hl7.org/implement/standards/fhir/base-definitions.html#ResourceReference.reference
	  :)
	  for $fac in ($provider/csd:facilities/csd:facility)
	  return
	    <_ type="object">
	      <reference>{string($fac/@urn)}</reference>
	    </_>
	}
      </location>
      <qualification type="array">
	{
	  for $qual in ($provider/csd:credential)
	  return
	    <_ type="object">
	      <code type="object">
		<coding type="array">
	          <_ type="object">
		    <system>urn:oid:{string($qual/@codingScheme)}</system>
		    <code>{string($qual/@code)}</code>
		  </_>
		</coding>
	      </code>
	      <period type="object">
		{if (exists($qual/csd:credenitalIssueDate)) then   <start>{$qual/csd:credenitalIssueDate}</start> else ()}
		{if (exists($qual/csd:credentialRenewalDate)) then  <end>{$qual/csd:credentialRenewalDate}</end> else ()}
	      </period>
	      {
		(:Note: I don't think this is quite correct.  It wants it to be an organization ID :)
		if (exists($qual/csd:issuingAuthority))
		then
	          <issuer type="object">
		    <reference>Assigning Authority/{$qual/csd:issuingAuthority/text()}</reference>
		  </issuer>
		else ()
	      }
	    </_>
	}
      </qualification>
      <communication type="array">
	{
	  for $lang in $provider/csd:language
	  return
	     <_ type="object">
	       <coding type="array">
	         <_ type="object">
		   <system>urn:oid:{string($lang/@codingScheme)}</system>
		   <code>{string($lang/@code)}</code>
		 </_>
	       </coding>
	     </_>
	}
      </communication>

    </json>

  return
    if ($as_xml)
    then $xml
    else json:serialize($xml,map{"format":"direct"})
};


commented more generic solution for app:listPers_hits

xquery version "3.0";
module namespace app="http://www.digital-archiv.at/ns/aratea-digital/templates";
declare namespace tei="http://www.tei-c.org/ns/1.0";
declare namespace functx = 'http://www.functx.com';
import module namespace templates="http://exist-db.org/xquery/templates" ;
import module namespace config="http://www.digital-archiv.at/ns/aratea-digital/config" at "config.xqm";
import module namespace kwic = "http://exist-db.org/xquery/kwic" at "resource:org/exist/xquery/lib/kwic.xql";
declare function functx:substring-after-last
  ( $arg as xs:string? ,
    $delim as xs:string )  as xs:string {
    replace ($arg,concat('^.*',$delim),'')
 };

(:~
 : This is a sample templating function. It will be called by the templating module if
 : it encounters an HTML element with an attribute data-template="app:test"
 : or class="app:test" (deprecated). The function has to take at least 2 default
 : parameters. Additional parameters will be mapped to matching request or session parameters.
 :
 : @param $node the HTML node with the attribute which triggered this call
 : @param $model a map containing arbitrary data - used to pass information between template calls
 :)
declare function app:test($node as node(), $model as map(*)) {

Dummy template output generated by function app:test at {current-dateTime()}. The templating
        function was triggered by the data-template attribute data-template="app:test".

};

(:~
: returns the name of the document of the node passed to this function.
:)
declare function app:getDocName($node as node()){
let $name := functx:substring-after-last(document-uri(root($node)), '/')
    return $name
};

(:~
 : href to document.
 :)
declare function app:hrefToDoc($node as node()){
let $name := functx:substring-after-last($node, '/')
let $href := concat('show.html','?document=', app:getDocName($node))
    return $href
};

(:~
 : a fulltext-search function
 :)
 declare function app:ft_search($node as node(), $model as map (*)) {
 if (request:get-parameter("searchexpr", "") !="") then
 let $searchterm as xs:string:= request:get-parameter("searchexpr", "")
 for $hit in collection(concat($config:app-root, '/data/editions/'))//*[.//tei:p[ft:query(.,$searchterm)]|.//tei:cell[ft:query(.,$searchterm)]]
    let $href := concat(app:hrefToDoc($hit), "&searchexpr=", $searchterm)
    let $score as xs:float := ft:score($hit)
    order by $score descending
    return

        {$score}
        {kwic:summarize($hit, <config width="40" link="{$href}" />)}
        {app:getDocName($hit)}

 else

Nothing to search for

 };

(:~
 : fetches all documents which contain the searched person
 :)
declare function app:listPers_hits($node as node(), $model as map(*), $searchkey as xs:string?, $path as xs:string?)
{
    for $hit in collection(concat($config:app-root, '/data/editions/'))//tei:TEI[.//tei:persName[@key=$searchkey] |.//tei:rs[@ref=concat("#",$searchkey)] |.//tei:rs[@key=contains(./@key,$searchkey)]]
(:    for $hit in collection(concat($config:app-root, '/data/'))//tei:TEI[.//*[@key=$searchkey] | .//@ref=concat("#",$searchkey)]:)
    let $doc := document-uri(root($hit))
    (:let $params := if (contains($doc, '/editions/'))
        then ""
        else
            "&directory=descriptions":)
(:            {app:getDocName($hit)}:)
    return

        {app:getDocName($hit)}

 };

(:~
 : creates a basic person-index derived from the  '/data/indices/listperson.xml'
 :)
declare function app:listPers($node as node(), $model as map(*)) {
    let $hitHtml := "hits.html?searchkey="
    for $person in doc(concat($config:app-root, '/data/indices/listperson.xml'))//tei:listPerson/tei:person
        return

                {$person/tei:persName}

};

(:~
 : creates a basic table of content derived from the documents stored in '/data/editions'
 :)
declare function app:toc($node as node(), $model as map(*)) {
    for $doc in collection(concat($config:app-root, '/data/editions/'))//tei:TEI
        return

                {app:getDocName($doc)}

};

(:~
 : perfoms an XSLT transformation
:)
declare function app:XMLtoHTML ($node as node(), $model as map (*), $query as xs:string?) {
let $ref := xs:string(request:get-parameter("document", ""))
let $xmlPath := concat(xs:string(request:get-parameter("directory", "editions")), '/')
let $xml := doc(replace(concat($config:app-root,'/data/', $xmlPath, $ref), '/exist/', '/db/'))
let $xslPath := concat(xs:string(request:get-parameter("stylesheet", "xmlToHtml")), '.xsl')
let $xsl := doc(replace(concat($config:app-root,'/resources/xslt/', $xslPath), '/exist/', '/db/'))
let $params :=
<parameters>
   {for $p in request:get-parameter-names()
    let $val := request:get-parameter($p,())
    where  not($p = ("document","directory","stylesheet"))
    return
       <param name="{$p}"  value="{$val}"/>
   }
</parameters>
return
    transform:transform($xml, $xsl, $params)
};

xquery version "3.0";
module namespace app="http://www.digital-archiv.at/ns/aratea-digital/templates";
declare namespace tei="http://www.tei-c.org/ns/1.0";
declare namespace functx = 'http://www.functx.com';
import module namespace templates="http://exist-db.org/xquery/templates" ;
import module namespace config="http://www.digital-archiv.at/ns/aratea-digital/config" at "config.xqm";
import module namespace kwic = "http://exist-db.org/xquery/kwic" at "resource:org/exist/xquery/lib/kwic.xql";
declare function functx:substring-after-last
  ( $arg as xs:string? ,
    $delim as xs:string )  as xs:string {
    replace ($arg,concat('^.*',$delim),'')
 };

(:~
 : This is a sample templating function. It will be called by the templating module if
 : it encounters an HTML element with an attribute data-template="app:test"
 : or class="app:test" (deprecated). The function has to take at least 2 default
 : parameters. Additional parameters will be mapped to matching request or session parameters.
 :
 : @param $node the HTML node with the attribute which triggered this call
 : @param $model a map containing arbitrary data - used to pass information between template calls
 :)
declare function app:test($node as node(), $model as map(*)) {

Dummy template output generated by function app:test at {current-dateTime()}. The templating
        function was triggered by the data-template attribute data-template="app:test".

};

(:~
: returns the name of the document of the node passed to this function.
:)
declare function app:getDocName($node as node()){
let $name := functx:substring-after-last(document-uri(root($node)), '/')
    return $name
};

(:~
 : href to document.
 :)
declare function app:hrefToDoc($node as node()){
let $name := functx:substring-after-last($node, '/')
let $href := concat('show.html','?document=', app:getDocName($node))
    return $href
};

(:~
 : a fulltext-search function
 :)
 declare function app:ft_search($node as node(), $model as map (*)) {
 if (request:get-parameter("searchexpr", "") !="") then
 let $searchterm as xs:string:= request:get-parameter("searchexpr", "")
 for $hit in collection(concat($config:app-root, '/data/editions/'))//*[.//tei:p[ft:query(.,$searchterm)]|.//tei:cell[ft:query(.,$searchterm)]]
    let $href := concat(app:hrefToDoc($hit), "&searchexpr=", $searchterm)
    let $score as xs:float := ft:score($hit)
    order by $score descending
    return

        {$score}
        {kwic:summarize($hit, <config width="40" link="{$href}" />)}
        {app:getDocName($hit)}

 else

Nothing to search for

 };

(:~
 : fetches all documents which contain the searched person
 :)
declare function app:listPers_hits($node as node(), $model as map(*), $searchkey as xs:string?, $path as xs:string?)
{
    (:for $hit in collection(concat($config:app-root, '/data/editions/'))//tei:TEI[.//tei:persName[@key=$searchkey] |.//tei:rs[@ref=concat("#",$searchkey)] |.//tei:rs[@key=contains(./@key,$searchkey)]]:)
    (:for $hit in collection(concat($config:app-root, '/data/'))//tei:TEI[.//*[@key=$searchkey] | .//@ref=concat("#",$searchkey)]:)
    let $doc := document-uri(root($hit))
    (:let $params := if (contains($doc, '/editions/'))
        then ""
        else
            "&directory=descriptions":)
    return

        {app:getDocName($hit)}
(:        {app:getDocName($hit)}:)

 };

(:~
 : creates a basic person-index derived from the  '/data/indices/listperson.xml'
 :)
declare function app:listPers($node as node(), $model as map(*)) {
    let $hitHtml := "hits.html?searchkey="
    for $person in doc(concat($config:app-root, '/data/indices/listperson.xml'))//tei:listPerson/tei:person
        return

                {$person/tei:persName}

};

(:~
 : creates a basic table of content derived from the documents stored in '/data/editions'
 :)
declare function app:toc($node as node(), $model as map(*)) {
    for $doc in collection(concat($config:app-root, '/data/editions/'))//tei:TEI
        return

                {app:getDocName($doc)}

};

(:~
 : perfoms an XSLT transformation
:)
declare function app:XMLtoHTML ($node as node(), $model as map (*), $query as xs:string?) {
let $ref := xs:string(request:get-parameter("document", ""))
let $xmlPath := concat(xs:string(request:get-parameter("directory", "editions")), '/')
let $xml := doc(replace(concat($config:app-root,'/data/', $xmlPath, $ref), '/exist/', '/db/'))
let $xslPath := concat(xs:string(request:get-parameter("stylesheet", "xmlToHtml")), '.xsl')
let $xsl := doc(replace(concat($config:app-root,'/resources/xslt/', $xslPath), '/exist/', '/db/'))
let $params :=
<parameters>
   {for $p in request:get-parameter-names()
    let $val := request:get-parameter($p,())
    where  not($p = ("document","directory","stylesheet"))
    return
       <param name="{$p}"  value="{$val}"/>
   }
</parameters>
return
    transform:transform($xml, $xsl, $params)
};


adhoc CSR in UI does not parseXML

adhoc CSR in UI does not parseXML

module namespace page = 'http://basex.org/modules/web-page';

import module namespace csr_proc = "https://github.com/his-interop/openinfoman/csr_proc" at "../repo/csr_processor.xqm";
import module namespace csd_dm = "https://github.com/his-interop/openinfoman/csd_dm" at "../repo/csd_document_manager.xqm";
import module namespace csd_webconf =  "https://github.com/his-interop/openinfoman/csd_webconf" at "../repo/csd_webapp_config.xqm";

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

declare variable $page:csd_docs := csd_dm:registered_documents($csd_webconf:db);

declare
  %rest:path("/CSD/csr/{$name}/careServicesRequest")
  %rest:consumes("application/xml", "text/xml", "multipart/form-data")
  %rest:POST("{$careServicesRequest}")
  function page:csr($name,$careServicesRequest)
{
if (csd_dm:document_source_exists($csd_webconf:db,$name)) then
 csr_proc:process_CSR($careServicesRequest/careServicesRequest,csd_dm:open_document($csd_webconf:db,$name))
else
  (:need appropriate error handling:)
  ()

};

declare updating
  %rest:path("/CSD/csr/{$name}/careServicesRequest/update")
  %rest:consumes("application/xml", "text/xml", "multipart/form-data")
  %rest:POST("{$careServicesRequest}")
  function page:csr_updating($name,$careServicesRequest)
{
if (csd_dm:document_source_exists($csd_webconf:db,$name)) then
 csr_proc:process_updating_CSR($careServicesRequest/careServicesRequest,csd_dm:open_document($csd_webconf:db,$name))
else
  (:need appropriate error handling:)
  ()

};

declare
  %rest:path("/CSD/csr/{$name}/adhoc")
  %rest:consumes("application/xml", "text/xml", "multipart/form-data")
  %rest:POST
  %rest:form-param("adhoc","{$adhoc}")
  %rest:form-param("content", "{$content}","application/xml")
function page:adhoc($name,$adhoc,$content) {
if (csd_dm:document_source_exists($csd_webconf:db,$name)) then
(:  csr_proc:process_CSR_adhoc(fn:parse-xml($adhoc),csd_dm:open_document($csd_webconf:db,$name)) :)
let  $adhoc_doc := csr_proc:create_adhoc_doc(string($adhoc),$content)
return  csr_proc:process_CSR($adhoc_doc,csd_dm:open_document($csd_webconf:db,$name))
(:
  return  csr_proc:process_CSR($adhoc_doc,csd_dm:open_document($csd_webconf:db,$name))      :)
else
  (:need appropriate error handling:)
  ()

};

declare
  %rest:path("/CSD/csr")
  %rest:GET
  %output:method("xhtml")
  function page:csr_list()
{
let $response :=

Care Services Request - Stored Queries

      {
      for $function in $csd_webconf:stored_functions
      let  $uuid := string($function/@uuid)
      return

      UUID: {string($uuid)}

      Method: {string(csd_webconf:lookup_stored_method($uuid))}

      Content: {string(csd_webconf:lookup_stored_content_type($uuid)) }

      }

Care Services Request - Ad Hoc Option

      {
	for $name in $page:csd_docs
	return

	  Submit Care Services Request for {$name} at:

{$csd_webconf:baseurl}//CSD/csr/{$name}/careServicesRequest

	  Submit ad-hoc query:
	  <form method='post' action="/CSD/csr/{$name}/adhoc"  enctype="multipart/form-data">
	    Ad-Hoc Query<textarea  rows="10" cols="80" name="adhoc" ><![CDATA[

You have {count(/csd:CSD/csd:providerDirectory/*)} providers.

You have {count(/csd:CSD/csd:facilityDirectory/*)} facilities.

You have {count(/csd:CSD/csd:organizationDirectory/*)} organizations.

You have {count(/csd:CSD/csd:serviceDirectory/*)} services.

 ]]> </textarea>

	    Content Type<input    cols="80" name="content" value="text/html"/>

	    <input type="submit" value="submit"/>
	  </form>

      }

  return page:wrapper($response)
};

declare function page:wrapper($response) {

    <link href="{$csd_webconf:baseurl}static/bootstrap/css/bootstrap.css" rel="stylesheet"/>
    <link href="{$csd_webconf:baseurl}static/bootstrap/css/bootstrap-theme.css" rel="stylesheet"/>

module namespace page = 'http://basex.org/modules/web-page';

import module namespace csr_proc = "https://github.com/his-interop/openinfoman/csr_proc" at "../repo/csr_processor.xqm";
import module namespace csd_dm = "https://github.com/his-interop/openinfoman/csd_dm" at "../repo/csd_document_manager.xqm";
import module namespace csd_webconf =  "https://github.com/his-interop/openinfoman/csd_webconf" at "../repo/csd_webapp_config.xqm";

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

declare variable $page:csd_docs := csd_dm:registered_documents($csd_webconf:db);

declare
  %rest:path("/CSD/csr/{$name}/careServicesRequest")
  %rest:consumes("application/xml", "text/xml", "multipart/form-data")
  %rest:POST("{$careServicesRequest}")
  function page:csr($name,$careServicesRequest)
{
if (csd_dm:document_source_exists($csd_webconf:db,$name)) then
 csr_proc:process_CSR($careServicesRequest/careServicesRequest,csd_dm:open_document($csd_webconf:db,$name))
else
  (:need appropriate error handling:)
  ()

};

declare updating
  %rest:path("/CSD/csr/{$name}/careServicesRequest/update")
  %rest:consumes("application/xml", "text/xml", "multipart/form-data")
  %rest:POST("{$careServicesRequest}")
  function page:csr_updating($name,$careServicesRequest)
{
if (csd_dm:document_source_exists($csd_webconf:db,$name)) then
 csr_proc:process_updating_CSR($careServicesRequest/careServicesRequest,csd_dm:open_document($csd_webconf:db,$name))
else
  (:need appropriate error handling:)
  ()

};

declare
  %rest:path("/CSD/csr/{$name}/adhoc")
  %rest:consumes("application/xml", "text/xml", "multipart/form-data")
  %rest:POST
  %rest:form-param("adhoc","{$adhoc}")
  %rest:form-param("content", "{$content}","application/xml")
function page:adhoc($name,$adhoc,$content) {
if (csd_dm:document_source_exists($csd_webconf:db,$name)) then
(:  csr_proc:process_CSR_adhoc(fn:parse-xml($adhoc),csd_dm:open_document($csd_webconf:db,$name)) :)
let  $adhoc_doc := csr_proc:create_adhoc_doc(fn:root(fn:parse-xml($adhoc)),$content)
return  csr_proc:process_CSR($adhoc_doc,csd_dm:open_document($csd_webconf:db,$name))
(:
  return  csr_proc:process_CSR($adhoc_doc,csd_dm:open_document($csd_webconf:db,$name))      :)
else
  (:need appropriate error handling:)
  ()

};

declare
  %rest:path("/CSD/csr")
  %rest:GET
  %output:method("xhtml")
  function page:csr_list()
{
let $response :=

Care Services Request - Stored Queries

      {
      for $function in $csd_webconf:stored_functions
      let  $uuid := string($function/@uuid)
      return

      UUID: {string($uuid)}

      Method: {string(csd_webconf:lookup_stored_method($uuid))}

      Content: {string(csd_webconf:lookup_stored_content_type($uuid)) }

      }

Care Services Request - Ad Hoc Option

      {
	for $name in $page:csd_docs
	return

	  Submit Care Services Request for {$name} at:

{$csd_webconf:baseurl}//CSD/csr/{$name}/careServicesRequest

	  Submit ad-hoc query:
	  <form method='post' action="/CSD/csr/{$name}/adhoc"  enctype="multipart/form-data">
	    Ad-Hoc Query<textarea  rows="10" cols="80" name="adhoc" ><![CDATA[

You have {count(/csd:CSD/csd:providerDirectory/*)} providers.

You have {count(/csd:CSD/csd:facilityDirectory/*)} facilities.

You have {count(/csd:CSD/csd:organizationDirectory/*)} organizations.

You have {count(/csd:CSD/csd:serviceDirectory/*)} services.

 ]]> </textarea>

	    Content Type<input    cols="80" name="content" value="text/html"/>

	    <input type="submit" value="submit"/>
	  </form>

      }

  return page:wrapper($response)
};

declare function page:wrapper($response) {

    <link href="{$csd_webconf:baseurl}static/bootstrap/css/bootstrap.css" rel="stylesheet"/>
    <link href="{$csd_webconf:baseurl}static/bootstrap/css/bootstrap-theme.css" rel="stylesheet"/>


Fix for SF bug 3137520: Improved serialization module documentation

(:
 : Copyright 2006-2009 The FLWOR Foundation.
 :
 : 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.
:)

(:~
 : XSLT 2.0 and XQuery 1.0 Serialization Module
 :
 : @author Matthias Brantner, Gabriel Petrovay
 :
 : @see XSLT 2.0 and XQuery 1.0 Serialization
 :)
module namespace ser = "http://www.zorba-xquery.com/modules/serialize";

(:~
 : Serialize a sequence of items to a string.
 :
 : The $serializer-params parameter can be used to control the $content serialization.
 : This argument can be either a string value or an
 : xsl:output
 : element as defined in the the XSLT 2.0 specification recommendation. If a string
 : value is provided, this will be interpreted as: <xsl:output method="string_value"/>.
 : Currently, Zorba supports the following methods:  xml, html, xhtml, text, json, and jsonml.
 :
 : In this version Zorba supports only the following attributes of the xsl:output element:
 :

 :
<output method="xml|html|xhtml|text|json|jsonml"
 : doctype-public="string"
 : doctype-system="string"
 : encoding="string"
 : indent="yes|no"
 : media-type="string"
 : omit-xml-declaration="yes|no"
 : standalone="yes|no"
 : undeclare-prefixes="yes|no"
 : version="string"/>

 :
 : @param $content The item sequence to be serialized.
 : @param $serializer-params Parameter to control the serialization.
 : @error An error is thrown if serialization problems occur.
 : @return A string representing the serialized sequence of items.
 : @see XSLT 2.0 xsl:output element
 :)
declare function ser:serialize($content as item()*,
                               $serializer-params as item()) as xs:string external;

(:~
 : Serialize a sequence of items to a string. The supported serialization
 : parameters that require a value are set as follows:
 :

 :
method: xml

 :
encoding: UTF-8

 :
indent: no

 :
omit-xml-declaration: no

 :
standalone: omit

 :
undeclare-prefixes: no

 :
version: 1.0

 :

 :
 : @param $content The item sequence to be serialized.
 : @error An error is thrown if serialization problems occur.
 : @return A string representing the serialized sequence of items.
 :)
declare function ser:serialize($content as item()*) as xs:string external;

(:
 : Copyright 2006-2009 The FLWOR Foundation.
 :
 : 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.
:)

(:~
 : XSLT 2.0 and XQuery 1.0 Serialization Module
 :
 : @author Matthias Brantner, Gabriel Petrovay
 :
 : @see XSLT 2.0 and XQuery 1.0 Serialization
 :)
module namespace ser = "http://www.zorba-xquery.com/modules/serialize";

(:~
 : Serialize a sequence of items to a string.
 :
 : @param   $content The content to be serialized to the string.
 : @param   $serializer-params Parameters to control the serialization of the content.

 : This parameter can either be a string (xml, html, xhtml, text, json, or jsonml) describing the serialization method to
 : be used or a element node as follows:

 : output  method="xml|html|text|json|jsonml"

 : version="string" encoding="string"

 : omit-xml-declaration="yes|no"

 : standalone="yes|no"

 : doctype-public="string" doctype-system="string"

 : cdata-section-elements="namelist"

 : indent="yes|no" media-type="string"

 :
 : @error   An error is thrown if serialization problems occur.
 : @return  Serialize a sequence of items to a string.
 :)
declare function ser:serialize($content as item()*,
                               $serializer-params as item()) as xs:string external;

(:~
 : Serialize a sequence of items to a string.
 :
 : @param $content The content to be serialized to the string.
 : @error An error is thrown if serialization problems occur.
 : @return   Serialize a sequence of items to a string. For serialization, the serialization parameters are set as follows:
 :

 :
 serialization method: XML

 :
 byte-order-mark: NO

 :
 esacpe-uri-attributes: NO

 :
 include-content-type: NO

 :
 indent: NO

 :
 normalization-form: none

 :
 omit-xml-declaration: NO

 :
 standalone: omit

 :
 undeclare-prefixes: NO

 :

 :)
declare function ser:serialize($content as item()*) as xs:string external;


removed redundant .xql file

removed redundant .xql file

xquery version "3.0";

declare namespace tei = "http://www.tei-c.org/ns/1.0";
declare namespace json="http://www.json.org";

declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "json";
declare option output:media-type "application/json";

declare variable $coll             as xs:string   := request:get-parameter('coll', '');
declare variable $q                as xs:string   := request:get-parameter('q', '');
declare variable $first            as xs:string   := request:get-parameter('first', '');
declare variable $luceneOptions    as node()      := <options>
                                                        <default-operator>and</default-operator>
                                                        <leading-wildcard>yes</leading-wildcard>
                                                     </options>;
declare variable $queryPath      as xs:string     := '/db/test';

(:~
~ Three-columns demo response
:)
declare function local:demoResponse () as node() {

   <response>
      <cols>
         <name>Key</name>
      </cols>
      <cols>
         <name>Name</name>
      </cols>
      <data json:array="true">
         <json:value>a</json:value>
         <json:value>DEMO SERVER RESPONSE</json:value>
      </data>
      <data json:array="true">
         <json:value>b</json:value>
         <json:value>Type in a string, hit "Enter" and check the "q" parameter in the next row.</json:value>
      </data>
      <data json:array="true">
         <json:value>c</json:value>
         <json:value>User: "{xmldb:get-current-user()}". Parameters: q: "{$q}", coll: "{$coll}", first: "{$first}".</json:value>
      </data>
      <data json:array="true">
         <json:value>d</json:value>
         <json:value>Select a table entry and press the "OK" button (or double click on the entry) to insert a new fragment to the current editor pane.</json:value>
      </data>
      <data json:array="true">
         <json:value>1</json:value>
         <json:value>Search for "1" to get a multi-column response.</json:value>
      </data>
      <data json:array="true">
         <json:value>2</json:value>
         <json:value>Search for "2" to a get column names, but no data. (no error)</json:value>
      </data>
      <data json:array="true">
         <json:value>3</json:value>
         <json:value>Search for "3" to cause a server exception. ERROR</json:value>
      </data>
      <data json:array="true">
         <json:value>4</json:value>
         <json:value>Search for "4" to request malformed data. ERROR</json:value>
      </data>
   </response>

};

(:~
~ Three-columns demo response
:)
declare function local:demoResponse1 () as node() {

   <response>
      <cols>
         <name>x</name>
      </cols>
      <cols>
         <name>MULTI</name>
      </cols>
      <cols>
         <name>COLUMN</name>
      </cols>
      <cols>
         <name>SERVER</name>
      </cols>
      <cols>
         <name>RESPONSE</name>
      </cols>
      <cols>
         <name>Data3</name>
      </cols>
      <cols>
         <name>Data4</name>
      </cols>
      <data json:array="true">
         <json:value>d11</json:value>
         <json:value>d12</json:value>
         <json:value>d13</json:value>
         <json:value>d14</json:value>
         <json:value>d15</json:value>
         <json:value>d16</json:value>
         <json:value>d17</json:value>
      </data>
      <data json:array="true">
         <json:value>d21</json:value>
         <json:value>d22</json:value>
         <json:value>d23</json:value>
         <json:value>d24</json:value>
         <json:value>d25</json:value>
         <json:value>d26</json:value>
         <json:value>d27</json:value>
      </data>
   </response>

};

(:~
~ Column names, but no data -> OK
:)
declare function local:demoResponse2 () as node() {

   <response>
      <cols>
         <name>Key</name>
      </cols>
      <cols>
         <name>Name</name>
      </cols>
      <cols>
         <name>Description</name>
      </cols>
   </response>

};

(:~
~ Server error -> error msg
:)
declare function local:demoResponse3 () as node() { '' };

(:~
~ Return wrong number of columns in data array -> error msg
:)
declare function local:demoResponse4 () as node() {

   <response>
      <cols>
         <name>Key</name>
      </cols>
      <cols>
         <name>Name</name>
      </cols>
      <cols>
         <name>Description</name>
      </cols>
      <data json:array="true">
         <json:value>0</json:value>
         <json:value>1</json:value>
         <!-- MISSING COLUMN -->
      </data>
   </response>

};

(:~
~ Example database query (two-column server response)
:)
(:declare function local:query () as node()* {

   let $hits :=
      if ($q='' or $coll='')
      then ()
      else collection($queryPath)/tei:TEI[ft:query(., $q, $luceneOptions)]
   return
      element response {
         for $colName in ('Key', 'Name')
         return
            <cols>
               <name>{$colName}</name>
            </cols>
         ,
         for $i in $hits
         return
            <data json:array="true">
               <json:value>{substring-before(util:document-name($i), '.')}</json:value>
               <json:value>{($i//tei:persName)[1]/text()}</json:value>
            </data>
      }

};:)

if ($q = "1") then local:demoResponse1() else
if ($q = "2") then local:demoResponse2() else
if ($q = "3") then local:demoResponse3() else
if ($q = "4") then local:demoResponse3() else
local:demoResponse()
(:local:query():)


[ignore] corrected wrong atom feed urls in the news section.

svn path=/trunk/eXist/; revision=8793

xquery version "1.0";

declare namespace atom="http://www.w3.org/2005/Atom";

declare variable $atom:server := "http://atomic.exist-db.org";
declare variable $atom:uri := concat($atom:server, "/atom/summary/wiki/blogs/eXist/");

declare function atom:format-entry($feed as element()) {

    {
        for $entry in $feed//atom:entry
        let $link := $entry/atom:link[@rel = 'alternate'][@type = 'text/html']/@href
        return

                    {substring($entry/atom:published, 1, 10)}

                    {$entry/atom:title/text()}

    }

};

let $uri := xs:anyURI($atom:uri)
let $response := doc($uri)
return
    atom:format-entry($response/atom:feed)