exported documentation now also include updating functions

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

import module namespace csd_webconf =  "https://github.com/his-interop/openinfoman/csd_webconf" at "../repo/csd_webapp_config.xqm";
import module namespace csr_proc = "https://github.com/his-interop/openinfoman/csr_proc" at "../repo/csr_processor.xqm";
declare   namespace   xforms = "http://www.w3.org/2002/xforms";
declare namespace xs = "http://www.w3.org/2001/XMLSchema";
declare   namespace   csd = "urn:ihe:iti:csd:2013";
declare default element  namespace   "urn:ihe:iti:csd:2013";
import module namespace random = "http://basex.org/modules/random";
import module namespace bin = "http://expath.org/ns/binary";
declare variable $page:xsl := "../resources/doc_careServiceFunctions.xsl";

declare
  %rest:path("/CSD/storedFunctions")
  %rest:GET
  %output:method("xhtml")
  function page:csr_list()
{
if (not (db:is-xml($csd_webconf:db,$csr_proc:stored_functions_doc))) then
  let $content:=

No Registered Functions

    Please intialize the stored function  manager in order to start using the stored functions

  return page:wrapper_simple($content)
else
  let $new := page:new_stored_function()
  let $reload:=

Load Registered Functions

    Reload stored functions from disk

  let $list := page:function_list()
  return page:wrapper(($reload,$list),$new)
};

declare updating
  %rest:path("/CSD/storedFunctions/upload")
  %rest:consumes("application/xml", "text/xml", "multipart/form-data")
  %rest:form-param("upload","{$upload}")
  %rest:POST
  function page:upload($upload)
{
 for $name    in map:keys($upload)
 let $content := $upload($name)
 let $func := parse-xml(bin:decode-string($content, 'UTF-8'))
 return
   (
     csr_proc:load_stored_function($csd_webconf:db,$func/careServicesFunction)
     ,
   db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/storedFunctions")))
  )

};

declare function page:new_stored_function()
{

Upload careServicesFunction Document

   <form method='post' action="/CSD/storedFunctions/upload"  enctype="multipart/form-data">
   Upload<input name='upload' type='file'/>
   <input type="submit" value="submit"/>
   </form>

Create New Stored Function

   <form method='post' action="/CSD/storedFunctions/create"  enctype="multipart/form-data">
     UUID<input    size="42" name="uuid" value="{random:uuid()}"  readonly="readonly"/>

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

     Description<textarea  rows="20" cols="80" name="description" ></textarea>

     XQuery<textarea  rows="20" cols="80" name="query" ></textarea>

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

};

declare  updating
  %rest:path("/CSD/storedFunctions/delete/{$uuid}")
  function page:delete($uuid)
  {
    (
      csr_proc:delete_stored_function($csd_webconf:db,$uuid),
      db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/storedFunctions")))
    )

};

declare  updating
  %rest:path("/CSD/storedFunctions/create")
  %rest:consumes("application/xml", "text/xml", "multipart/form-data")
  %rest:POST
  %rest:form-param("query","{$query}")
  %rest:form-param("description","{$description}")
  %rest:form-param("content", "{$content}","application/xml")
  %rest:form-param("uuid", "{$uuid}")
  function page:create($uuid,$query,$description,$content)
{
(  if ($uuid) then
   let $func :=
   <careServicesFunction uuid="{$uuid}" content-type="{$content}">
     <description>{$description}</description>
     <definition>{$query}</definition>
   </careServicesFunction>
   return csr_proc:load_stored_function($csd_webconf:db,$func)
  else (),
    db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/storedFunctions")))
)
};

declare updating
  %rest:path("/CSD/storedFunctions/init")
  %rest:GET
  function page:init()
{
(csr_proc:init($csd_webconf:db),
db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/storedFunctions")))
)
};

declare updating
  %rest:path("/CSD/storedFunctions/reload")
  %rest:GET
  function page:reload()
{
(csr_proc:load_functions_from_files($csd_webconf:db),
db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/storedFunctions")))
)
};

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

declare function page:display_function($function,$updating) {
  let  $uuid := string($function/@uuid)
  return
    {if ($updating) then  "(Updating) " else ()}
    UUID: {string($uuid)}

    Method:

{string($function/definition)}

    Content: {string(csr_proc:lookup_stored_content_type($csd_webconf:db,$uuid)) }

    Description:
{$function/description}

    Instance:

{serialize($function/xforms:instance/careServicesRequest,map{'indent':='yes'})}

    {if (exists($function/@method)) then  ("Method: ",string($function/@method),
) else () }
    {if (exists($function/xs:schema)) then  ("Schema: ",string($function/xs:schema),
) else () }
    {if (count( $function/xforms:bind) > 0) then
    ("Bindings: ",

        {for $bind in $function/xforms:bind return
Node set: {string($bind/@nodeset)}
Type: {string($bind/@type)}
}

    ) else ()
    }

};

declare
  %rest:path("/CSD/storedFunctions/export_doc")
  %rest:GET
  %output:method("xhtml")
  function page:export_doc()
{
  let $funcs :=
  <careServiceFunctions
    xmlns:xforms="http://www.w3.org/2002/xforms"
    xmlns:csd="urn:ihe:iti:csd:2013"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:hfp="http://www.w3.org/2001/XMLSchema-hasFacetAndProperty"
     >
  {(
    csr_proc:stored_functions($csd_webconf:db)
    ,csr_proc:stored_updating_functions($csd_webconf:db)
   )}
 </careServiceFunctions>
(: return $funcs :)
 return xslt:transform($funcs,doc($page:xsl))
};

declare function page:function_list()  {

Registered Stored Queries

    {count(csr_proc:stored_functions($csd_webconf:db))} Stored Functions

    {count(csr_proc:stored_updating_functions($csd_webconf:db))} Stored Updating Functions

    Export Documentation

    {
      for $function in (csr_proc:stored_functions($csd_webconf:db),csr_proc:stored_updating_functions($csd_webconf:db))
      return

UUID: {string($function/@uuid)} {"  "}

	{substring(string($function/description),1,100)}
	{if (string-length(string($function/description)) > 100) then "..." else ()}

      View
      Delete

    }

    {
      for $function in (csr_proc:stored_functions($csd_webconf:db),csr_proc:stored_updating_functions($csd_webconf:db))
      return

{page:display_function($function,false())}

    }

};

declare function page:wrapper($list,$new) {

    <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"/>

          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">

          </button>
          OpenInfoMan

Available Functions

Upload Function

{$list}

{$new}

};

