Added try/catch for errors in the module processing.

xquery version "3.0";

(:
 : Copyright 2006-2010 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.
:)

(:~
 : Function library provides functions for generating the XQDoc XML's for a project.
 :
 : @author Sorin Nasoi
 : @project xqdoc
 :)

module namespace pxqdoc  = "http://www.zorba-xquery.com/modules/project_xqdoc";

(:~ needed for generating the XML's :)
import module namespace xqd  = "http://www.zorba-xquery.com/modules/xqdoc";
(:~ needed for writing the XML's to disk:)
import module namespace file = "http://expath.org/ns/file";

import schema namespace xqdoc = "http://www.xqdoc.org/1.0";
import schema namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";

declare namespace an = "http://www.zorba-xquery.com/annotations";
declare namespace zm = "http://www.zorba-xquery.com/manifest";
import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch";

declare namespace ver = "http://www.zorba-xquery.com/options/versioning";

import module namespace err  = "http://www.zorba-xquery.com/modules/xqdoc2xhtml/error";
declare namespace werr = "http://www.w3.org/2005/xqt-errors";
declare option ver:module-version "2.0";

(:~
 : The serialization parameters for XML serialization.
 :)
declare variable $pxqdoc:serParamXml :=
  <output:serialization-parameters>
    <output:method value="xml"/>
    <output:indent value="yes"/>
  </output:serialization-parameters>;

(:~
 : Delete the intermediary xml dir
 :
 : @param $xqdocPath where to generate the XQDoc XML documents.
 : @return empty sequence.
 :)
declare %an:sequential function pxqdoc:delete-XML-dir(
  $xqdocPath as xs:string)
{
  variable $xqdocXMLPath  := fn:concat( $xqdocPath,
                                        file:directory-separator(),
                                        "xml");
  (: clear the XML folder :)
  if(file:exists($xqdocXMLPath)) then
    file:delete($xqdocXMLPath);
  else ();
};

declare %private %an:nondeterministic function pxqdoc:load-manifest(
  $zorbaManifestPath as xs:string)
{
  try
  {
    fn:parse-xml(file:read-text($zorbaManifestPath))
  }
  catch *
  {
    fn:error($err:UE004,fn:concat("The file <",$zorbaManifestPath,"> does not have the correct structure."))
  }
};

(:~
 : This function generates the XQDoc XML for all the modules found in build/ZorbaManifest.xml
 :
 : @param $zorbaManifestPath location of ZorbaManifest.xml.
 : @param $xqdocPath where to generate the XQDoc XML documents.
 : @return empty sequence.
 :)
declare %an:sequential function pxqdoc:generate-xqdoc-XML(
  $zorbaManifestPath as xs:string,
  $xqdocPath as xs:string)
{
  (: Note: only the modules that are configured in the Zorba version you are using will be build :)
  variable $xqdocXMLPath := concat($xqdocPath, file:directory-separator(), "xml");

  (: create the XML folder if it does not exist already :)
  file:create-directory($xqdocXMLPath);

  if(not(file:is-file($zorbaManifestPath))) then
  {
    variable $message := fn:concat("The file <ZorbaManifest.xml> was not found: <", $zorbaManifestPath, ">. Suggestion: run 'cmake' in your build folder such that ZorbaManifest.xml is regenerated.");
    fn:error($err:UE004, $message);
  }
  else
  {
    variable $manifestXML := pxqdoc:load-manifest($zorbaManifestPath);
    variable $moduleManifests := $manifestXML/zm:manifest/zm:module;
    if(count($moduleManifests) eq xs:integer(0)) then ();
    else
    {
      try
      {
      for $module in $moduleManifests
      (: note the module version is not supported because of a bug in the fetch for the module URI ending with / :)
      (:let $moduleURI := if(ends-with(data($module/zm:uri),'/')) then data($module/zm:uri)
                       else if(exists($module/@version)) then concat(data($module/zm:uri),"#",data($module/@version))
                       else data($module/zm:uri):)
      (:let $moduleFetched := fetch:content(trace($moduleURI,"fetch module URI version.."), "MODULE"):)
      let $moduleURI := data($module/zm:uri)
      let $moduleFetched := fetch:content($moduleURI, "MODULE")
      let $xqdoc := xqd:xqdoc-content($moduleFetched)
      let $xqdocRelFileName  := pxqdoc:get-filename($moduleURI)
      let $xqdocFileName := concat($xqdocXMLPath, file:directory-separator(), $xqdocRelFileName, ".xml")
      return
        file:write($xqdocFileName,
                   $xqdoc,
                   $pxqdoc:serParamXml)
      }
      catch *
      {
        fn:error($err:UE004,
                 concat("Error processing module ",
                        $werr:code,
                        " - ",
                        $werr:description))
      }
    };
  }
};

(:~
 : Returns the string resulting from replacing the directory-separators (i.e. / ) with '_'
 :
 : @param $moduleURI the path to the module URI.
 : @return the string resulting from replacing the directory-separators (i.e. / ) with '_'.
 :
 :)
declare function pxqdoc:get-filename(
  $moduleURI as xs:string) as xs:string {
  let $lmodule := if(fn:ends-with($moduleURI,"/")) then fn:concat($moduleURI,"index") else $moduleURI
  return
    replace(
      replace($lmodule, "/", "_"),
      "http:__",
      ""
  )
};

xquery version "3.0";

(:
 : Copyright 2006-2010 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.
:)

(:~
 : Function library provides functions for generating the XQDoc XML's for a project.
 :
 : @author Sorin Nasoi
 : @project xqdoc
 :)

module namespace pxqdoc  = "http://www.zorba-xquery.com/modules/project_xqdoc";

(:~ needed for generating the XML's :)
import module namespace xqd  = "http://www.zorba-xquery.com/modules/xqdoc";
(:~ needed for writing the XML's to disk:)
import module namespace file = "http://expath.org/ns/file";

import schema namespace xqdoc = "http://www.xqdoc.org/1.0";
import schema namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";

declare namespace an = "http://www.zorba-xquery.com/annotations";
declare namespace zm = "http://www.zorba-xquery.com/manifest";
import module namespace fetch = "http://www.zorba-xquery.com/modules/fetch";

declare namespace ver = "http://www.zorba-xquery.com/options/versioning";

import module namespace err  = "http://www.zorba-xquery.com/modules/xqdoc2xhtml/error";
declare namespace werr = "http://www.w3.org/2005/xqt-errors";
declare option ver:module-version "2.0";

(:~
 : The serialization parameters for XML serialization.
 :)
declare variable $pxqdoc:serParamXml :=
  <output:serialization-parameters>
    <output:method value="xml"/>
    <output:indent value="yes"/>
  </output:serialization-parameters>;

(:~
 : Delete the intermediary xml dir
 :
 : @param $xqdocPath where to generate the XQDoc XML documents.
 : @return empty sequence.
 :)
declare %an:sequential function pxqdoc:delete-XML-dir(
  $xqdocPath as xs:string)
{
  variable $xqdocXMLPath  := fn:concat( $xqdocPath,
                                        file:directory-separator(),
                                        "xml");
  (: clear the XML folder :)
  if(file:exists($xqdocXMLPath)) then
    file:delete($xqdocXMLPath);
  else ();
};

declare %private %an:nondeterministic function pxqdoc:load-manifest(
  $zorbaManifestPath as xs:string)
{
  try
  {
    fn:parse-xml(file:read-text($zorbaManifestPath))
  }
  catch *
  {
    fn:error($err:UE004,fn:concat("The file <",$zorbaManifestPath,"> does not have the correct structure."))
  }
};

(:~
 : This function generates the XQDoc XML for all the modules found in build/ZorbaManifest.xml
 :
 : @param $zorbaManifestPath location of ZorbaManifest.xml.
 : @param $xqdocPath where to generate the XQDoc XML documents.
 : @return empty sequence.
 :)
declare %an:sequential function pxqdoc:generate-xqdoc-XML(
  $zorbaManifestPath as xs:string,
  $xqdocPath as xs:string)
{
  (: Note: only the modules that are configured in the Zorba version you are using will be build :)
  variable $xqdocXMLPath := concat($xqdocPath, file:directory-separator(), "xml");

  (: create the XML folder if it does not exist already :)
  file:create-directory($xqdocXMLPath);

  if(not(file:is-file($zorbaManifestPath))) then
  {
    variable $message := fn:concat("The file <ZorbaManifest.xml> was not found: <", $zorbaManifestPath, ">. Suggestion: run 'cmake' in your build folder such that ZorbaManifest.xml is regenerated.");
    fn:error($err:UE004, $message);
  }
  else
  {
    variable $manifestXML := pxqdoc:load-manifest($zorbaManifestPath);
    variable $moduleManifests := $manifestXML/zm:manifest/zm:module;
    if(count($moduleManifests) eq xs:integer(0)) then ();
    else
    {
      for $module in $moduleManifests
      (: note the module version is not supported because of a bug in the fetch for the module URI ending with / :)
      (:let $moduleURI := if(ends-with(data($module/zm:uri),'/')) then data($module/zm:uri)
                       else if(exists($module/@version)) then concat(data($module/zm:uri),"#",data($module/@version))
                       else data($module/zm:uri):)
      (:let $moduleFetched := fetch:content(trace($moduleURI,"fetch module URI version.."), "MODULE"):)
      let $moduleURI := if(ends-with(data($module/zm:uri),".xq")) then substring-before(data($module/zm:uri),".xq") else data($module/zm:uri)
      let $moduleFetched := fetch:content($moduleURI, "MODULE")
      let $xqdoc := xqd:xqdoc-content($moduleFetched)
      let $xqdocRelFileName  := pxqdoc:get-filename($moduleURI)
      let $xqdocFileName := concat($xqdocXMLPath, file:directory-separator(), $xqdocRelFileName, ".xml")
      return
        file:write($xqdocFileName,
                   $xqdoc,
                   $pxqdoc:serParamXml)
    };
  }
};

(:~
 : Returns the string resulting from replacing the directory-separators (i.e. / ) with '_'
 :
 : @param $moduleURI the path to the module URI.
 : @return the string resulting from replacing the directory-separators (i.e. / ) with '_'.
 :
 :)
declare function pxqdoc:get-filename(
  $moduleURI as xs:string) as xs:string {
  let $lmodule := if(fn:ends-with($moduleURI,"/")) then fn:concat($moduleURI,"index") else $moduleURI
  return
    replace(
      replace($lmodule, "/", "_"),
      "http:__",
      ""
  )
};


Address #56 - Builtin Saxon functions: removed unnecessary annotation declaration.

xquery version "1.0";
(:~
 : Saxon extension functions
 : @see http://www.saxonica.com/html/documentation/functions/saxon
 :
 :)
module namespace saxon = "http://saxon.sf.net/";

declare namespace a = "http://reecedunn.co.uk/xquery/annotations";
declare namespace o = "http://reecedunn.co.uk/xquery/options";

declare %a:since("saxon", "9.2") function saxon:adjust-to-civil-time($in as xs:dateTime, $tz as xs:string) as xs:dateTime? external; (: reqs PE or EE :)
declare %a:since("saxon", "9.8") function saxon:array-member($value as item()*) as jt:com.saxonica.functions.extfn.ArrayMemberValue external; (: http://www.saxonica.com/html/documentation/functions/saxon/array-member.html? how to indicate namespaces there? :)
declare %a:since("saxon", "8.1") function saxon:base64Binary-to-octets($input as xs:base64Binary) as xs:integer* external;
declare %a:since("saxon", "8.5") function saxon:base64Binary-to-string($input as xs:base64Binary?, $encoding as xs:string) as xs:string external;

xquery version "1.0";
(:~
 : Saxon extension functions
 : @see http://www.saxonica.com/html/documentation/functions/saxon
 :
 :)
module namespace saxon = "http://saxon.sf.net/";

declare namespace a = "http://reecedunn.co.uk/xquery/annotations";
declare namespace o = "http://reecedunn.co.uk/xquery/options";

(: declare option o:requires ...:)

declare %a:since("saxon", "9.2") function saxon:adjust-to-civil-time($in as xs:dateTime, $tz as xs:string) as xs:dateTime? external; (: reqs PE or EE :)
declare %a:since("saxon", "9.8") function saxon:array-member($value as item()*) as jt:com.saxonica.functions.extfn.ArrayMemberValue external; (: http://www.saxonica.com/html/documentation/functions/saxon/array-member.html? how to indicate namespaces there? :)
declare %a:since("saxon", "8.1") function saxon:base64Binary-to-octets($input as xs:base64Binary) as xs:integer* external;
declare %a:since("saxon", "8.5") function saxon:base64Binary-to-string($input as xs:base64Binary?, $encoding as xs:string) as xs:string external;


added ability to update url/user/pass of named polled service directory in web UI

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

import module namespace csd_psd = "https://github.com/openhie/openinfoman/csd_psd";
import module namespace csd_lsc = "https://github.com/openhie/openinfoman/csd_lsc";
import module namespace csd_dm = "https://github.com/openhie/openinfoman/csd_dm";
import module namespace csd_webconf =  "https://github.com/openhie/openinfoman/csd_webconf";
import module namespace csd_qus =  "https://github.com/openhie/openinfoman/csd_qus";

declare function page:redirect($redirect as xs:string) as element(restxq:redirect)
{
  <restxq:redirect>{ $redirect }</restxq:redirect>
};

declare function page:nocache($response) {
(
  <rest:response>
    <http:response >
      <http:header name="Cache-Control" value="must-revalidate,no-cache,no-store"/>
    </http:response>
  </rest:response>
,
  $response
)

};

declare updating
  %rest:path("/CSD/registerService/init")
  function page:init()
{
  (
    csd_lsc:init_cache_meta($csd_webconf:db)
    ,csd_psd:init($csd_webconf:db)
    ,db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )
};

declare updating
  %rest:path("/CSD/registerService/named/{$name}")
  %output:method("xhtml")
  %rest:GET
  function page:register_named($name)
{

  (
    let $sample := $csd_webconf:remote_services//serviceDirectory[@name=$name]
    return if (exists($sample)) then
      csd_psd:register_service($csd_webconf:db,$name,text{$sample/@url},$sample/credentials)
    else ()
  ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )
};

declare updating
  %rest:path("/CSD/registerService/basic_auth")
  %output:method("xhtml")
  %rest:query-param("name", "{$name}")
  %rest:query-param("url", "{$url}")
  %rest:query-param("password", "{$password}")
  %rest:query-param("username", "{$username}")
  %rest:GET
  function page:register_basic_auth($name,$url,$username,$password)
{

  (
    let $credentials := <credentials type="basic_auth" username="{$username}" password="{$password}"/>
    return csd_psd:register_service($csd_webconf:db,$name,$url,$credentials)
      ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )

};

declare updating
  %rest:path("/CSD/registerService/basic_auth/{$name}")
  %output:method("xhtml")
  %rest:query-param("url", "{$url}")
  %rest:query-param("password", "{$password}")
  %rest:query-param("username", "{$username}")
  %rest:GET
  function page:update_basic_auth($name,$url,$username,$password)
{

  (
    let $credentials := <credentials type="basic_auth" username="{$username}" password="{$password}"/>
    return csd_psd:register_service($csd_webconf:db,$name,$url,$credentials)
      ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )

};

declare
  %rest:path("/CSD/pollService/cache_meta")
  %rest:GET
  function page:get_cache_meta()
{
  csd_lsc:get_cache_data($csd_webconf:db,())
};

declare
  %rest:path("/CSD/pollService/directory/{$name}")
  %rest:GET
  %output:method("xhtml")
  function page:get_service_menu($name)
{
  let $response :=
{$name}
{page:service_menu($name) }
  return page:nocache(csd_webconf:wrapper($response))
};

declare
  %rest:path("/CSD/pollService/directory/{$name}/cache_meta")
  %rest:GET
  function page:get_service_cache_meta($name)
{
  csd_lsc:get_cache_data($csd_webconf:db,$name)
};

declare updating
  %rest:path("/CSD/pollService/directory/{$name}/create_cache")
  %rest:GET
  function page:create_cache($name)
{

  (
    if (csd_lsc:directory_exists($csd_webconf:db,$name))
    then csd_lsc:empty_cache($csd_webconf:db,$name)
    else csd_dm:empty($csd_webconf:db,$name)
  ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )

};

declare updating
  %rest:path("/CSD/pollService/directory/{$name}/drop_cache_meta")
  %rest:GET
  function page:drop_service_cache_meta($name)
{
  (
  csd_lsc:drop_cache_data($csd_webconf:db,$name)
  ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )

};

declare
  %rest:path("/CSD/pollService/directory/{$name}/get_cache")
  %rest:GET
  function page:get_cache($name)
{
 csd_lsc:get_cache($csd_webconf:db,$name)
};

declare updating
  %rest:path("/CSD/pollService/directory/{$name}/empty_cache")
  %rest:GET
  function page:empty_cache($name)
{
  (
  csd_lsc:empty_cache($csd_webconf:db,$name)
  ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )

};

declare updating
  %rest:path("/CSD/pollService/directory/{$name}/update_cache")
  %rest:GET
  function page:update_cache($name)
{
(
  csd_lsc:update_cache($csd_webconf:db,$name)   ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
)

};

declare
  %rest:path("/CSD/pollService/directory/{$name}/show_update_cache")
  %rest:GET
  function page:show_update_cache($name)
{

  let $db := $csd_webconf:db
  let $mtime :=  csd_lsc:get_service_directory_mtime($db,$name)
  let $soap := csd_psd:generate_soap_request($db,$name,$mtime)
  let $result := http:send-request($soap)
  return <r>{$result}</r><s>{$soap}</s>

};

declare
  %rest:path("/CSD/pollService/{$name}")
  %output:method("xhtml")
  %rest:GET
  function page:display_service_menu($name)
{
  let $response :=

	{page:service_menu($name)}

  return page:nocache(page:wrapper($response))
};

declare
  %rest:path("/CSD/pollService/{$name}/get")
  %rest:query-param("mtime", "{$mtime}")
  %rest:GET
  function page:poll_service($name,$mtime)
{
if ($mtime) then
 csd_psd:poll_service_directory_soap_response($csd_webconf:db,$name,$mtime)
else
 csd_psd:poll_service_directory_soap_response($csd_webconf:db,$name,csd_lsc:get_service_directory_mtime($csd_webconf:db,$name))
};

declare
  %rest:path("/CSD/pollService/{$name}/get_csd")
  %rest:query-param("mtime", "{$mtime}")
  %rest:GET
  function page:poll_service_csd($name,$mtime)
{
if ($mtime) then
 csd_psd:poll_service_directory($csd_webconf:db,$name,$mtime)
else
 csd_psd:poll_service_directory($csd_webconf:db,$name,csd_lsc:get_service_directory_mtime($csd_webconf:db,$name))
};

declare
  %rest:path("/CSD/pollService/{$name}/get_soap")
  %rest:query-param("mtime", "{$mtime}")
  %rest:GET
  function page:poll_service_soap($name,$mtime)
{
 let $url := csd_psd:get_service_directory_url($csd_webconf:db,$name)
 return (
 <rest:response>
   <http:response status="200" >
     <http:header name="Content-Type" value="application/soap+xml"/>
     <http:header name="Content-Disposition"  value="inline; filename=soap_query_updated_services_{$name}"/>
   </http:response>
   </rest:response>
   ,
   if ($mtime) then
     csd_qus:create_last_update_request($url,$mtime)
   else
     csd_qus:create_last_update_request($url,csd_lsc:get_service_directory_mtime($csd_webconf:db,$name))
 )

};

declare function page:wrapper($response) {
  let $headers :=
  (<link rel="stylesheet" type="text/css" media="screen"   href="{$csd_webconf:baseurl}static/bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css"/>
  ,
  )
  return csd_webconf:wrapper($response,$headers)
};

declare
  %rest:path("/CSD/pollService")
  %rest:GET
  %output:method("xhtml")
  function page:poll_service_list()
{

if (not(csd_psd:dm_exists($csd_webconf:db))) then
   page:redirect(concat($csd_webconf:baseurl,"CSD/registerService/init"))
 else
   let $services := csd_psd:registered_directories($csd_webconf:db)
   let $unreg_services :=
     for $sample in  $csd_webconf:remote_services//serviceDirectory
     where not(csd_psd:is_registered($csd_webconf:db,$sample/text{@name}))
     return  $sample
    let $response :=

Add New Service (Basic Auth)

	 <form method='get' action="/CSD/registerService/basic_auth">

 Name<input class='pull-right'  size="35"      name='name' type="text" value=""/>

URL<input  class='pull-right' size="35"     name='url' type="text" value=""/>

User Name<input  class='pull-right' size="35"     name='username' type="text" value=""/>

Password<input  class='pull-right' size="35"     name='password' type="text" value=""/>

	   <input type='submit' />
	 </form>

	 {
	   if (count($unreg_services) > 0) then

Add New Default Service

	       {for $sample in $unreg_services
	       let $name := $sample/text{@name}
	       return

		 Register {$name}

	       }

	 else ()
}

Global Operations

 Get all cache Meta-Data

Registered Service Directories

	 {if (count($services) = 0)
	 then
No Services Registered

       else

	 {for $name in $services
	 let $mtime := csd_lsc:get_service_directory_mtime($csd_webconf:db,$name)
	 order by $name
	 return

	   {$name} last cached on {$mtime}

	 }

	 }

Update Service (Basic Auth)

	 {
	   for $name in $services
	   let $url := csd_psd:get_service_directory_url($csd_webconf:db,$name)
	   return

{$name}

	       <form method='get' action="/CSD/registerService/basic_auth/{$name}">

URL<input  class='pull-right' size="35"     name='url' type="text" value="{$url}"/>

User Name<input  class='pull-right' size="35"     name='username' type="text" value=""/>

Password<input  class='pull-right' size="35"     name='password' type="text" value=""/>

		 <input type='submit' />
	       </form>

	 }

  return page:nocache(page:wrapper($response))

};

declare function page:service_menu($name) {
  let $url := csd_psd:get_service_directory_url($csd_webconf:db,$name)
  let $mtime := csd_lsc:get_service_directory_mtime($csd_webconf:db,$name)
  return

{$url}

    modified: {$mtime}

Caching
{csd_lsc:get_document_name($name)}

    {if (not(csd_lsc:directory_exists($csd_webconf:db,$name))) then
      (

Create cache of {$name}

      )
  else
    (

Empty local cache of {$name}
,

Get local cache  of {$name}
,

      Update local cache  of {$name}

	WARNING:An InfoMan trying to cache its own service directory will result in a deadlock.  see this issue

,

Get cache Meta Data  for {$name}
,

Drop cache Meta Data  of {$name}

  )
    }

Testing

 Query  {$name} for Updated Services using stored last modified time (SOAP result)

 Query  {$name} for Updated Services using stored last modified time (CSD result)

 Get {$name}'s Soap Query for Updated Services Request using stored last modified time

    Query {$name} for Updated Services by time
    <form method='get' action="/CSD/pollService/{$name}/get">
      <input  size="35" id="datetimepicker_{$name}"    name='mtime' type="text" value="{$mtime}"/>
      <input type='submit' />
    </form>

    Get {$name}'s SOAP reuest for Query for Updated Services by time
    <form method='get' action="/CSD/pollService/soap_query_updated_services_{$name}">
      <input  size="35" id="soap_datetimepicker_{$name}"  name='mtime' type="text" value="{$mtime}"/>
      <input type='submit' />
    </form>

  To test submission on your machine you can do:

curl --header "content-type: application/soap+xml" --data "@soap_query_updated_services_{$name}.xml" {$url}

  where soap_updated_services_{$name}.xml is  the downloaded soap request document.  Add authorization parameters as neccesary.

};

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

import module namespace csd_psd = "https://github.com/openhie/openinfoman/csd_psd";
import module namespace csd_lsc = "https://github.com/openhie/openinfoman/csd_lsc";
import module namespace csd_dm = "https://github.com/openhie/openinfoman/csd_dm";
import module namespace csd_webconf =  "https://github.com/openhie/openinfoman/csd_webconf";
import module namespace csd_qus =  "https://github.com/openhie/openinfoman/csd_qus";

declare function page:redirect($redirect as xs:string) as element(restxq:redirect)
{
  <restxq:redirect>{ $redirect }</restxq:redirect>
};

declare function page:nocache($response) {
(
  <rest:response>
    <http:response >
      <http:header name="Cache-Control" value="must-revalidate,no-cache,no-store"/>
    </http:response>
  </rest:response>
,
  $response
)

};

declare updating
  %rest:path("/CSD/registerService/init")
  function page:init()
{
  (
    csd_lsc:init_cache_meta($csd_webconf:db)
    ,csd_psd:init($csd_webconf:db)
    ,db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )
};

declare updating
  %rest:path("/CSD/registerService/named/{$name}")
  %output:method("xhtml")
  %rest:GET
  function page:register_named($name)
{

  (
    let $sample := $csd_webconf:remote_services//serviceDirectory[@name=$name]
    return if (exists($sample)) then
      csd_psd:register_service($csd_webconf:db,$name,text{$sample/@url},$sample/credentials)
    else ()
  ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )
};

declare updating
  %rest:path("/CSD/registerService/basic_auth")
  %output:method("xhtml")
  %rest:query-param("name", "{$name}")
  %rest:query-param("url", "{$url}")
  %rest:query-param("password", "{$password}")
  %rest:query-param("username", "{$username}")
  %rest:GET
  function page:register_basic_auth($name,$url,$username,$password)
{

  (
    let $credentials := <credentials type="basic_auth" username="{$username}" password="{$password}"/>
    return csd_psd:register_service($csd_webconf:db,$name,$url,$credentials)
      ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )

};

declare
  %rest:path("/CSD/pollService/cache_meta")
  %rest:GET
  function page:get_cache_meta()
{
  csd_lsc:get_cache_data($csd_webconf:db,())
};

declare
  %rest:path("/CSD/pollService/directory/{$name}")
  %rest:GET
  %output:method("xhtml")
  function page:get_service_menu($name)
{
  let $response :=
{$name}
{page:service_menu($name) }
  return page:nocache(csd_webconf:wrapper($response))
};

declare
  %rest:path("/CSD/pollService/directory/{$name}/cache_meta")
  %rest:GET
  function page:get_service_cache_meta($name)
{
  csd_lsc:get_cache_data($csd_webconf:db,$name)
};

declare updating
  %rest:path("/CSD/pollService/directory/{$name}/create_cache")
  %rest:GET
  function page:create_cache($name)
{

  (
    if (csd_lsc:directory_exists($csd_webconf:db,$name))
    then csd_lsc:empty_cache($csd_webconf:db,$name)
    else csd_dm:empty($csd_webconf:db,$name)
  ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )

};

declare updating
  %rest:path("/CSD/pollService/directory/{$name}/drop_cache_meta")
  %rest:GET
  function page:drop_service_cache_meta($name)
{
  (
  csd_lsc:drop_cache_data($csd_webconf:db,$name)
  ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )

};

declare
  %rest:path("/CSD/pollService/directory/{$name}/get_cache")
  %rest:GET
  function page:get_cache($name)
{
 csd_lsc:get_cache($csd_webconf:db,$name)
};

declare updating
  %rest:path("/CSD/pollService/directory/{$name}/empty_cache")
  %rest:GET
  function page:empty_cache($name)
{
  (
  csd_lsc:empty_cache($csd_webconf:db,$name)
  ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
  )

};

declare updating
  %rest:path("/CSD/pollService/directory/{$name}/update_cache")
  %rest:GET
  function page:update_cache($name)
{
(
  csd_lsc:update_cache($csd_webconf:db,$name)   ,
  db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/pollService")))
)

};

declare
  %rest:path("/CSD/pollService/directory/{$name}/show_update_cache")
  %rest:GET
  function page:show_update_cache($name)
{

  let $db := $csd_webconf:db
  let $mtime :=  csd_lsc:get_service_directory_mtime($db,$name)
  let $soap := csd_psd:generate_soap_request($db,$name,$mtime)
  let $result := http:send-request($soap)
  return <r>{$result}</r><s>{$soap}</s>

};

declare
  %rest:path("/CSD/pollService/{$name}")
  %output:method("xhtml")
  %rest:GET
  function page:display_service_menu($name)
{
  let $response :=

	{page:service_menu($name)}

  return page:nocache(page:wrapper($response))
};

declare
  %rest:path("/CSD/pollService/{$name}/get")
  %rest:query-param("mtime", "{$mtime}")
  %rest:GET
  function page:poll_service($name,$mtime)
{
if ($mtime) then
 csd_psd:poll_service_directory_soap_response($csd_webconf:db,$name,$mtime)
else
 csd_psd:poll_service_directory_soap_response($csd_webconf:db,$name,csd_lsc:get_service_directory_mtime($csd_webconf:db,$name))
};

declare
  %rest:path("/CSD/pollService/{$name}/get_csd")
  %rest:query-param("mtime", "{$mtime}")
  %rest:GET
  function page:poll_service_csd($name,$mtime)
{
if ($mtime) then
 csd_psd:poll_service_directory($csd_webconf:db,$name,$mtime)
else
 csd_psd:poll_service_directory($csd_webconf:db,$name,csd_lsc:get_service_directory_mtime($csd_webconf:db,$name))
};

declare
  %rest:path("/CSD/pollService/{$name}/get_soap")
  %rest:query-param("mtime", "{$mtime}")
  %rest:GET
  function page:poll_service_soap($name,$mtime)
{
 let $url := csd_psd:get_service_directory_url($csd_webconf:db,$name)
 return (
 <rest:response>
   <http:response status="200" >
     <http:header name="Content-Type" value="application/soap+xml"/>
     <http:header name="Content-Disposition"  value="inline; filename=soap_query_updated_services_{$name}"/>
   </http:response>
   </rest:response>
   ,
   if ($mtime) then
     csd_qus:create_last_update_request($url,$mtime)
   else
     csd_qus:create_last_update_request($url,csd_lsc:get_service_directory_mtime($csd_webconf:db,$name))
 )

};

declare function page:wrapper($response) {
  let $headers :=
  (<link rel="stylesheet" type="text/css" media="screen"   href="{$csd_webconf:baseurl}static/bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css"/>
  ,
  )
  return csd_webconf:wrapper($response,$headers)
};

declare
  %rest:path("/CSD/pollService")
  %rest:GET
  %output:method("xhtml")
  function page:poll_service_list()
{

if (not(csd_psd:dm_exists($csd_webconf:db))) then
   page:redirect(concat($csd_webconf:baseurl,"CSD/registerService/init"))
 else
   let $services := csd_psd:registered_directories($csd_webconf:db)
   let $unreg_services :=
     for $sample in  $csd_webconf:remote_services//serviceDirectory
     where not(csd_psd:is_registered($csd_webconf:db,$sample/text{@name}))
     return  $sample
    let $response :=

Add New Service (Basic Auth)

	 <form method='get' action="/CSD/registerService/basic_auth">

 Name<input class='pull-right'  size="35"      name='name' type="text" value=""/>

URL<input  class='pull-right' size="35"     name='url' type="text" value=""/>

User Name<input  class='pull-right' size="35"     name='username' type="text" value=""/>

Password<input  class='pull-right' size="35"     name='password' type="text" value=""/>

	   <input type='submit' />
	 </form>

	 {
	   if (count($unreg_services) > 0) then

Add New Default Service

	       {for $sample in $unreg_services
	       let $name := $sample/text{@name}
	       return

		 Register {$name}

	       }

	 else ()
}

Global Operations

 Get all cache Meta-Data

Registered Service Directories

	 {if (count($services) = 0)
	 then
No Services Registered

       else

	 {for $name in $services
	 let $mtime := csd_lsc:get_service_directory_mtime($csd_webconf:db,$name)
	 order by $name
	 return

	   {$name} last cached on {$mtime}

	 }

	 }

  return page:nocache(page:wrapper($response))

};

declare function page:service_menu($name) {
  let $url := csd_psd:get_service_directory_url($csd_webconf:db,$name)
  let $mtime := csd_lsc:get_service_directory_mtime($csd_webconf:db,$name)
  return

{$url}

    modified: {$mtime}

Caching
{csd_lsc:get_document_name($name)}

    {if (not(csd_lsc:directory_exists($csd_webconf:db,$name))) then
      (

Create cache of {$name}

      )
  else
    (

Empty local cache of {$name}
,

Get local cache  of {$name}
,

      Update local cache  of {$name}

	WARNING:An InfoMan trying to cache its own service directory will result in a deadlock.  see this issue

,

Get cache Meta Data  for {$name}
,

Drop cache Meta Data  of {$name}

  )
    }

Testing

 Query  {$name} for Updated Services using stored last modified time (SOAP result)

 Query  {$name} for Updated Services using stored last modified time (CSD result)

 Get {$name}'s Soap Query for Updated Services Request using stored last modified time

    Query {$name} for Updated Services by time
    <form method='get' action="/CSD/pollService/{$name}/get">
      <input  size="35" id="datetimepicker_{$name}"    name='mtime' type="text" value="{$mtime}"/>
      <input type='submit' />
    </form>

    Get {$name}'s SOAP reuest for Query for Updated Services by time
    <form method='get' action="/CSD/pollService/soap_query_updated_services_{$name}">
      <input  size="35" id="soap_datetimepicker_{$name}"  name='mtime' type="text" value="{$mtime}"/>
      <input type='submit' />
    </form>

  To test submission on your machine you can do:

curl --header "content-type: application/soap+xml" --data "@soap_query_updated_services_{$name}.xml" {$url}

  where soap_updated_services_{$name}.xml is  the downloaded soap request document.  Add authorization parameters as neccesary.

};