declare function page:wrapper_simple($content) {

    <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 csd_webconf =  "https://github.com/his-interop/openinfoman/csd_webconf" at "../repo/csd_webapp_config.xqm";
import module namespace csr_proc = "https://github.com/his-interop/openinfoman/csr_proc" at "../repo/csr_processor.xqm";
declare   namespace   xforms = "http://www.w3.org/2002/xforms";
declare namespace xs = "http://www.w3.org/2001/XMLSchema";
declare   namespace   csd = "urn:ihe:iti:csd:2013";
declare default element  namespace   "urn:ihe:iti:csd:2013";
import module namespace random = "http://basex.org/modules/random";
import module namespace bin = "http://expath.org/ns/binary";
declare variable $page:xsl := "../resources/doc_careServiceFunctions.xsl";

declare
  %rest:path("/CSD/storedFunctions")
  %rest:GET
  %output:method("xhtml")
  function page:csr_list()
{
if (not (db:is-xml($csd_webconf:db,$csr_proc:stored_functions_doc))) then
  let $content:=

No Registered Functions

    Please intialize the stored function  manager in order to start using the stored functions

  return page:wrapper_simple($content)
else
  let $new := page:new_stored_function()
  let $reload:=

Load Registered Functions

    Reload stored functions from disk

  let $list := page:function_list()
  return page:wrapper(($reload,$list),$new)
};

declare updating
  %rest:path("/CSD/storedFunctions/upload")
  %rest:consumes("application/xml", "text/xml", "multipart/form-data")
  %rest:form-param("upload","{$upload}")
  %rest:POST
  function page:upload($upload)
{
 for $name    in map:keys($upload)
 let $content := $upload($name)
 let $func := parse-xml(bin:decode-string($content, 'UTF-8'))
 return
   (
     csr_proc:load_stored_function($csd_webconf:db,$func/careServicesFunction)
     ,
   db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/storedFunctions")))
  )

};

declare function page:new_stored_function()
{

Upload careServicesFunction Document

   <form method='post' action="/CSD/storedFunctions/upload"  enctype="multipart/form-data">
   Upload<input name='upload' type='file'/>
   <input type="submit" value="submit"/>
   </form>

Create New Stored Function

   <form method='post' action="/CSD/storedFunctions/create"  enctype="multipart/form-data">
     UUID<input    size="42" name="uuid" value="{random:uuid()}"  readonly="readonly"/>

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

     Description<textarea  rows="20" cols="80" name="description" ></textarea>

     XQuery<textarea  rows="20" cols="80" name="query" ></textarea>

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

};

declare  updating
  %rest:path("/CSD/storedFunctions/delete/{$uuid}")
  function page:delete($uuid)
  {
    (
      csr_proc:delete_stored_function($csd_webconf:db,$uuid),
      db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/storedFunctions")))
    )

};

declare  updating
  %rest:path("/CSD/storedFunctions/create")
  %rest:consumes("application/xml", "text/xml", "multipart/form-data")
  %rest:POST
  %rest:form-param("query","{$query}")
  %rest:form-param("description","{$description}")
  %rest:form-param("content", "{$content}","application/xml")
  %rest:form-param("uuid", "{$uuid}")
  function page:create($uuid,$query,$description,$content)
{
(  if ($uuid) then
   let $func :=
   <careServicesFunction uuid="{$uuid}" content-type="{$content}">
     <description>{$description}</description>
     <definition>{$query}</definition>
   </careServicesFunction>
   return csr_proc:load_stored_function($csd_webconf:db,$func)
  else (),
    db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/storedFunctions")))
)
};

declare updating
  %rest:path("/CSD/storedFunctions/init")
  %rest:GET
  function page:init()
{
(csr_proc:init($csd_webconf:db),
db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/storedFunctions")))
)
};

declare updating
  %rest:path("/CSD/storedFunctions/reload")
  %rest:GET
  function page:reload()
{
(csr_proc:load_functions_from_files($csd_webconf:db),
db:output(page:redirect(concat($csd_webconf:baseurl,"CSD/storedFunctions")))
)
};

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

declare function page:display_function($function,$updating) {
  let  $uuid := string($function/@uuid)
  return
    {if ($updating) then  "(Updating) " else ()}
    UUID: {string($uuid)}

    Method:

{string($function/definition)}

    Content: {string(csr_proc:lookup_stored_content_type($csd_webconf:db,$uuid)) }

    Description:
{$function/description}

    Instance:

{serialize($function/xforms:instance/careServicesRequest,map{'indent':='yes'})}

    {if (exists($function/@method)) then  ("Method: ",string($function/@method),
) else () }
    {if (exists($function/xs:schema)) then  ("Schema: ",string($function/xs:schema),
) else () }
    {if (count( $function/xforms:bind) > 0) then
    ("Bindings: ",

        {for $bind in $function/xforms:bind return
Node set: {string($bind/@nodeset)}
Type: {string($bind/@type)}
}

    ) else ()
    }

};

declare
  %rest:path("/CSD/storedFunctions/export_doc")
  %rest:GET
  %output:method("xhtml")
  function page:export_doc()
{
  let $funcs :=
  <careServiceFunctions
    xmlns:xforms="http://www.w3.org/2002/xforms"
    xmlns:csd="urn:ihe:iti:csd:2013"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:hfp="http://www.w3.org/2001/XMLSchema-hasFacetAndProperty"
     >
  {(
    csr_proc:stored_functions($csd_webconf:db)
    ,csr_proc:stored_functions($csd_webconf:db)
   )}
 </careServiceFunctions>
(: return $funcs :)
 return xslt:transform($funcs,doc($page:xsl))
};

declare function page:function_list()  {

Registered Stored Queries

    {count(csr_proc:stored_functions($csd_webconf:db))} Stored Functions

    {count(csr_proc:stored_updating_functions($csd_webconf:db))} Stored Updating Functions

    Export Documentation

    {
      for $function in (csr_proc:stored_functions($csd_webconf:db),csr_proc:stored_updating_functions($csd_webconf:db))
      return

UUID: {string($function/@uuid)} {"  "}

	{substring(string($function/description),1,100)}
	{if (string-length(string($function/description)) > 100) then "..." else ()}

      View
      Delete

    }

    {
      for $function in (csr_proc:stored_functions($csd_webconf:db),csr_proc:stored_updating_functions($csd_webconf:db))
      return

{page:display_function($function,false())}

    }

};

declare function page:wrapper($list,$new) {

    <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"/>

          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">

          </button>
          OpenInfoMan

Available Functions

Upload Function

{$list}

{$new}

};

declare function page:wrapper_simple($content) {

    <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"/>


[bugfix] delete of document failed, to double presence of collection parameter.

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

xquery version "1.0";
(: $Id$ :)
(:
    Module: display and browse collections.
:)

module namespace browse="http://exist-db.org/xquery/admin-interface/browse";

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

import module namespace date="http://exist-db.org/xquery/admin-interface/date" at "dates.xqm";

(:
    Main function: outputs the page.
:)
declare function browse:main() as element()
{
    let $colName := request:get-parameter("collection", "/db")[1] return

            { browse:process-action($colName) }

Browsing Collection: {xdb:decode-uri(xs:anyURI($colName))}

            <form method="POST" enctype="multipart/form-data">
                {
                    browse:display-collection($colName)
                }

<input type="submit" name="action" value="Remove Selected"/>

                        <input type="submit" name="action" value="Create Collection"/>
                        New collection:

                        <input type="text" name="create" size="40"/>

                        <input type="submit" name="action" value="Upload"/>
                        <input type="file" size="30" name="upload"/>
                        Store as:

                        <input type="text" name="name" size="20"/>

                <input type="hidden" name="collection" value="{$colName}"/>
                <input type="hidden" name="panel" value="browse"/>
            </form>

};

(:
    Process an action.
:)
declare function browse:process-action($colName as xs:string) as element()*
{
    let $action := request:get-parameter("action", ()) return
        util:catch("java.lang.Exception",
            if($action eq "Remove Selected") then
            (
                browse:remove()
            )
            else if($action eq "Create Collection") then
            (
                browse:create-collection($colName)
            )
            else if($action eq "Store") then
            (
                browse:store($colName)
            )
            else if($action eq "Upload") then
            (
                browse:upload($colName)
            )else(),

                An error occurred while processing the action:

                {$util:exception-message}

        )
};

(:
    Store uploaded content.
:)
declare function browse:upload($colName as xs:string) as element()
{
    let $name := request:get-parameter("name", ()),
    $docName := if($name) then $name else request:get-uploaded-file-name("upload"),
    $file := request:get-uploaded-file-data("upload") return

Actions:

Storing uploaded content to: {$docName}

                {
                    xdb:decode-uri(xs:anyURI(xdb:store($colName, xdb:encode-uri($docName), $file)))
                }

};

(:
    Store files from an URI.

    Allowing this opens a security whole as a user can
    upload arbitrary files on the server if the process is running
    as root.
:)
declare function browse:store($colName as xs:string) as element()
{
    let $uri := request:get-parameter("uri", ()),
    $path := if(starts-with($uri, "file:")) then $uri else concat("file:", $uri),
    $docName := request:get-parameter("name", ()) return

Actions:

Storing resources from URI: {$path}

                {
                    xdb:store($colName, $docName, xs:anyURI($path))
                }

};

(:
    Remove a set of resources.
:)
declare function browse:remove() as element()
{
    let $resources := request:get-parameter("resource", ()) return

Actions:

                {
                    for $resource in $resources
                    return
                        browse:remove-resource($resource)
                }

};

(:
    Remove a resource.
:)
declare function browse:remove-resource($resource as xs:string) as element()*
{
    let $isBinary := util:binary-doc-available($resource),
    $doc := if ($isBinary) then $resource else doc($resource) return

        if($doc)then
        (

Removing document: {xdb:decode-uri(xs:anyURI($resource))} ...
,
            xdb:remove(util:collection-name($doc), util:document-name($doc))
        )
        else
        (

Removing collection: {xdb:decode-uri(xs:anyURI($resource))} ...
,
            xdb:remove($resource)
        )
};

(:
    Create a collection.
:)
declare function browse:create-collection($parentColName as xs:string) as element()
{
    let $newcol := request:get-parameter("create", ()) return

Actions:

            {
                if($newcol) then
                (
                    let $col := xdb:create-collection($parentColName, xdb:encode-uri($newcol)) return

Created collection: {xdb:decode-uri(xs:anyURI(util:collection-name($col)))}.

                )
                else
                (

No name specified for new collection!

                )
            }

};

(:
    Display the contents of a collection in a table view.
:)
declare function browse:display-collection($colName as xs:string) as element()
{

            Name
            Permissions
            Owner
            Group
            Created
            Modified
            Size (KB)
			Revision

            Up
            Refresh

        {
            browse:display-child-collections($colName),
            browse:display-child-resources($colName)
        }

};

declare function browse:display-child-collections($colName as xs:string) as element()*
{
    for $child in xdb:get-child-collections($colName)
        let $path := concat($colName, '/', $child),
        $created := xdb:created($path)
    order by $child return

            <input type="checkbox" name="resource" value="{$path}"/>
            {xdb:decode-uri(xs:anyURI($child))}
            {xdb:permissions-to-string(xdb:get-permissions($path))}
            {xdb:get-owner($path)}
            {xdb:get-group($path)}
            {date:format-dateTime($created)}

};

declare function browse:display-child-resources($colName as xs:string) as element()*
{
    for $child in xdb:get-child-resources($colName)
    let $restUri := concat(request:get-context-path(), '/rest')
    order by $child
	return

            <input type="checkbox" name="resource" value="{$colName}/{$child}"/>
            {xdb:decode-uri(xs:anyURI($child))}
            {xdb:permissions-to-string(xdb:get-permissions($colName, $child))}
            {xdb:get-owner($colName, $child)}
            {xdb:get-group($colName, $child)}
            {date:format-dateTime(xdb:created($colName, $child))}
            {date:format-dateTime(xdb:last-modified($colName, $child))}
            {fn:ceiling(xdb:size($colName, $child) div 1024)}

				{browse:last-revision($colName, $child)//v:properties/v:revision/string()}

};

declare function browse:get-child-resource-name( $child ) as xs:string
{
	(: This function will properly encode resource names "." and ".." so that the generated href url will work correctly :)

	let $name := xdb:encode-uri( $child )

	return if( $name = "." ) then "%2E"
		    else if( $name = ".." ) then "%2E%2E"
		    else $name
};

declare function browse:last-revision($collection as xs:string, $resource as xs:string) {
	let $vCollection := concat("/db/system/versions", $collection)
	let $versions :=
		for $version in collection($vCollection)/v:version[
			v:properties[v:document = $resource]
		]
		order by xs:long($version/v:properties/v:revision) descending
		return $version
	return
		$versions[1]
};

(:
    Get the name of the parent collection from a specified collection path.
:)
declare function browse:get-parent-collection($path as xs:string) as xs:string
{
    if($path eq "/db") then
        $path
    else
        replace($path, "/[^/]*$", "")
};

xquery version "1.0";
(: $Id$ :)
(:
    Module: display and browse collections.
:)

module namespace browse="http://exist-db.org/xquery/admin-interface/browse";

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

import module namespace date="http://exist-db.org/xquery/admin-interface/date" at "dates.xqm";

(:
    Main function: outputs the page.
:)
declare function browse:main() as element()
{
    let $colName := request:get-parameter("collection", "/db") return

            { browse:process-action($colName) }

Browsing Collection: {xdb:decode-uri(xs:anyURI($colName))}

            <form method="POST" enctype="multipart/form-data">
                {
                    browse:display-collection($colName)
                }

<input type="submit" name="action" value="Remove Selected"/>

                        <input type="submit" name="action" value="Create Collection"/>
                        New collection:

                        <input type="text" name="create" size="40"/>

                        <input type="submit" name="action" value="Upload"/>
                        <input type="file" size="30" name="upload"/>
                        Store as:

                        <input type="text" name="name" size="20"/>

                <input type="hidden" name="collection" value="{$colName}"/>
                <input type="hidden" name="panel" value="browse"/>
            </form>

};

(:
    Process an action.
:)
declare function browse:process-action($colName as xs:string) as element()*
{
    let $action := request:get-parameter("action", ()) return
        util:catch("java.lang.Exception",
            if($action eq "Remove Selected") then
            (
                browse:remove()
            )
            else if($action eq "Create Collection") then
            (
                browse:create-collection($colName)
            )
            else if($action eq "Store") then
            (
                browse:store($colName)
            )
            else if($action eq "Upload") then
            (
                browse:upload($colName)
            )else(),

                An error occurred while processing the action:

                {$util:exception-message}

        )
};

(:
    Store uploaded content.
:)
declare function browse:upload($colName as xs:string) as element()
{
    let $name := request:get-parameter("name", ()),
    $docName := if($name) then $name else request:get-uploaded-file-name("upload"),
    $file := request:get-uploaded-file-data("upload") return

Actions:

Storing uploaded content to: {$docName}

                {
                    xdb:decode-uri(xs:anyURI(xdb:store($colName, xdb:encode-uri($docName), $file)))
                }

};

(:
    Store files from an URI.

    Allowing this opens a security whole as a user can
    upload arbitrary files on the server if the process is running
    as root.
:)
declare function browse:store($colName as xs:string) as element()
{
    let $uri := request:get-parameter("uri", ()),
    $path := if(starts-with($uri, "file:")) then $uri else concat("file:", $uri),
    $docName := request:get-parameter("name", ()) return

Actions:

Storing resources from URI: {$path}

                {
                    xdb:store($colName, $docName, xs:anyURI($path))
                }

};

(:
    Remove a set of resources.
:)
declare function browse:remove() as element()
{
    let $resources := request:get-parameter("resource", ()) return

Actions:

                {
                    for $resource in $resources
                    return
                        browse:remove-resource($resource)
                }

};

(:
    Remove a resource.
:)
declare function browse:remove-resource($resource as xs:string) as element()*
{
    let $isBinary := util:binary-doc-available($resource),
    $doc := if ($isBinary) then $resource else doc($resource) return

        if($doc)then
        (

Removing document: {xdb:decode-uri(xs:anyURI($resource))} ...
,
            xdb:remove(util:collection-name($doc), util:document-name($doc))
        )
        else
        (

Removing collection: {xdb:decode-uri(xs:anyURI($resource))} ...
,
            xdb:remove($resource)
        )
};

(:
    Create a collection.
:)
declare function browse:create-collection($parentColName as xs:string) as element()
{
    let $newcol := request:get-parameter("create", ()) return

Actions:

            {
                if($newcol) then
                (
                    let $col := xdb:create-collection($parentColName, xdb:encode-uri($newcol)) return

Created collection: {xdb:decode-uri(xs:anyURI(util:collection-name($col)))}.

                )
                else
                (

No name specified for new collection!

                )
            }

};

(:
    Display the contents of a collection in a table view.
:)
declare function browse:display-collection($colName as xs:string) as element()
{

            Name
            Permissions
            Owner
            Group
            Created
            Modified
            Size (KB)
			Revision

            Up
            Refresh

        {
            browse:display-child-collections($colName),
            browse:display-child-resources($colName)
        }

};

declare function browse:display-child-collections($colName as xs:string) as element()*
{
    for $child in xdb:get-child-collections($colName)
        let $path := concat($colName, '/', $child),
        $created := xdb:created($path)
    order by $child return

            <input type="checkbox" name="resource" value="{$path}"/>
            {xdb:decode-uri(xs:anyURI($child))}
            {xdb:permissions-to-string(xdb:get-permissions($path))}
            {xdb:get-owner($path)}
            {xdb:get-group($path)}
            {date:format-dateTime($created)}

};

declare function browse:display-child-resources($colName as xs:string) as element()*
{
    for $child in xdb:get-child-resources($colName)
    let $restUri := concat(request:get-context-path(), '/rest')
    order by $child
	return

            <input type="checkbox" name="resource" value="{$colName}/{$child}"/>
            {xdb:decode-uri(xs:anyURI($child))}
            {xdb:permissions-to-string(xdb:get-permissions($colName, $child))}
            {xdb:get-owner($colName, $child)}
            {xdb:get-group($colName, $child)}
            {date:format-dateTime(xdb:created($colName, $child))}
            {date:format-dateTime(xdb:last-modified($colName, $child))}
            {fn:ceiling(xdb:size($colName, $child) div 1024)}

				{browse:last-revision($colName, $child)//v:properties/v:revision/string()}

};

declare function browse:get-child-resource-name( $child ) as xs:string
{
	(: This function will properly encode resource names "." and ".." so that the generated href url will work correctly :)

	let $name := xdb:encode-uri( $child )

	return if( $name = "." ) then "%2E"
		    else if( $name = ".." ) then "%2E%2E"
		    else $name
};

declare function browse:last-revision($collection as xs:string, $resource as xs:string) {
	let $vCollection := concat("/db/system/versions", $collection)
	let $versions :=
		for $version in collection($vCollection)/v:version[
			v:properties[v:document = $resource]
		]
		order by xs:long($version/v:properties/v:revision) descending
		return $version
	return
		$versions[1]
};

(:
    Get the name of the parent collection from a specified collection path.
:)
declare function browse:get-parent-collection($path as xs:string) as xs:string
{
    if($path eq "/db") then
        $path
    else
        replace($path, "/[^/]*$", "")
};


[bugfix] prevent login html admin client if 1st time username is mistyped (copy of parameters)

svn path=/stable/eXist-1.4.x/; revision=14995

xquery version "1.0";
(: $Id$ :)
(:
    Main module of the database administration interface.
:)

declare namespace admin = "http://exist-db.org/xquery/admin-interface";

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

import module namespace status = "http://exist-db.org/xquery/admin-interface/status" at "status.xqm";
import module namespace browse = "http://exist-db.org/xquery/admin-interface/browse" at "browse.xqm";
import module namespace users = "http://exist-db.org/xquery/admin-interface/users" at "users.xqm";
import module namespace xqueries = "http://exist-db.org/xquery/admin-interface/xqueries" at "xqueries.xqm";
import module namespace shut = "http://exist-db.org/xquery/admin-interface/shutdown" at "shutdown.xqm";
import module namespace setup = "http://exist-db.org/xquery/admin-interface/setup" at "setup.xqm";
import module namespace rev="http://exist-db.org/xquery/admin-interface/revisions" at "versions.xqm";
import module namespace backup="http://exist-db.org/xquery/admin-interface/backup" at "backup.xqm";
import module namespace prof="http://exist-db.org/xquery/profiling" at "trace.xqm";
import module namespace grammar="http://exist-db.org/xquery/admin-interface/grammar" at "grammar.xqm";
import module namespace install="http://exist-db.org/xquery/install-tools" at "install.xqm";
import module namespace fundocs="http://exist-db.org/xquery/admin/fundocs" at "fundocs.xqm";

declare option exist:serialize "method=xhtml media-type=text/html";

(:
    Display the version, SVN revision and user info in the top right corner
:)
declare function admin:info-header() as element()
{

Version: { util:system-property( "product-version" ) }

SVN Revision: { util:system-property( "svn-revision" ) }

Build: {util:system-property("product-build")}

User: { xdb:get-current-user() }

};

(:
    Select the page to show. Every page is defined in its own module
:)
declare function admin:panel() as element()
{
    let $panel := request:get-parameter("panel", "status") return
        if($panel eq "browse") then
        (
            browse:main()
        )
        else if($panel eq "users") then
        (
            users:main()
        )
         else if($panel eq "xqueries") then
        (
            xqueries:main()
        )
        else if($panel eq "shutdown") then
        (
            shut:main()
        )
        else if($panel eq "setup") then
        (
            setup:main()
        )
        else if ($panel eq "fundocs") then
        (
            fundocs:main()
        )
		else if ($panel eq "revisions") then
		(
			rev:main()
		)
		else if ($panel eq "backup") then
		(
		    backup:main()
		)
	    else if ($panel eq "trace") then
	    (
	        prof:main()
        )
        else if ($panel eq "grammar") then
	    (
	        grammar:main()
        )
        else if ($panel eq "install") then
        (
            install:main()
        )
        else
        (
            status:main()
        )
};

declare function admin:panel-header() {
    let $panel := request:get-parameter("panel", "status")
    return
        if ($panel eq "install") then
            install:header()
        else
            <xf:model xmlns:xf="http://www.w3.org/2002/xforms">
            </xf:model>
};

(:~
    Display the login form.
:)
declare function admin:display-login-form() as element()
{

Login

This is a protected resource. Only registered database users can log
        in. If you have not set up any users, login as "admin" and leave the
        password field empty. Note that the "guest" user is not permitted access.

        <form action="{session:encode-url(request:get-uri())}" method="post">

                    Please Login

                    Username:
                    <input name="user" type="text" size="20"/>

                    Password:
                    <input name="pass" type="password" size="20"/>

                    <input type="submit"/>

            {
                for $param in request:get-parameter-names()
                return
                    if ( $param = ("user","pass") ) then
                        ()
                    else
                        <input type="hidden" name="{$param}" value="{request:get-parameter($param, ())}"/>

            }
        </form>

};

(: main entry point :)
let $isLoggedIn :=  if(xdb:get-current-user() eq "guest")then
    (
        (: is this a login attempt? :)
        if(request:get-parameter("user", ()) and not(empty(request:get-parameter("pass", ()))))then
        (
            if(request:get-parameter("user", ()) eq "guest")then
            (
                (: prevent the guest user from accessing the admin webapp :)
                false()
            )
            else
            (
                (: try and log the user in :)
                xdb:login( "/db", request:get-parameter("user", ()), request:get-parameter("pass", () ), true() )
            )
        )
        else
        (
            (: prevent the guest user from accessing the admin webapp :)
            false()
        )
    )
    else
    (
        (: if we are already logged in, are we logging out - i.e. set permissions back to guest :)
        if(request:get-parameter("logout",()))then
        (
        	let $null  := xdb:login("/db", "guest", "guest")
            let $inval := session:invalidate()

            return false()
        )
        else
        (
             (: we are already logged in and we are not the guest user :)
            true()
        )
    )
return (
    <?css-conversion no?>,

            <title>eXist Database Administration</title>
            <link type="text/css" href="admin.css" rel="stylesheet"/>
			<link type="text/css" href="styles/prettify.css" rel="stylesheet"/>
			<link type="text/css" href="../scripts/yui/yui-skin.css" rel="stylesheet"/>
            <link rel="shortcut icon" href="../resources/exist_icon_16x16.ico"/>
			<link rel="icon" href="../resources/exist_icon_16x16.png" type="image/png"/>

			{ admin:panel-header() }

                {admin:info-header()}

Select a Page

                    {
                        let $link := session:encode-url(request:get-uri())
                        return

Home

System Status

Browse Collections

User Management

View Running Jobs

Examples Setup

Install Tools

Install Documentation

Backups

Query Profiling

Grammar cache

Shutdown

Logout

                    }

                        Logged in as: {xdb:get-current-user()}

                {
                    if($isLoggedIn)then
                    (
                        admin:panel()
                    )
                    else
                    (
                        admin:display-login-form()
                    )
                }

)

xquery version "1.0";
(: $Id$ :)
(:
    Main module of the database administration interface.
:)

declare namespace admin = "http://exist-db.org/xquery/admin-interface";

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

import module namespace status = "http://exist-db.org/xquery/admin-interface/status" at "status.xqm";
import module namespace browse = "http://exist-db.org/xquery/admin-interface/browse" at "browse.xqm";
import module namespace users = "http://exist-db.org/xquery/admin-interface/users" at "users.xqm";
import module namespace xqueries = "http://exist-db.org/xquery/admin-interface/xqueries" at "xqueries.xqm";
import module namespace shut = "http://exist-db.org/xquery/admin-interface/shutdown" at "shutdown.xqm";
import module namespace setup = "http://exist-db.org/xquery/admin-interface/setup" at "setup.xqm";
import module namespace rev="http://exist-db.org/xquery/admin-interface/revisions" at "versions.xqm";
import module namespace backup="http://exist-db.org/xquery/admin-interface/backup" at "backup.xqm";
import module namespace prof="http://exist-db.org/xquery/profiling" at "trace.xqm";
import module namespace grammar="http://exist-db.org/xquery/admin-interface/grammar" at "grammar.xqm";
import module namespace install="http://exist-db.org/xquery/install-tools" at "install.xqm";
import module namespace fundocs="http://exist-db.org/xquery/admin/fundocs" at "fundocs.xqm";

declare option exist:serialize "method=xhtml media-type=text/html";

(:
    Display the version, SVN revision and user info in the top right corner
:)
declare function admin:info-header() as element()
{

Version: { util:system-property( "product-version" ) }

SVN Revision: { util:system-property( "svn-revision" ) }

Build: {util:system-property("product-build")}

User: { xdb:get-current-user() }

};

(:
    Select the page to show. Every page is defined in its own module
:)
declare function admin:panel() as element()
{
    let $panel := request:get-parameter("panel", "status") return
        if($panel eq "browse") then
        (
            browse:main()
        )
        else if($panel eq "users") then
        (
            users:main()
        )
         else if($panel eq "xqueries") then
        (
            xqueries:main()
        )
        else if($panel eq "shutdown") then
        (
            shut:main()
        )
        else if($panel eq "setup") then
        (
            setup:main()
        )
        else if ($panel eq "fundocs") then
        (
            fundocs:main()
        )
		else if ($panel eq "revisions") then
		(
			rev:main()
		)
		else if ($panel eq "backup") then
		(
		    backup:main()
		)
	    else if ($panel eq "trace") then
	    (
	        prof:main()
        )
        else if ($panel eq "grammar") then
	    (
	        grammar:main()
        )
        else if ($panel eq "install") then
        (
            install:main()
        )
        else
        (
            status:main()
        )
};

declare function admin:panel-header() {
    let $panel := request:get-parameter("panel", "status")
    return
        if ($panel eq "install") then
            install:header()
        else
            <xf:model xmlns:xf="http://www.w3.org/2002/xforms">
            </xf:model>
};

(:~
    Display the login form.
:)
declare function admin:display-login-form() as element()
{

Login

This is a protected resource. Only registered database users can log
        in. If you have not set up any users, login as "admin" and leave the
        password field empty. Note that the "guest" user is not permitted access.

        <form action="{session:encode-url(request:get-uri())}" method="post">

                    Please Login

                    Username:
                    <input name="user" type="text" size="20"/>

                    Password:
                    <input name="pass" type="password" size="20"/>

                    <input type="submit"/>

            {
                for $param in request:get-parameter-names()
                return
                    <input type="hidden" name="{$param}"
                        value="{request:get-parameter($param, ())}"/>
            }
        </form>

};

(: main entry point :)
let $isLoggedIn :=  if(xdb:get-current-user() eq "guest")then
    (
        (: is this a login attempt? :)
        if(request:get-parameter("user", ()) and not(empty(request:get-parameter("pass", ()))))then
        (
            if(request:get-parameter("user", ()) eq "guest")then
            (
                (: prevent the guest user from accessing the admin webapp :)
                false()
            )
            else
            (
                (: try and log the user in :)
                xdb:login( "/db", request:get-parameter("user", ()), request:get-parameter("pass", () ), true() )
            )
        )
        else
        (
            (: prevent the guest user from accessing the admin webapp :)
            false()
        )
    )
    else
    (
        (: if we are already logged in, are we logging out - i.e. set permissions back to guest :)
        if(request:get-parameter("logout",()))then
        (
        	let $null  := xdb:login("/db", "guest", "guest")
            let $inval := session:invalidate()

            return false()
        )
        else
        (
             (: we are already logged in and we are not the guest user :)
            true()
        )
    )
return (
    <?css-conversion no?>,

            <title>eXist Database Administration</title>
            <link type="text/css" href="admin.css" rel="stylesheet"/>
			<link type="text/css" href="styles/prettify.css" rel="stylesheet"/>
			<link type="text/css" href="../scripts/yui/yui-skin.css" rel="stylesheet"/>
            <link rel="shortcut icon" href="../resources/exist_icon_16x16.ico"/>
			<link rel="icon" href="../resources/exist_icon_16x16.png" type="image/png"/>

			{ admin:panel-header() }

                {admin:info-header()}

Select a Page

                    {
                        let $link := session:encode-url(request:get-uri())
                        return

Home

System Status

Browse Collections

User Management

View Running Jobs

Examples Setup

Install Tools

Install Documentation

Backups

Query Profiling

Grammar cache

Shutdown

Logout

                    }

                        Logged in as: {xdb:get-current-user()}

                {
                    if($isLoggedIn)then
                    (
                        admin:panel()
                    )
                    else
                    (
                        admin:display-login-form()
                    )
                }

)


Fixed sample setup in web admin client.

Fixed sample setup in web admin client.

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

xquery version "1.0";
(: $Id$ :)
(:
    Module: examples setup
:)

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

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

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

Examples Setup

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

};

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

Loading from directory: {$dir}.

Actions:

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

    )
};

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

Actions:

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

    )
};

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

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

};

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

Uploaded: {$doc}

};

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

Created collection: {$col}

};

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

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

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

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

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

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

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

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

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

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

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

};

xquery version "1.0";
(: $Id$ :)
(:
    Module: examples setup
:)

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

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

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

Examples Setup

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

};

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

Loading from directory: {$dir}.

Actions:

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

    )
};

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

Actions:

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

    )
};

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

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

};

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

Uploaded: {$doc}

};

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

Created collection: {$col}

};

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

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

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

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

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

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

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

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

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

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

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

};


Updating the footer colophon

Updating the footer colophon

xquery version "1.0";
declare namespace exist = "http://exist.sourceforge.net/NS/exist";
declare namespace request="http://exist-db.org/xquery/request";

(:

Punch list:
(must have)

(probably need)
  * Add file manifest viewer (subform)

(might want)
  * Add trigger to see preview on save (may involve xq)
  * See if modals can be improved
  * Add keyboard command bindings

:)

declare option exist:serialize "method=xhtml media-type=text/xml";
declare option exist:serialize "indent=no";
declare option exist:serialize "process-xsl-pi=no";

let $attribute := request:set-attribute("betterform.filter.ignoreResponseBody", "true")

let $base_url := '/metadata/'
let $load_path := 'posted_data/'
let $param := request:get-parameter("fid", 0)

let $form_url := concat($base_url, $load_path, $param)

let $form :=

    <title>Shelley-Godwin Archive Metadata Editor</title>
    <link rel="stylesheet" type="text/css" href="../lib/bootstrap/css/bootstrap.min.css" />
    <link rel="stylesheet" type="text/css" href="../lib/FontAwesome/css/font-awesome.css" />
    <link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.8.2/css/jquery.dataTables.css" />
    <link rel="stylesheet" type="text/css" href="../lib/fancyBox/source/jquery.fancybox.css" />

    <xf:model id="teiHeader">
      <xf:instance id="itemMD" xmlns="http://www.tei-c.org/ns/1.0"
        src= "{$form_url}">
      </xf:instance>

      <xf:instance id="control-codes" xmlns="">
        <data>
          <output-filename>temp.xml</output-filename>
          <institution-id></institution-id>
        </data>
      </xf:instance>

      <xf:bind id="title"
        nodeset="/tei:TEI/tei:teiHeader/tei:fileDesc/tei:titleStmt/tei:title[@type='main']"
        required="true()"></xf:bind>
      <xf:bind id="date"
        nodeset="/tei:TEI/tei:teiHeader/tei:profileDesc/tei:creation/tei:date/@when"></xf:bind>
      <xf:bind id="desc-label" nodeset="//tei:msDesc/tei:msContents/tei:summary" required="true()"></xf:bind>

      <xf:bind id="call-number" nodeset="//tei:msDesc/tei:msIdentifier/tei:idno" required="true()"></xf:bind>

      <xf:bind id="xtra-foliation" nodeset="instance('control-codes')/boolean1" type="boolean"></xf:bind>
      <xf:bind id="foliation-modern"
        nodeset="//tei:msDesc/tei:physDesc/tei:objectDesc/tei:supportDesc/tei:foliation[@xml:id='modern']"></xf:bind>

      <xf:bind id="meditor"
        nodeset="/tei:TEI/tei:teiHeader/tei:fileDesc/tei:titleStmt/tei:respStmt[@xml:id='md_editor']/tei:name"
        required="true()"></xf:bind>
      <xf:bind id="metadata-source"
        nodeset="//tei:msDesc/tei:additional/tei:adminInfo/tei:recordHist/tei:p/tei:bibl"
        required="true()"></xf:bind>

      <xf:bind id="change-author" nodeset="//tei:revisionDesc/tei:change/@who" readonly="true()"></xf:bind>
      <xf:bind id="change" nodeset="//tei:revisionDesc/tei:change" readonly="true()"></xf:bind>

      <xf:submission id="save" method="put" replace="none">
        <xf:resource value="concat('/metadata/posted_data/', instance('control-codes')/output-filename)"></xf:resource>
      </xf:submission>

      <xf:message level="modal" ev:event="xforms-submit-done">Saved!</xf:message>

    </xf:model>

Metadata Editor

for the Shelley-Godwin Archive

          <xf:trigger>
            <xf:label> Basics</xf:label>
            <xf:toggle case="basics" ev:event="DOMActivate"></xf:toggle>
          </xf:trigger>
          <xf:trigger id="holdings">
            <xf:label> Holdings Info</xf:label>
            <xf:toggle case="holdings_info" ev:event="DOMActivate"></xf:toggle>
          </xf:trigger>
          <xf:trigger>
            <xf:label> Physical Description</xf:label>
            <xf:toggle case="physical_description" ev:event="DOMActivate"></xf:toggle>
          </xf:trigger>
          <xf:trigger>
            <xf:label> Hands</xf:label>
            <xf:toggle case="hand_info" ev:event="DOMActivate"></xf:toggle>
          </xf:trigger>
          <xf:trigger>
            <xf:label> Data Provenance</xf:label>
            <xf:toggle case="prov" ev:event="DOMActivate"></xf:toggle>
          </xf:trigger>
          <xf:trigger id="related-items">
            <xf:label> Related Items</xf:label>
            <xf:toggle case="surrogates" ev:event="DOMActivate"></xf:toggle>
          </xf:trigger>
          <xf:trigger>
            <xf:label> Changelog</xf:label>
            <xf:toggle case="admin_info" ev:event="DOMActivate"></xf:toggle>
          </xf:trigger>

        <xf:switch>
          <xf:case id="basics">

1 of 7

Basic Item Description

          <xf:group>

              <xf:input id="main-title" bind="title" incremental="true">
                <xf:label>Main title: </xf:label>
              </xf:input>

              <xf:input id="creation-date" appearance="minimal" bind="date">
                <xf:label>Date created: </xf:label>

              </xf:input>

              <xf:textarea id="item-label" bind="desc-label">
                <xf:label>Short description: </xf:label>
              </xf:textarea>

          </xf:group>

                <xf:trigger id="next-to-holdings">
                  <xf:label>Next →</xf:label>
                  <xf:toggle case="holdings_info" ev:event="DOMActivate"></xf:toggle>
                </xf:trigger>

        </xf:case>
          <xf:case id="holdings_info">

2 of 7

Holdings Information

          <xf:group ref="//tei:msDesc/tei:msIdentifier">

              <xf:select1 id="select-repo" ref="tei:repository" appearance="minimal">
                <xf:label>Host institution</xf:label>
                <xf:item>
                  <xf:label>British Library</xf:label>
                  <xf:value>bl</xf:value>
                </xf:item>
                <xf:item>
                  <xf:label>Harvard University, Houghton Library</xf:label>
                  <xf:value>mh</xf:value>
                </xf:item>
                <xf:item>
                  <xf:label>Huntington Library</xf:label>
                  <xf:value>hu</xf:value>
                </xf:item>
                <xf:item>
                  <xf:label>New York Public Library</xf:label>
                  <xf:value>pf</xf:value>
                </xf:item>
                <xf:item>
                  <xf:label>Oxford University, Bodleian Library</xf:label>
                  <xf:value>ox</xf:value>
                </xf:item>
                <xf:action ev:event="xforms-value-changed">
                  <xf:setvalue ref="instance('control-codes')/institution-id" value="instance('itemMD')//tei:repository"></xf:setvalue>
                </xf:action>
              </xf:select1>

              <xf:input id="lib-collection" ref="tei:collection" appearance="minimal">
                <xf:label>Name of collection: </xf:label>
              </xf:input>

              <xf:input id="lib-idno" bind="call-number" appearance="minimal">
                <xf:label>Call number/shelf mark for item: </xf:label>
                <xf:action ev:event="xforms-value-changed">
                  <xf:setvalue ref="instance('control-codes')/output-filename" value="concat(lower-case(translate(instance('itemMD')//tei:msDesc/tei:msIdentifier/tei:idno, ' .,', '_')), '.xml')"></xf:setvalue>
                </xf:action>
              </xf:input>

          </xf:group>

                  <xf:trigger id="prev-to-basics">
                    <xf:label>← Previous</xf:label>
                    <xf:toggle case="basics" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

                  <xf:trigger id="next-to-physDesc">
                    <xf:label>Next →</xf:label>
                    <xf:toggle case="physical_description" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

        </xf:case>
          <xf:case id="physical_description">

3 of 7

Physical Description Aspects of the form, support, and extent of a manuscript, as well as the styles of writing present

          <xf:group ref="//tei:msDesc/tei:physDesc/tei:objectDesc/tei:supportDesc">

              <xf:input id="physical-extent" ref="tei:extent" appearance="minimal">
              <xf:label>Extent: </xf:label>
            </xf:input>

              <xf:textarea id="physical-support" ref="tei:support/tei:p" appearance="minimal">
                <xf:label>Describe the material support of the item: </xf:label>
              </xf:textarea>

              <xf:textarea id="foliation-orig" ref="tei:foliation[@xml:id='original']/tei:p">
                <xf:label>Describe any (original) foliation scheme present: </xf:label>
              </xf:textarea>

              <xf:input bind="xtra-foliation">
              <xf:label>Record another foliation scheme?</xf:label>
            </xf:input>
              <xf:textarea id="foliation-mod" bind="foliation-modern">
              <xf:label>Describe any additional foliation schemes present: </xf:label>
            </xf:textarea>

              <xf:textarea id="physical-condition" ref="tei:condition/tei:p">
                <xf:label>Describe the condition of the item: </xf:label>
              </xf:textarea>

          </xf:group>

                  <xf:trigger id="prev-to-holdings">
                    <xf:label>← Previous</xf:label>
                    <xf:toggle case="holdings_info" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

                  <xf:trigger id="next-to-hands">
                    <xf:label>Next →</xf:label>
                    <xf:toggle case="hand_info" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

        </xf:case>
          <xf:case id="hand_info">

4 of 7

Manuscript Hands

          <xf:group>

              <xf:textarea id="manu-hands" ref="//tei:msDesc/tei:physDesc/tei:handDesc/tei:p">
                <xf:label>Describe hands found in the item: </xf:label>
              </xf:textarea>

          </xf:group>

                  <xf:trigger id="prev-to-physDesc">
                    <xf:label>← Previous</xf:label>
                    <xf:toggle case="physical_description" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

                  <xf:trigger id="next-to-prov">
                    <xf:label>Next →</xf:label>
                    <xf:toggle case="prov" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

        </xf:case>
          <xf:case id="prov">

5 of 7

Data Provenance

          <xf:group ref="//tei:msDesc/tei:additional/tei:adminInfo/tei:recordHist">

              <xf:input id="metadata-creator" bind="meditor">
                <xf:label>Metadata created/edited for SGA by: </xf:label>
              </xf:input>

              <xf:textarea id="source" bind="metadata-source">
                <xf:label>Source used: </xf:label>
              </xf:textarea>

          </xf:group>

                  <xf:trigger id="prev-to-hands">
                    <xf:label>← Previous</xf:label>
                    <xf:toggle case="hand_info" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

                  <xf:trigger id="next-to-surrogates">
                    <xf:label>Next →</xf:label>
                    <xf:toggle case="surrogates" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

        </xf:case>
          <xf:case id="surrogates">

6 of 7

Related Items Most of the items in the Shelley-Godwin Archive have been published in facsimile editions.
              This section records information about those surrogate items.

          <xf:group ref="//tei:msDesc/tei:additional/tei:listBibl">

              <xf:textarea id="surrogate1" ref="tei:bibl">
                <xf:label>Citation for related/additional surrogate for this item: </xf:label>
              </xf:textarea>

          </xf:group>

                <xf:trigger id="next-to-manifest">
                  <xf:label> Link page images to this Item</xf:label>
                <xf:toggle case="file_manifest" ev:event="DOMActivate"></xf:toggle>
              </xf:trigger>

                  <xf:trigger id="prev-to-prov">
                    <xf:label>← Previous</xf:label>
                    <xf:toggle case="prov" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

                  <xf:trigger id="surrogate-to-finish">
                    <xf:label>Finish</xf:label>
                    <xf:toggle case="admin_info" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

        </xf:case>
          <xf:case id="file_manifest">

Link Page Images Label image files with descriptive information indicating their relationship to the original item

<xf:output id="institution-code" ref="instance('control-codes')/institution-id"></xf:output>

Select an item:

Loading

Retrieving page images for this item. Please wait.

                                filename
                                link
                                label

                        <button id="jsSave" class="btn btn-primary">Save</button>

                  <xf:trigger id="prev-to-manifest">
                    <xf:label>← Back</xf:label>
                    <xf:toggle case="file_manifest" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

                  <xf:trigger id="img-to-finish">
                    <xf:label>Finish</xf:label>
                    <xf:toggle case="admin_info" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

          </xf:case>
          <xf:case id="admin_info">

7 of 7

Edit Changelog Help the Shelley-Godwin Archive keep track of everyone's contributions

                Timestamp
                Author
                Change(s)

          <xf:repeat id="change-repeat" nodeset="instance('itemMD')//tei:revisionDesc/tei:change">

                    <xf:output ref="./@when"></xf:output>

                    <xf:input ref="./@who">
                        <xf:action ev:event="DOMFocusIn">
                            <xf:load resource="javascript:makeEditable()"></xf:load>
                        </xf:action>
                    </xf:input>

                    <xf:input ref="."></xf:input>

            </xf:repeat>

          <xf:trigger>
                <xf:label>Add an entry</xf:label>
                    <xf:action ev:event="DOMActivate">
                    <xf:insert nodeset="//tei:revisionDesc/tei:change" at="last()" position="after"/>
                    <xf:setvalue ref="instance('control-codes')/output-filename" value="concat(lower-case(translate(instance('itemMD')//tei:msDesc/tei:msIdentifier/tei:idno, ' .,', '_')), '.xml')"></xf:setvalue>
                    <xf:setvalue ref="//tei:revisionDesc/tei:change[last()]/@when" value="now()"></xf:setvalue>
                    <xf:setvalue ref="//tei:revisionDesc/tei:change[last()]/@who" value="'Click to edit'"></xf:setvalue>
                    <xf:setvalue ref="//tei:revisionDesc/tei:change[last()]" value="'Click to edit'"></xf:setvalue>
                    </xf:action>
          </xf:trigger>

                  <xf:trigger id="prev-from-submit">
                    <xf:label>← Go back</xf:label>
                    <xf:toggle case="surrogates" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

                  <xf:submit id="finish" submission="save">
                    <xf:label>Save</xf:label>
                  </xf:submit>

        </xf:case>
        </xf:switch>

            Powered by XSLTForms, Bootstrap, Font Awesome, fancyBox, and poetry.

let $xslt-pi := processing-instruction xml-stylesheet {'type="text/xsl" href="http://50.19.209.106/fs/xforms/xsltforms/xsltforms.xsl" '}
let $css-pi := processing-instruction css-conversion {'no'}

return ($xslt-pi,$css-pi,$form)

xquery version "1.0";
declare namespace exist = "http://exist.sourceforge.net/NS/exist";
declare namespace request="http://exist-db.org/xquery/request";

(:

Punch list:
(must have)

(probably need)
  * Add file manifest viewer (subform)

(might want)
  * Add trigger to see preview on save (may involve xq)
  * See if modals can be improved
  * Add keyboard command bindings

:)

declare option exist:serialize "method=xhtml media-type=text/xml";
declare option exist:serialize "indent=no";
declare option exist:serialize "process-xsl-pi=no";

let $attribute := request:set-attribute("betterform.filter.ignoreResponseBody", "true")

let $base_url := '/metadata/'
let $load_path := 'posted_data/'
let $param := request:get-parameter("fid", 0)

let $form_url := concat($base_url, $load_path, $param)

let $form :=

    <title>Shelley-Godwin Archive Metadata Editor</title>
    <link rel="stylesheet" type="text/css" href="../lib/bootstrap/css/bootstrap.min.css" />
    <link rel="stylesheet" type="text/css" href="../lib/FontAwesome/css/font-awesome.css" />
    <link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.8.2/css/jquery.dataTables.css" />
    <link rel="stylesheet" type="text/css" href="../lib/fancyBox/source/jquery.fancybox.css" />

    <xf:model id="teiHeader">
      <xf:instance id="itemMD" xmlns="http://www.tei-c.org/ns/1.0"
        src= "{$form_url}">
      </xf:instance>

      <xf:instance id="control-codes" xmlns="">
        <data>
          <output-filename>temp.xml</output-filename>
          <institution-id></institution-id>
        </data>
      </xf:instance>

      <xf:bind id="title"
        nodeset="/tei:TEI/tei:teiHeader/tei:fileDesc/tei:titleStmt/tei:title[@type='main']"
        required="true()"></xf:bind>
      <xf:bind id="date"
        nodeset="/tei:TEI/tei:teiHeader/tei:profileDesc/tei:creation/tei:date/@when"></xf:bind>
      <xf:bind id="desc-label" nodeset="//tei:msDesc/tei:msContents/tei:summary" required="true()"></xf:bind>

      <xf:bind id="call-number" nodeset="//tei:msDesc/tei:msIdentifier/tei:idno" required="true()"></xf:bind>

      <xf:bind id="xtra-foliation" nodeset="instance('control-codes')/boolean1" type="boolean"></xf:bind>
      <xf:bind id="foliation-modern"
        nodeset="//tei:msDesc/tei:physDesc/tei:objectDesc/tei:supportDesc/tei:foliation[@xml:id='modern']"></xf:bind>

      <xf:bind id="meditor"
        nodeset="/tei:TEI/tei:teiHeader/tei:fileDesc/tei:titleStmt/tei:respStmt[@xml:id='md_editor']/tei:name"
        required="true()"></xf:bind>
      <xf:bind id="metadata-source"
        nodeset="//tei:msDesc/tei:additional/tei:adminInfo/tei:recordHist/tei:p/tei:bibl"
        required="true()"></xf:bind>

      <xf:bind id="change-author" nodeset="//tei:revisionDesc/tei:change/@who" readonly="true()"></xf:bind>
      <xf:bind id="change" nodeset="//tei:revisionDesc/tei:change" readonly="true()"></xf:bind>

      <xf:submission id="save" method="put" replace="none">
        <xf:resource value="concat('/metadata/posted_data/', instance('control-codes')/output-filename)"></xf:resource>
      </xf:submission>

      <xf:message level="modal" ev:event="xforms-submit-done">Saved!</xf:message>

    </xf:model>

Metadata Editor

for the Shelley-Godwin Archive

          <xf:trigger>
            <xf:label> Basics</xf:label>
            <xf:toggle case="basics" ev:event="DOMActivate"></xf:toggle>
          </xf:trigger>
          <xf:trigger id="holdings">
            <xf:label> Holdings Info</xf:label>
            <xf:toggle case="holdings_info" ev:event="DOMActivate"></xf:toggle>
          </xf:trigger>
          <xf:trigger>
            <xf:label> Physical Description</xf:label>
            <xf:toggle case="physical_description" ev:event="DOMActivate"></xf:toggle>
          </xf:trigger>
          <xf:trigger>
            <xf:label> Hands</xf:label>
            <xf:toggle case="hand_info" ev:event="DOMActivate"></xf:toggle>
          </xf:trigger>
          <xf:trigger>
            <xf:label> Data Provenance</xf:label>
            <xf:toggle case="prov" ev:event="DOMActivate"></xf:toggle>
          </xf:trigger>
          <xf:trigger id="related-items">
            <xf:label> Related Items</xf:label>
            <xf:toggle case="surrogates" ev:event="DOMActivate"></xf:toggle>
          </xf:trigger>
          <xf:trigger>
            <xf:label> Changelog</xf:label>
            <xf:toggle case="admin_info" ev:event="DOMActivate"></xf:toggle>
          </xf:trigger>

        <xf:switch>
          <xf:case id="basics">

1 of 7

Basic Item Description

          <xf:group>

              <xf:input id="main-title" bind="title" incremental="true">
                <xf:label>Main title: </xf:label>
              </xf:input>

              <xf:input id="creation-date" appearance="minimal" bind="date">
                <xf:label>Date created: </xf:label>

              </xf:input>

              <xf:textarea id="item-label" bind="desc-label">
                <xf:label>Short description: </xf:label>
              </xf:textarea>

          </xf:group>

                <xf:trigger id="next-to-holdings">
                  <xf:label>Next →</xf:label>
                  <xf:toggle case="holdings_info" ev:event="DOMActivate"></xf:toggle>
                </xf:trigger>

        </xf:case>
          <xf:case id="holdings_info">

2 of 7

Holdings Information

          <xf:group ref="//tei:msDesc/tei:msIdentifier">

              <xf:select1 id="select-repo" ref="tei:repository" appearance="minimal">
                <xf:label>Host institution</xf:label>
                <xf:item>
                  <xf:label>British Library</xf:label>
                  <xf:value>bl</xf:value>
                </xf:item>
                <xf:item>
                  <xf:label>Harvard University, Houghton Library</xf:label>
                  <xf:value>mh</xf:value>
                </xf:item>
                <xf:item>
                  <xf:label>Huntington Library</xf:label>
                  <xf:value>hu</xf:value>
                </xf:item>
                <xf:item>
                  <xf:label>New York Public Library</xf:label>
                  <xf:value>pf</xf:value>
                </xf:item>
                <xf:item>
                  <xf:label>Oxford University, Bodleian Library</xf:label>
                  <xf:value>ox</xf:value>
                </xf:item>
                <xf:action ev:event="xforms-value-changed">
                  <xf:setvalue ref="instance('control-codes')/institution-id" value="instance('itemMD')//tei:repository"></xf:setvalue>
                </xf:action>
              </xf:select1>

              <xf:input id="lib-collection" ref="tei:collection" appearance="minimal">
                <xf:label>Name of collection: </xf:label>
              </xf:input>

              <xf:input id="lib-idno" bind="call-number" appearance="minimal">
                <xf:label>Call number/shelf mark for item: </xf:label>
                <xf:action ev:event="xforms-value-changed">
                  <xf:setvalue ref="instance('control-codes')/output-filename" value="concat(lower-case(translate(instance('itemMD')//tei:msDesc/tei:msIdentifier/tei:idno, ' .,', '_')), '.xml')"></xf:setvalue>
                </xf:action>
              </xf:input>

          </xf:group>

                  <xf:trigger id="prev-to-basics">
                    <xf:label>← Previous</xf:label>
                    <xf:toggle case="basics" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

                  <xf:trigger id="next-to-physDesc">
                    <xf:label>Next →</xf:label>
                    <xf:toggle case="physical_description" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

        </xf:case>
          <xf:case id="physical_description">

3 of 7

Physical Description Aspects of the form, support, and extent of a manuscript, as well as the styles of writing present

          <xf:group ref="//tei:msDesc/tei:physDesc/tei:objectDesc/tei:supportDesc">

              <xf:input id="physical-extent" ref="tei:extent" appearance="minimal">
              <xf:label>Extent: </xf:label>
            </xf:input>

              <xf:textarea id="physical-support" ref="tei:support/tei:p" appearance="minimal">
                <xf:label>Describe the material support of the item: </xf:label>
              </xf:textarea>

              <xf:textarea id="foliation-orig" ref="tei:foliation[@xml:id='original']/tei:p">
                <xf:label>Describe any (original) foliation scheme present: </xf:label>
              </xf:textarea>

              <xf:input bind="xtra-foliation">
              <xf:label>Record another foliation scheme?</xf:label>
            </xf:input>
              <xf:textarea id="foliation-mod" bind="foliation-modern">
              <xf:label>Describe any additional foliation schemes present: </xf:label>
            </xf:textarea>

              <xf:textarea id="physical-condition" ref="tei:condition/tei:p">
                <xf:label>Describe the condition of the item: </xf:label>
              </xf:textarea>

          </xf:group>

                  <xf:trigger id="prev-to-holdings">
                    <xf:label>← Previous</xf:label>
                    <xf:toggle case="holdings_info" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

                  <xf:trigger id="next-to-hands">
                    <xf:label>Next →</xf:label>
                    <xf:toggle case="hand_info" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

        </xf:case>
          <xf:case id="hand_info">

4 of 7

Manuscript Hands

          <xf:group>

              <xf:textarea id="manu-hands" ref="//tei:msDesc/tei:physDesc/tei:handDesc/tei:p">
                <xf:label>Describe hands found in the item: </xf:label>
              </xf:textarea>

          </xf:group>

                  <xf:trigger id="prev-to-physDesc">
                    <xf:label>← Previous</xf:label>
                    <xf:toggle case="physical_description" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

                  <xf:trigger id="next-to-prov">
                    <xf:label>Next →</xf:label>
                    <xf:toggle case="prov" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

        </xf:case>
          <xf:case id="prov">

5 of 7

Data Provenance

          <xf:group ref="//tei:msDesc/tei:additional/tei:adminInfo/tei:recordHist">

              <xf:input id="metadata-creator" bind="meditor">
                <xf:label>Metadata created/edited for SGA by: </xf:label>
              </xf:input>

              <xf:textarea id="source" bind="metadata-source">
                <xf:label>Source used: </xf:label>
              </xf:textarea>

          </xf:group>

                  <xf:trigger id="prev-to-hands">
                    <xf:label>← Previous</xf:label>
                    <xf:toggle case="hand_info" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

                  <xf:trigger id="next-to-surrogates">
                    <xf:label>Next →</xf:label>
                    <xf:toggle case="surrogates" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

        </xf:case>
          <xf:case id="surrogates">

6 of 7

Related Items Most of the items in the Shelley-Godwin Archive have been published in facsimile editions.
              This section records information about those surrogate items.

          <xf:group ref="//tei:msDesc/tei:additional/tei:listBibl">

              <xf:textarea id="surrogate1" ref="tei:bibl">
                <xf:label>Citation for related/additional surrogate for this item: </xf:label>
              </xf:textarea>

          </xf:group>

                <xf:trigger id="next-to-manifest">
                  <xf:label> Link page images to this Item</xf:label>
                <xf:toggle case="file_manifest" ev:event="DOMActivate"></xf:toggle>
              </xf:trigger>

                  <xf:trigger id="prev-to-prov">
                    <xf:label>← Previous</xf:label>
                    <xf:toggle case="prov" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

                  <xf:trigger id="surrogate-to-finish">
                    <xf:label>Finish</xf:label>
                    <xf:toggle case="admin_info" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

        </xf:case>
          <xf:case id="file_manifest">

Link Page Images Label image files with descriptive information indicating their relationship to the original item

<xf:output id="institution-code" ref="instance('control-codes')/institution-id"></xf:output>

Select an item:

Loading

Retrieving page images for this item. Please wait.

                                filename
                                link
                                label

                        <button id="jsSave" class="btn btn-primary">Save</button>

                  <xf:trigger id="prev-to-manifest">
                    <xf:label>← Back</xf:label>
                    <xf:toggle case="file_manifest" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

                  <xf:trigger id="img-to-finish">
                    <xf:label>Finish</xf:label>
                    <xf:toggle case="admin_info" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

          </xf:case>
          <xf:case id="admin_info">

7 of 7

Edit Changelog Help the Shelley-Godwin Archive keep track of everyone's contributions

                Timestamp
                Author
                Change(s)

          <xf:repeat id="change-repeat" nodeset="instance('itemMD')//tei:revisionDesc/tei:change">

                    <xf:output ref="./@when"></xf:output>

                    <xf:input ref="./@who">
                        <xf:action ev:event="DOMFocusIn">
                            <xf:load resource="javascript:makeEditable()"></xf:load>
                        </xf:action>
                    </xf:input>

                    <xf:input ref="."></xf:input>

            </xf:repeat>

          <xf:trigger>
                <xf:label>Add an entry</xf:label>
                    <xf:action ev:event="DOMActivate">
                    <xf:insert nodeset="//tei:revisionDesc/tei:change" at="last()" position="after"/>
                    <xf:setvalue ref="instance('control-codes')/output-filename" value="concat(lower-case(translate(instance('itemMD')//tei:msDesc/tei:msIdentifier/tei:idno, ' .,', '_')), '.xml')"></xf:setvalue>
                    <xf:setvalue ref="//tei:revisionDesc/tei:change[last()]/@when" value="now()"></xf:setvalue>
                    <xf:setvalue ref="//tei:revisionDesc/tei:change[last()]/@who" value="'Click to edit'"></xf:setvalue>
                    <xf:setvalue ref="//tei:revisionDesc/tei:change[last()]" value="'Click to edit'"></xf:setvalue>
                    </xf:action>
          </xf:trigger>

                  <xf:trigger id="prev-from-submit">
                    <xf:label>← Go back</xf:label>
                    <xf:toggle case="surrogates" ev:event="DOMActivate"></xf:toggle>
                  </xf:trigger>

                  <xf:submit id="finish" submission="save">
                    <xf:label>Save</xf:label>
                  </xf:submit>

        </xf:case>
        </xf:switch>

            Powered by Bootstrap, Font Awesome, and poetry.

let $xslt-pi := processing-instruction xml-stylesheet {'type="text/xsl" href="http://50.19.209.106/fs/xforms/xsltforms/xsltforms.xsl" '}
let $css-pi := processing-instruction css-conversion {'no'}

return ($xslt-pi,$css-pi,$form)


added back the uuid function (was removed by accident in the preceding commit to this module)

xquery version "3.0";

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

(:~
 : This module provides several functions for generating (pseudo-)random
 : numbers and strings.
 :
 : @author Matthias Brantner, Sorin Nasoi
 : @project XDM/atomic
 :
 :)
module namespace r = "http://www.zorba-xquery.com/modules/random";

declare namespace ann = "http://www.zorba-xquery.com/annotations";
declare namespace zerr = "http://www.zorba-xquery.com/errors";

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

(:~
 : This function generates an arbitrary number of pseudo-random numbers.
 : The sequence is repeatable by calling the function with the same
 : seed.
 :
 :
The function is based on posix function <tt>srand()</tt> and
 : <tt>rand()</tt>. Specifically, it invokes <tt>srand($seed)</tt>
 : and then returns the values returned by invoking <tt>rand()</tt>
 : <tt>$num</tt>-times.

 :
 :
Sequences returned by this function are not thread-safe (i.e.
 : if multiple XQuery programs invoking this function are executed
 : concurrently in several threads). This is because the function is
 : based on <tt>srand()</tt> and <tt>rand()</tt>.

 :
 : @param $seed the initial seed value for the sequence
 : @param $num the length of the sequence returned
 : @return <tt>$num</tt> pseudo-random integers, or the empty
 :  sequence if <tt>$num</tt> is negative.
 :
 : @error zerr:ZQXD0004 if the given seed is negative or great
 :  than the max value of <tt>unsigned int</tt> on the given platform.
 :)
declare function r:seeded-random(
  $seed as xs:integer,
  $num as xs:integer
) as xs:integer* external;

(:~
 : This function generates an arbitrary number of random numbers.
 : The function is nondeterministic because the sequence is
 : not repeatable.
 :
 :
However, the function is based on posix function <tt>srand()</tt> and
 : <tt>rand()</tt>. Specifically, it invokes <tt>srand()</tt>
 : with the current wallclock time in milliseconds (restricted to
 : the limit of unsigned int on the given platform) and then returns
 : the values returned by invoking <tt>rand()</tt> <tt>$num</tt>-times.

 :
 : @param $num the length of the sequence returned
 : @return <tt>$num</tt> random integers, or the empty
 :  sequence if <tt>$num</tt> is negative.
 :)
declare %ann:nondeterministic function r:random(
  $num as xs:integer
) as xs:integer* external;

(:~
 : This function generates one random number.
 : The function is nondeterministic.
 :
 :
The function is based on <tt>r:random#1</tt>. Specifically, it
 : returns the value of invoking <tt>r:random(1)</tt>.

 :
 : @return a random integer
 :)
declare %ann:nondeterministic function r:random() as xs:integer
{
  r:random(1)
};

(:~
 : This function generates an arbitrary number of pseudo-random numbers
 : within a given range. The sequence is repeatable by calling the
 : function with the same seed and boundaries.
 :
 :
The function is based on the function <tt>r:seeded-random#2</tt>.
 : Specifically, it's result is repeatable if called with the
 : same arguments.

 :
 : @param $seed the initial seed value for the sequence
 : @param $lower the lower bound for every value within the sequence
 : @param $upper the upper bound for every value within the sequence
 : @param $num the length of the sequence returned
 : @return <tt>$num</tt> pseudo-random integers within (and including) the
 :    range specified by <tt>$lower</tt> and <tt>$upper</tt>. It returns
 :     <tt>$num</tt>-times <tt>$lower</tt> if <tt>$lower</tt> is
 :     equal to <tt>$upper</tt> and the empty sequence if <tt>$num</tt>
 :     is negative.
 :
 : @error zerr:ZQXD0004 if the given seed is negative or great
 :  than the max value of <tt>unsigned int</tt> on the given platform.
 : @error r:invalid-arg if <tt>$lower</tt> is greater than <tt>$upper</tt>
 :)
declare function r:seeded-random-between(
  $seed as xs:integer,
  $lower as xs:integer,
  $upper as xs:integer,
  $num as xs:integer
) as xs:integer*
{
  if ( $lower eq $upper ) then
    $lower
  else
    if ( $lower > $upper ) then
      fn:error(
        fn:QName("http://www.zorba-xquery.com/modules/random", "invalid-arg"),
        "$lower must be smaller or equal than $upper",
        ($lower, $upper)
      )
    else
      for $i in r:seeded-random( $seed, $num )
      return xs:integer($i mod ($upper - $lower) + $lower)
};

(:~
 : This function generates an arbitrary number of random numbers
 : within a given range. The function is nondeterministic because
 : the sequence is not repeatable.
 :
 : @param $lower the lower bound for every value within the sequence
 : @param $upper the upper bound for every value within the sequence
 : @param $num the length of the sequence returned
 : @return <tt>$num</tt> pseudo-random integers within (and including) the
 :    range specified by <tt>$lower</tt> and <tt>$upper</tt>. It returns
 :     <tt>$num</tt>-times <tt>$lower</tt> if <tt>$lower</tt> is
 :     equal to <tt>$upper</tt> and the empty sequence if <tt>$num</tt>
 :     is negative.
 :
 : @error r:invalid-arg if <tt>$lower</tt> is greater than <tt>$upper</tt>
 :)
declare %ann:nondeterministic function r:random-between(
  $lower as xs:integer,
  $upper as xs:integer,
  $num as xs:integer) as xs:integer*
{
  if ( $lower eq $upper ) then
    $lower
  else
    if ( $lower > $upper ) then
      fn:error(
        fn:QName("http://www.zorba-xquery.com/modules/random", "invalid-arg"),
        "$lower must be smaller or equal than $upper",
        ($lower, $upper)
      )
    else
      for $i in r:random( $num )
      return
        if ( ( $upper - $lower ) lt 10000 ) then
          xs:integer( fn:round( xs:double( $i mod 10000 ) div 10000 * ( $upper - $lower) ) + $lower )
        else
          xs:integer( fn:round( xs:double( $i ) mod ( $upper - $lower ) ) + $lower )
};

(:~
 : This function generates one random number within a given range.
 : The function is nondeterministic.
 :
 :
The function is based on <tt>r:random-between#3</tt>.
 : Specifically, it returns the value of invoking
 : <tt>r:random-betwen($lower, $upper, 1)</tt>.

 :
 : @param $lower the lower bound for the random number
 : @param $upper the upper bound for the random number
 : @return a random integer within the given range
 :)
declare %ann:nondeterministic function r:random-between(
  $lower as xs:integer,
  $upper as xs:integer
) as xs:integer
{
  r:random-between($lower, $upper, 1)
};

(:~
 : This function returns a uuid. Note, that the function is not stable,
 : that is, it returns a different UUID everytime the function is invoked.
 :
 : @return the generated UUID as xs:string
:)
declare %ann:nondeterministic function r:uuid() as xs:string external;