*** empty log message ***

*** empty log message ***

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

xquery version "1.0";

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

(: Namespace for the local functions in this script :)
declare namespace f="http://exist-db.org/xquery/local-functions";

(:
    Display hits for the current page. The number of hits to print per page
    is read from parameter "howmany". Parameter "start" identifies the
    current offset in the result set.
:)
declare function f:display($hits as item()*, $count as xs:int)
as element()+
{
    if (empty($hits)) then

Nothing found! Back to query form.

    else
        let $howmany := request:request-parameter("howmany", "10") cast as xs:int,
            $start := request:request-parameter("start", "1") cast as xs:int,
            $end := if ($start + $howmany le $count) then $start + $howmany - 1 else $count
        return (

                        <New Query>

                { f:navbar($start, $end, $howmany, $count) }
                {
                    for $p in $start to $end
                    let $current := item-at($hits, $p),
                        $style := if($p mod 2 eq 0) then "high" else "low"
                    return

                            {$p}

                                {
                                    if ($current instance of element()) then
                                        <xml-source>{$current}</xml-source>
                                    else
                                        string($current)
                                }

                }
                { f:navbar($start, $end, $howmany, $count) }

                        <New Query>

        )
};

(: Display the navigation bar :)
declare function f:navbar($start as xs:int, $end as xs:int,
$hitsPerPage as xs:int, $count as xs:int) as element()
{
    let $uri := request:request-uri()
    return

                {
                    (: Link to previous page :)
                    if ($start gt 1) then
                        <<
                    else ()
                }

                {
                    (: Create page shortcuts :)
                    let $sections := $count idiv $hitsPerPage - 1,
                        $currentSection := $start idiv $hitsPerPage,
                        $lastSection :=
                            if ($sections lt 0) then 0 else
                                (: show 10 max unless current page > 10 :)
                                if ($sections gt 9) then
                                    if ($currentSection gt 8) then $currentSection + 1
                                    else 9
                                else $sections
                    for $i in 0 to $lastSection
                    let $s := xs:int($i * $hitsPerPage + 1)
                    return
                        if($i ne $currentSection) then

                                [{$i + 1}]

                        else
                            (: current page doesn't get a link :)
                            [{$i + 1}]
                }

                {
                    (: Link to next page :)
                    if ($end lt $count) then

                            >>

                    else ()
                }

};

(: Auxiliary function called in add-to-history()
   to avoid having twice the same query in history
:)
declare function f:string-list-union(
   $list as xs:string*,
   $s as xs:string ) as xs:string*
{
  let $contains :=
    for $ss in $list
      return
        if ( $ss = $s ) then true
        else ""

  return
    if ( $contains ) then
      $list
    else
      ( $list, $s )
};

(:  Add the last query to the query-history. The history is
    stored in the session as an XQuery sequence.
:)
declare function f:add-to-history($query as xs:string) as empty()
{
    let $history := request:get-session-attribute("history")
    return
        request:set-session-attribute( "history",
                                       f:string-list-union($history, $query) )
};

declare function f:handleException() as element()+
{
	,

Defined server limits exceeded!
,
	(
		if($util:exception eq
			"org.exist.xquery.TerminatedException$TimeoutException") then

The execution time of your query exceeded the predefined limits.
			It has been forced to terminate.

		else

The query exceeded the predefined size limits for
			temporary document fragments and has been forced to
			terminate.

	),

Limits can be configured! Please have a look at the
	"watchdog" section in the configuration file (conf.xml).

};

declare function f:eval($query as xs:string) as element()+
{
	let $startTime := current-time(),
		$collection := request:request-parameter("collection", ())
	return
		util:catch("org.exist.xquery.TerminatedException",
            util:catch("org.exist.xquery.XPathException",
                let	$result := util:eval($query, $collection),
                    $count := count($result),
                    $queryTime := current-time() - $startTime
                return (

Found {$count} hits in
                    {seconds-from-duration($queryTime)} seconds.
                    {if($count gt 100) then "Max. 100 will be shown." else ()}

,
                    request:set-session-attribute(
                        "results",
                        subsequence($result, 1, 100)
                    ),
                    f:add-to-history($query),
                    f:display($result, $count)
                ),

Error found: {$util:exception-message}.

            ),
			f:handleException()
		)
};

(:  The main function. If a query has been passed in parameter
    "query", execute the query and store the results into the
    session. If "query" is empty, try to retrieve the previous
    result set from the session.
:)
declare function f:main() as element()+
{
    let $query := request:request-parameter("query", ()),
        $previous := request:get-session-attribute("results")
    return
        if ($query) then
           f:eval($query)
        else if ($previous) then
            f:display($previous, count($previous))
        else

Please specify a query! Back to query
            form.

};

<document xmlns:xi="http://www.w3.org/2001/XInclude">

        <logo src="logo.jpg"/>
        <title>Open Source XML Database</title>
	    <author email="wolfgang@exist-db.org">Wolfgang M. Meier</author>

xquery version "1.0";

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

(: Namespace for the local functions in this script :)
declare namespace f="http://exist-db.org/xquery/local-functions";

(:
    Display hits for the current page. The number of hits to print per page
    is read from parameter "howmany". Parameter "start" identifies the
    current offset in the result set.
:)
declare function f:display($hits as item()*, $count as xs:int)
as element()+
{
    if (empty($hits)) then

Nothing found! Back to query form.

    else
        let $howmany := request:request-parameter("howmany", "10") cast as xs:int,
            $start := request:request-parameter("start", "1") cast as xs:int,
            $end := if ($start + $howmany le $count) then $start + $howmany - 1 else $count
        return (

                        <New Query>

                { f:navbar($start, $end, $howmany, $count) }
                {
                    for $p in $start to $end
                    let $current := item-at($hits, $p),
                        $style := if($p mod 2 eq 0) then "high" else "low"
                    return

                            {$p}

                                <xml-source>{$current}</xml-source>

                }
                { f:navbar($start, $end, $howmany, $count) }

                        <New Query>

        )
};

(: Display the navigation bar :)
declare function f:navbar($start as xs:int, $end as xs:int,
$hitsPerPage as xs:int, $count as xs:int) as element()
{
    let $uri := request:request-uri()
    return

                {
                    (: Link to previous page :)
                    if ($start gt 1) then
                        <<
                    else ()
                }

                {
                    (: Create page shortcuts :)
                    let $sections := $count idiv $hitsPerPage - 1,
                        $currentSection := $start idiv $hitsPerPage,
                        $lastSection :=
                            if ($sections lt 0) then 0 else
                                (: show 10 max unless current page > 10 :)
                                if ($sections gt 9) then
                                    if ($currentSection gt 8) then $currentSection + 1
                                    else 9
                                else $sections
                    for $i in 0 to $lastSection
                    let $s := xs:int($i * $hitsPerPage + 1)
                    return
                        if($i ne $currentSection) then

                                [{$i + 1}]

                        else
                            (: current page doesn't get a link :)
                            [{$i + 1}]
                }

                {
                    (: Link to next page :)
                    if ($end lt $count) then

                            >>

                    else ()
                }

};

(: Auxiliary function called in add-to-history()
   to avoid having twice the same query in history
:)
declare function f:string-list-union(
   $list as xs:string*,
   $s as xs:string ) as xs:string*
{
  let $contains :=
    for $ss in $list
      return
        if ( $ss = $s ) then true
        else ""

  return
    if ( $contains ) then
      $list
    else
      ( $list, $s )
};

(:  Add the last query to the query-history. The history is
    stored in the session as an XQuery sequence.
:)
declare function f:add-to-history($query as xs:string) as empty()
{
    let $history := request:get-session-attribute("history")
    return
        request:set-session-attribute( "history",
                                       f:string-list-union($history, $query) )
};

declare function f:handleException() as element()+
{
	,

Defined server limits exceeded!
,
	(
		if($util:exception eq
			"org.exist.xquery.TerminatedException$TimeoutException") then

The execution time of your query exceeded the predefined limits.
			It has been forced to terminate.

		else

The query exceeded the predefined size limits for
			temporary document fragments and has been forced to
			terminate.

	),

Limits can be configured! Please have a look at the
	"watchdog" section in the configuration file (conf.xml).

};

declare function f:eval($query as xs:string) as element()+
{
	let $startTime := current-time(),
		$collection := request:request-parameter("collection", ())
	return
		util:catch("org.exist.xquery.TerminatedException",
            util:catch("org.exist.xquery.XPathException",
                let	$result := util:eval($query, $collection),
                    $count := count($result),
                    $queryTime := current-time() - $startTime
                return (

Found {$count} hits in
                    {seconds-from-duration($queryTime)} seconds.
                    {if($count gt 100) then "Max. 100 will be shown." else ()}

,
                    request:set-session-attribute(
                        "results",
                        subsequence($result, 1, 100)
                    ),
                    f:add-to-history($query),
                    f:display($result, $count)
                ),

Error found: {$util:exception-message}.

            ),
			f:handleException()
		)
};

(:  The main function. If a query has been passed in parameter
    "query", execute the query and store the results into the
    session. If "query" is empty, try to retrieve the previous
    result set from the session.
:)
declare function f:main() as element()+
{
    let $query := request:request-parameter("query", ()),
        $previous := request:get-session-attribute("results")
    return
        if ($query) then
           f:eval($query)
        else if ($previous) then
            f:display($previous, count($previous))
        else

Please specify a query! Back to query
            form.

};

<document xmlns:xi="http://www.w3.org/2001/XInclude">

        <logo src="logo.jpg"/>
        <title>Open Source XML Database</title>
	    <author email="wolfgang@exist-db.org">Wolfgang M. Meier</author>


[bugfix] Update permission 'u' was changed to 'x'

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

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 namespace file="http://exist-db.org/xquery/file";

declare namespace xproc="http://xproc.net/xproc";

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

Install Examples

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

        }

};

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")
        ),
    $webapp := if (doc-available(concat("file:///", $home, "/webapp/index.xml"))) then
        (
            concat($home, $pathSep, "webapp")
        )
        else if(ends-with($home, "WEB-INF")) then
        (
            substring-before($home, "WEB-INF")
        )
        else
        (
            concat($home, $pathSep, "webapp")
        )
        ,
    $betterform-home := if (ends-with($home, "WEB-INF")) then
        (
            concat( substring-before($home, "WEB-INF"), "/betterform/samples")
        )
        else
        (
            concat($home, "/extensions/betterform/main")
        ),

    $betterform-xrx := concat($betterform-home, "/xrx/timetracker/"),
    $betterform-xforms := concat($betterform-home, "/xforms")

    return (
                setup:create-collection("/db/system/config", "db"),
                setup:create-collection("/db/system/config/db", "shakespeare"),
                setup:store-files("/db/system/config/db/shakespeare", $dir,
                    "shakespeare/collection.xconf", "text/xml"),
                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/*", "text/css"),
                setup:create-collection("/db/xinclude", "scripts"),
                setup:create-collection("/db/xinclude/scripts", "syntax"),
                setup:store-files("/db/xinclude/scripts/syntax", $dir, "xinclude/scripts/syntax/*.js", "application/x-javascript"),
                setup:create-collection("/db", "library"),
                setup:store-files("/db/library", $dir, "*.rdf", "text/xml"),
                setup:create-collection("/db/system/config/db", "mods"),
                setup:store-files("/db/system/config/db/mods", $dir, "mods/collection.xconf", "text/xml"),
                setup:create-collection("/db", "mods"),
                setup:create-collection("/db/mods", "eXist"),
                setup:create-collection("/db/mods", "samples"),
                setup:create-collection("/db/mods", "users"),
                setup:create-group("biblio.users"),
                setup:set-collection-group("/db/mods/users", "biblio.users"),
                setup:set-collection-permissions("/db/mods/users", "rwxrwxr--"),
                setup:create-collection("/db/mods", "groups"),
                setup:set-collection-group("/db/mods/groups", "biblio.users"),
                setup:set-collection-permissions("/db/mods/groups", "rwxrwx---"),
                setup:store-files("/db/mods/samples", $dir, "mods/*.xml", "text/xml"),
                setup:store-files("/db/mods/eXist", $dir, "mods/eXist/*.xml", "text/xml"),
                setup:store-files("/db", $dir, "*.xml", "text/xml"),
                setup:create-collection("/db/system/config/db", "mondial"),
                setup:store-files("/db/system/config/db/mondial", $dir, "mondial.xconf", "text/xml"),
                setup:create-collection("/db/system/config/db", "xmlad"),
                setup:store-files("/db/system/config/db/xmlad", $dir, "acronyms.xconf", "text/xml"),

                (: Storing Testing :)
                setup:create-collection("/db", "testing"),
                setup:store-files("/db/testing", $webapp, "testing/*.xml", "text/html"),
                setup:store-files("/db/testing", $webapp, "testing/*.xq*", "application/xquery"),
                setup:create-collection("/db/testing", "examples"),
                setup:store-files("/db/testing/examples", $webapp, "testing/examples/*.xml", "text/html"),
                setup:store-files("/db/testing/examples", $webapp, "testing/examples/*.xq*", "application/xquery"),

                (: Storing XProc :)
                setup:create-collection("/db", "xproc"),
                setup:create-collection("/db/xproc", "unit-test"),
                setup:create-collection("/db/xproc", "xml"),
                setup:create-collection("/db/xproc", "xslt"),
                setup:create-collection("/db/xproc", "result"),
                setup:create-collection("/db/xproc", "examples"),
                setup:create-collection("/db/xproc", "pipelines"),
                setup:store-files("/db/xproc/unit-test", $webapp, "xproc/unit-test/*.xml", "text/xml"),
                setup:store-files("/db/xproc/unit-test", $webapp, "xproc/unit-test/*.xql", "application/xquery"),
                setup:store-files("/db/xproc/unit-test", $webapp, "xproc/unit-test/*.xsl", "text/xml"),

                setup:store-files("/db/xproc/pipelines", $webapp, "xproc/pipelines/*.xml", "text/xml"),
                setup:store-files("/db/xproc/xml", $webapp, "xproc/xml/*.xml", "text/xml"),
                setup:store-files("/db/xproc/xslt", $webapp, "xproc/xml/*.xsl", "text/xml"),

                setup:store-files("/db/xproc/examples", $webapp, "xproc/examples/*.xproc", "application/xml+xproc"),
                setup:store-files("/db/xproc/examples", $webapp, "xproc/examples/*.xml", "text/xml"),

                setup:store-files("/db/xproc/examples", $webapp, "xproc/examples/*.xql", "application/xquery"),
                setup:store-files("/db/xproc", $webapp, "xproc/*.xml", "text/xml"),
                setup:store-files("/db/xproc", $webapp, "xproc/*.xql", "application/xquery"),

                (: Storing XForms in the db won't work right now :)
                (:
                setup:create-collection("/db", "xforms"),
                setup:store-files("/db/xforms", $webapp, "xforms/*.xml", "text/html"),
                setup:store-files("/db/xforms", $webapp, "xforms/*.xq*", "application/xquery"),
                setup:create-collection("/db/xforms", "xsltforms"),
                setup:create-collection("/db/xforms", "data"),
                setup:store-files("/db/xforms/xsltforms", $webapp, "xforms/xsltforms/*.properties", "text/plain"),
                setup:store-files("/db/xforms/xsltforms", $webapp, "xforms/xsltforms/*.png", "image/png"),
                setup:store-files("/db/xforms/xsltforms", $webapp, "xforms/xsltforms/*.gif", "image/gif"),
                setup:store-files("/db/xforms/xsltforms", $webapp, "xforms/xsltforms/*.xsl","text/xml"),
                setup:store-files("/db/xforms/xsltforms", $webapp, "xforms/xsltforms/*.js","application/x-javascript"),
                setup:store-files("/db/xforms/xsltforms", $webapp, "xforms/xsltforms/*.css","text/css")
                :)

				(: Storing betterFORM XRX sample application :)

				setup:create-collection("/db", "betterform"),
				setup:create-collection("/db/betterform", "apps"),
				setup:create-collection("/db/betterform/apps", "timetracker"),
				setup:store-files("/db/betterform/apps/timetracker", $betterform-xrx, "*.xql","application/xquery"),
				setup:store-files("/db/betterform/apps/timetracker", $betterform-xrx, "*.html","text/html"),
				setup:store-files("/db/betterform/apps/timetracker", $betterform-xrx, "*.xml","application/xml"),
				setup:create-collection("/db/betterform/apps/timetracker", "data"),
				setup:store-files("/db/betterform/apps/timetracker/data", $betterform-xrx, "data/*.xml", "application/xml"),
				setup:create-collection("/db/betterform/apps/timetracker/data", "task"),
				setup:store-files("/db/betterform/apps/timetracker/data/task", $betterform-xrx, "data/task/*.xml","application/xml"),
				setup:create-collection("/db/betterform/apps/timetracker/", "edit"),
				setup:store-files("/db/betterform/apps/timetracker/edit", $betterform-xrx, "edit/*.xql","application/xquery"),
				setup:create-collection("/db/betterform/apps/timetracker/", "lucene"),
				setup:store-files("/db/betterform/apps/timetracker/lucene", $betterform-xrx, "lucene/*.xconf","application/xml"),
				setup:create-collection("/db/betterform/apps/timetracker/", "reports"),
				setup:store-files("/db/betterform/apps/timetracker/reports", $betterform-xrx, "reports/*.xql","application/xquery"),
				setup:create-collection("/db/betterform/apps/timetracker/", "resources"),
				setup:store-files("/db/betterform/apps/timetracker/resources", $betterform-xrx, "resources/*.css","text/css"),
				setup:create-collection("/db/betterform/apps/timetracker/resources", "images"),
				setup:store-files("/db/betterform/apps/timetracker/resources/images", $betterform-xrx, "resources/images/*.gif","image/gif"),
				setup:store-files("/db/betterform/apps/timetracker/resources/images", $betterform-xrx, "resources/images/*.png","image/png"),
				setup:store-files("/db/betterform/apps/timetracker/resources/images", $betterform-xrx, "resources/images/*.jpg","image/jpeg"),
				setup:create-collection("/db/betterform/apps/timetracker/", "search"),
				setup:store-files("/db/betterform/apps/timetracker/search", $betterform-xrx, "search/*.xql","application/xquery"),
				setup:store-files("/db/betterform/apps/timetracker/search", $betterform-xrx, "search/*.html","text/html"),
				setup:create-collection("/db/betterform/apps/timetracker/", "update"),
				setup:store-files("/db/betterform/apps/timetracker/update", $betterform-xrx, "update/*.xql","application/xquery"),
				setup:create-collection("/db/betterform/apps/timetracker/", "views"),
				setup:store-files("/db/betterform/apps/timetracker/views", $betterform-xrx, "views/*.xql","application/xquery"),
				setup:store-files("/db/betterform/apps/timetracker/views", $betterform-xrx, "views/*.html","text/html"),
				setup:store-files("/db/betterform/apps/timetracker/views", $betterform-xrx, "views/*.xsl","application/xml"),

				(: Storing betterFORM dashboard :)
				setup:create-collection("/db/betterform", "utils"),
                setup:store-files("/db/betterform/utils", $betterform-xforms, "utils/*.xql","application/xquery"),

				(: Storing betterFORM XForms reference forms :)
				setup:store-files("/db/betterform", $betterform-xforms, "*.xhtml","application/xhtml+xml"),
				setup:create-collection("/db/betterform", "forms"),
				setup:create-collection("/db/betterform/forms", "reference"),
				setup:store-files("/db/betterform/forms/reference", $betterform-xforms, "reference/*.xhtml","application/xhtml+xml"),
				setup:store-files("/db/betterform/forms/reference", $betterform-xforms, "reference/*.css","text/css"),
				setup:store-files("/db/betterform/forms/reference", $betterform-xforms, "reference/*.html","text/html"),
				setup:create-collection("/db/betterform/forms/reference", "images"),
				setup:store-files("/db/betterform/forms/reference/images", $betterform-xforms, "reference/images/*.png","image/png"),
				setup:store-files("/db/betterform/forms/reference/images", $betterform-xforms, "reference/images/*.gif","image/gif"),
				setup:create-collection("/db/betterform/forms/reference", "resources"),
				setup:store-files("/db/betterform/forms/reference/resources", $betterform-xforms, "reference/resources/*.xhtml","application/xhtml+xml"),
				setup:store-files("/db/betterform/forms/reference/resources", $betterform-xforms, "reference/resources/*.html","text/html"),
				setup:store-files("/db/betterform/forms/reference/resources", $betterform-xforms, "reference/resources/*.css","text/css"),
				setup:store-files("/db/betterform/forms/reference/resources", $betterform-xforms, "reference/resources/*.js","application/x-javascript"),
				setup:store-files("/db/betterform/forms/reference/resources", $betterform-xforms, "reference/resources/*.jpg","image/jpeg"),
				setup:create-collection("/db/betterform/forms", "demo"),
				setup:store-files("/db/betterform/forms/demo", $betterform-xforms, "demo/*.xhtml","application/xhtml+xml"),
				setup:create-collection("/db/betterform/forms/demo", "styles"),
				setup:store-files("/db/betterform/forms/demo/styles", $betterform-xforms, "demo/styles/*.css","text/css"),
				setup:store-files("/db/betterform/forms/demo", $betterform-xforms, "demo/*.xml","application/xml")
    )
};

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

Actions:

            {
                let $includeXmlad := request:get-parameter("xmlad", ()),
                $includeMondial := request:get-parameter("mondial", ()),
 				$includeLocal := request:get-parameter("local", ()) return
                (
					if($includeLocal) then
					( setup:importLocal()
					)
					else (),
                    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:create-group($group as xs:string) as element()
{
    if(xdb:group-exists($group))then
    (

Verified group: {$group} exists

    )
    else
    (
        let $result := xdb:create-group($group, xdb:get-current-user()) return
            if($result)then (

Created group: {$group}

            ) else (

Failed to create group: {$group}

            )
    )
};

declare function setup:set-collection-group($collection as xs:string, $group as xs:string) as element() {
    let $null := xdb:set-collection-permissions($collection, xdb:get-owner($collection), $group, xdb:get-permissions($collection)) return

Set collection '{$collection}' group to '{$group}'

};

declare function setup:set-collection-permissions($collection as xs:string, $permissions as xs:string) as element() {
        let $null := xdb:set-collection-permissions($collection, xdb:get-owner($collection), xdb:get-group($collection), xdb:string-to-permissions($permissions)) return

Set collection '{$collection}' permissions '{$permissions}'.

};

declare function setup:select() 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. The XQuery examples also use some
		XML data not included with the distribution which can be downloaded by selecting
		the checkboxes below.

		<input type="checkbox" name="local" checked="true"/>eXist-db shipped files

        <input type="checkbox" name="xmlad"/>
        The XML Acronym Demystifier
        (approx. 384K, download from internet)

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

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

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

(*) Contains data for the betterFORM, shakespeare, xinclude, library, mods and xproc examples.
            It also contains the index configuration definitions for the mondial and acronym examples.

    </form>
};

declare function setup:report() 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 namespace file="http://exist-db.org/xquery/file";

declare namespace xproc="http://xproc.net/xproc";

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

Install Examples

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

        }

};

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")
        ),
    $webapp := if (doc-available(concat("file:///", $home, "/webapp/index.xml"))) then
        (
            concat($home, $pathSep, "webapp")
        )
        else if(ends-with($home, "WEB-INF")) then
        (
            substring-before($home, "WEB-INF")
        )
        else
        (
            concat($home, $pathSep, "webapp")
        )
        ,
    $betterform-home := if (ends-with($home, "WEB-INF")) then
        (
            concat( substring-before($home, "WEB-INF"), "/betterform/samples")
        )
        else
        (
            concat($home, "/extensions/betterform/main")
        ),

    $betterform-xrx := concat($betterform-home, "/xrx/timetracker/"),
    $betterform-xforms := concat($betterform-home, "/xforms")

    return (
                setup:create-collection("/db/system/config", "db"),
                setup:create-collection("/db/system/config/db", "shakespeare"),
                setup:store-files("/db/system/config/db/shakespeare", $dir,
                    "shakespeare/collection.xconf", "text/xml"),
                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/*", "text/css"),
                setup:create-collection("/db/xinclude", "scripts"),
                setup:create-collection("/db/xinclude/scripts", "syntax"),
                setup:store-files("/db/xinclude/scripts/syntax", $dir, "xinclude/scripts/syntax/*.js", "application/x-javascript"),
                setup:create-collection("/db", "library"),
                setup:store-files("/db/library", $dir, "*.rdf", "text/xml"),
                setup:create-collection("/db/system/config/db", "mods"),
                setup:store-files("/db/system/config/db/mods", $dir, "mods/collection.xconf", "text/xml"),
                setup:create-collection("/db", "mods"),
                setup:create-collection("/db/mods", "eXist"),
                setup:create-collection("/db/mods", "samples"),
                setup:create-collection("/db/mods", "users"),
                setup:create-group("biblio.users"),
                setup:set-collection-group("/db/mods/users", "biblio.users"),
                setup:set-collection-permissions("/db/mods/users", "rwurwur--"),
                setup:create-collection("/db/mods", "groups"),
                setup:set-collection-group("/db/mods/groups", "biblio.users"),
                setup:set-collection-permissions("/db/mods/groups", "rwurwu---"),
                setup:store-files("/db/mods/samples", $dir, "mods/*.xml", "text/xml"),
                setup:store-files("/db/mods/eXist", $dir, "mods/eXist/*.xml", "text/xml"),
                setup:store-files("/db", $dir, "*.xml", "text/xml"),
                setup:create-collection("/db/system/config/db", "mondial"),
                setup:store-files("/db/system/config/db/mondial", $dir, "mondial.xconf", "text/xml"),
                setup:create-collection("/db/system/config/db", "xmlad"),
                setup:store-files("/db/system/config/db/xmlad", $dir, "acronyms.xconf", "text/xml"),

                (: Storing Testing :)
                setup:create-collection("/db", "testing"),
                setup:store-files("/db/testing", $webapp, "testing/*.xml", "text/html"),
                setup:store-files("/db/testing", $webapp, "testing/*.xq*", "application/xquery"),
                setup:create-collection("/db/testing", "examples"),
                setup:store-files("/db/testing/examples", $webapp, "testing/examples/*.xml", "text/html"),
                setup:store-files("/db/testing/examples", $webapp, "testing/examples/*.xq*", "application/xquery"),

                (: Storing XProc :)
                setup:create-collection("/db", "xproc"),
                setup:create-collection("/db/xproc", "unit-test"),
                setup:create-collection("/db/xproc", "xml"),
                setup:create-collection("/db/xproc", "xslt"),
                setup:create-collection("/db/xproc", "result"),
                setup:create-collection("/db/xproc", "examples"),
                setup:create-collection("/db/xproc", "pipelines"),
                setup:store-files("/db/xproc/unit-test", $webapp, "xproc/unit-test/*.xml", "text/xml"),
                setup:store-files("/db/xproc/unit-test", $webapp, "xproc/unit-test/*.xql", "application/xquery"),
                setup:store-files("/db/xproc/unit-test", $webapp, "xproc/unit-test/*.xsl", "text/xml"),

                setup:store-files("/db/xproc/pipelines", $webapp, "xproc/pipelines/*.xml", "text/xml"),
                setup:store-files("/db/xproc/xml", $webapp, "xproc/xml/*.xml", "text/xml"),
                setup:store-files("/db/xproc/xslt", $webapp, "xproc/xml/*.xsl", "text/xml"),

                setup:store-files("/db/xproc/examples", $webapp, "xproc/examples/*.xproc", "application/xml+xproc"),
                setup:store-files("/db/xproc/examples", $webapp, "xproc/examples/*.xml", "text/xml"),

                setup:store-files("/db/xproc/examples", $webapp, "xproc/examples/*.xql", "application/xquery"),
                setup:store-files("/db/xproc", $webapp, "xproc/*.xml", "text/xml"),
                setup:store-files("/db/xproc", $webapp, "xproc/*.xql", "application/xquery"),

                (: Storing XForms in the db won't work right now :)
                (:
                setup:create-collection("/db", "xforms"),
                setup:store-files("/db/xforms", $webapp, "xforms/*.xml", "text/html"),
                setup:store-files("/db/xforms", $webapp, "xforms/*.xq*", "application/xquery"),
                setup:create-collection("/db/xforms", "xsltforms"),
                setup:create-collection("/db/xforms", "data"),
                setup:store-files("/db/xforms/xsltforms", $webapp, "xforms/xsltforms/*.properties", "text/plain"),
                setup:store-files("/db/xforms/xsltforms", $webapp, "xforms/xsltforms/*.png", "image/png"),
                setup:store-files("/db/xforms/xsltforms", $webapp, "xforms/xsltforms/*.gif", "image/gif"),
                setup:store-files("/db/xforms/xsltforms", $webapp, "xforms/xsltforms/*.xsl","text/xml"),
                setup:store-files("/db/xforms/xsltforms", $webapp, "xforms/xsltforms/*.js","application/x-javascript"),
                setup:store-files("/db/xforms/xsltforms", $webapp, "xforms/xsltforms/*.css","text/css")
                :)

				(: Storing betterFORM XRX sample application :)

				setup:create-collection("/db", "betterform"),
				setup:create-collection("/db/betterform", "apps"),
				setup:create-collection("/db/betterform/apps", "timetracker"),
				setup:store-files("/db/betterform/apps/timetracker", $betterform-xrx, "*.xql","application/xquery"),
				setup:store-files("/db/betterform/apps/timetracker", $betterform-xrx, "*.html","text/html"),
				setup:store-files("/db/betterform/apps/timetracker", $betterform-xrx, "*.xml","application/xml"),
				setup:create-collection("/db/betterform/apps/timetracker", "data"),
				setup:store-files("/db/betterform/apps/timetracker/data", $betterform-xrx, "data/*.xml", "application/xml"),
				setup:create-collection("/db/betterform/apps/timetracker/data", "task"),
				setup:store-files("/db/betterform/apps/timetracker/data/task", $betterform-xrx, "data/task/*.xml","application/xml"),
				setup:create-collection("/db/betterform/apps/timetracker/", "edit"),
				setup:store-files("/db/betterform/apps/timetracker/edit", $betterform-xrx, "edit/*.xql","application/xquery"),
				setup:create-collection("/db/betterform/apps/timetracker/", "lucene"),
				setup:store-files("/db/betterform/apps/timetracker/lucene", $betterform-xrx, "lucene/*.xconf","application/xml"),
				setup:create-collection("/db/betterform/apps/timetracker/", "reports"),
				setup:store-files("/db/betterform/apps/timetracker/reports", $betterform-xrx, "reports/*.xql","application/xquery"),
				setup:create-collection("/db/betterform/apps/timetracker/", "resources"),
				setup:store-files("/db/betterform/apps/timetracker/resources", $betterform-xrx, "resources/*.css","text/css"),
				setup:create-collection("/db/betterform/apps/timetracker/resources", "images"),
				setup:store-files("/db/betterform/apps/timetracker/resources/images", $betterform-xrx, "resources/images/*.gif","image/gif"),
				setup:store-files("/db/betterform/apps/timetracker/resources/images", $betterform-xrx, "resources/images/*.png","image/png"),
				setup:store-files("/db/betterform/apps/timetracker/resources/images", $betterform-xrx, "resources/images/*.jpg","image/jpeg"),
				setup:create-collection("/db/betterform/apps/timetracker/", "search"),
				setup:store-files("/db/betterform/apps/timetracker/search", $betterform-xrx, "search/*.xql","application/xquery"),
				setup:store-files("/db/betterform/apps/timetracker/search", $betterform-xrx, "search/*.html","text/html"),
				setup:create-collection("/db/betterform/apps/timetracker/", "update"),
				setup:store-files("/db/betterform/apps/timetracker/update", $betterform-xrx, "update/*.xql","application/xquery"),
				setup:create-collection("/db/betterform/apps/timetracker/", "views"),
				setup:store-files("/db/betterform/apps/timetracker/views", $betterform-xrx, "views/*.xql","application/xquery"),
				setup:store-files("/db/betterform/apps/timetracker/views", $betterform-xrx, "views/*.html","text/html"),
				setup:store-files("/db/betterform/apps/timetracker/views", $betterform-xrx, "views/*.xsl","application/xml"),

				(: Storing betterFORM dashboard :)
				setup:create-collection("/db/betterform", "utils"),
                setup:store-files("/db/betterform/utils", $betterform-xforms, "utils/*.xql","application/xquery"),

				(: Storing betterFORM XForms reference forms :)
				setup:store-files("/db/betterform", $betterform-xforms, "*.xhtml","application/xhtml+xml"),
				setup:create-collection("/db/betterform", "forms"),
				setup:create-collection("/db/betterform/forms", "reference"),
				setup:store-files("/db/betterform/forms/reference", $betterform-xforms, "reference/*.xhtml","application/xhtml+xml"),
				setup:store-files("/db/betterform/forms/reference", $betterform-xforms, "reference/*.css","text/css"),
				setup:store-files("/db/betterform/forms/reference", $betterform-xforms, "reference/*.html","text/html"),
				setup:create-collection("/db/betterform/forms/reference", "images"),
				setup:store-files("/db/betterform/forms/reference/images", $betterform-xforms, "reference/images/*.png","image/png"),
				setup:store-files("/db/betterform/forms/reference/images", $betterform-xforms, "reference/images/*.gif","image/gif"),
				setup:create-collection("/db/betterform/forms/reference", "resources"),
				setup:store-files("/db/betterform/forms/reference/resources", $betterform-xforms, "reference/resources/*.xhtml","application/xhtml+xml"),
				setup:store-files("/db/betterform/forms/reference/resources", $betterform-xforms, "reference/resources/*.html","text/html"),
				setup:store-files("/db/betterform/forms/reference/resources", $betterform-xforms, "reference/resources/*.css","text/css"),
				setup:store-files("/db/betterform/forms/reference/resources", $betterform-xforms, "reference/resources/*.js","application/x-javascript"),
				setup:store-files("/db/betterform/forms/reference/resources", $betterform-xforms, "reference/resources/*.jpg","image/jpeg"),
				setup:create-collection("/db/betterform/forms", "demo"),
				setup:store-files("/db/betterform/forms/demo", $betterform-xforms, "demo/*.xhtml","application/xhtml+xml"),
				setup:create-collection("/db/betterform/forms/demo", "styles"),
				setup:store-files("/db/betterform/forms/demo/styles", $betterform-xforms, "demo/styles/*.css","text/css"),
				setup:store-files("/db/betterform/forms/demo", $betterform-xforms, "demo/*.xml","application/xml")
    )
};

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

Actions:

            {
                let $includeXmlad := request:get-parameter("xmlad", ()),
                $includeMondial := request:get-parameter("mondial", ()),
 				$includeLocal := request:get-parameter("local", ()) return
                (
					if($includeLocal) then
					( setup:importLocal()
					)
					else (),
                    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:create-group($group as xs:string) as element()
{
    if(xdb:group-exists($group))then
    (

Verified group: {$group} exists

    )
    else
    (
        let $result := xdb:create-group($group, xdb:get-current-user()) return
            if($result)then (

Created group: {$group}

            ) else (

Failed to create group: {$group}

            )
    )
};

declare function setup:set-collection-group($collection as xs:string, $group as xs:string) as element() {
    let $null := xdb:set-collection-permissions($collection, xdb:get-owner($collection), $group, xdb:get-permissions($collection)) return

Set collection '{$collection}' group to '{$group}'

};

declare function setup:set-collection-permissions($collection as xs:string, $permissions as xs:string) as element() {
        let $null := xdb:set-collection-permissions($collection, xdb:get-owner($collection), xdb:get-group($collection), xdb:string-to-permissions($permissions)) return

Set collection '{$collection}' permissions '{$permissions}'.

};

declare function setup:select() 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. The XQuery examples also use some
		XML data not included with the distribution which can be downloaded by selecting
		the checkboxes below.

		<input type="checkbox" name="local" checked="true"/>eXist-db shipped files

        <input type="checkbox" name="xmlad"/>
        The XML Acronym Demystifier
        (approx. 384K, download from internet)

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

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

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

(*) Contains data for the betterFORM, shakespeare, xinclude, library, mods and xproc examples.
            It also contains the index configuration definitions for the mondial and acronym examples.

    </form>
};

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

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

};


Cleanup and polishing of script to generate definitions

xquery version "1.0-ml";

declare variable $xml external;
let $xml := xdmp:unquote("<wrap>" || $xml || "</wrap>")

let $definition := xdmp:xslt-eval(
  <xsl:stylesheet version="2.0" exclude-result-prefixes="#all" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:apidoc="http://marklogic.com/xdmp/apidoc" xmlns:local="local">

    <xsl:output method="text" indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="@*|node()" mode="#all">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()" mode="#current"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="apidoc:function" mode="#all">
      <xsl:param name="use-function-keyword" select="false()"/>
      <xsl:param name="use-declare-keyword" select="false()"/>

      <xsl:text>    /** </xsl:text>
      <xsl:value-of select="normalize-space(apidoc:summary)"/>
      <xsl:text> **/
</xsl:text>

      <xsl:text>  </xsl:text>
      <xsl:if test="$use-declare-keyword">
        <xsl:text>declare </xsl:text>
      </xsl:if>
      <xsl:if test="$use-function-keyword">
        <xsl:text>function </xsl:text>
      </xsl:if>
      <xsl:value-of select="local:fixName(@name)"/>
      <xsl:text>(</xsl:text>
      <xsl:for-each select="apidoc:params/apidoc:param">
        <xsl:variable name="is-multi" select="matches(@type, ',\.\.\.$')"/>
        <xsl:if test="$is-multi">...</xsl:if>
        <xsl:value-of select="local:fixName(@name)"/>
        <xsl:if test="preceding-sibling::apidoc:param[@name = current()/@name]">2</xsl:if>
        <xsl:if test="not($is-multi) and string(@optional) = 'true'">?</xsl:if>
        <xsl:text>: </xsl:text>
        <xsl:value-of select="local:fixType(@type, true())"/>
        <xsl:if test="$is-multi">[]</xsl:if>
        <xsl:if test="not($is-multi) and string(@optional) = 'true'">|null|undefined</xsl:if>
        <xsl:if test="not(position() = last())">, </xsl:if>
      </xsl:for-each>
      <xsl:text>): </xsl:text>
      <xsl:value-of select="local:fixType(string(apidoc:return), false())"/>
      <xsl:text>;

</xsl:text>
    </xsl:template>

    <xsl:template match="/wrap">
      <xsl:variable name="root" select="."/>

      <xsl:text>// Type definitions for </xsl:text><xsl:value-of select="apidoc:module[exists(apidoc:function)]/@name"/><xsl:text>
</xsl:text>
      <xsl:text>// Definitions: </xsl:text><xsl:value-of select="base-uri(.)"/><xsl:text>

</xsl:text>

        <xsl:for-each select="distinct-values(((//apidoc:module[exists(apidoc:function)]/@lib, 'xdmp')[1], //apidoc:function/@lib))">
          <xsl:sort/>
          <xsl:variable name="lib" select="."/>
          <xsl:variable name="name" select="string-join(local:fixName($lib), '')"/>
          <xsl:variable name="functions" select="$root//apidoc:function[@lib = $lib]"/>
          <xsl:variable name="module" select="$functions/.."/>

          <xsl:text>
/**
</xsl:text>
          <xsl:value-of select="$module/apidoc:summary"/>
          <xsl:text>
**/

</xsl:text>

          <xsl:choose>
          <xsl:when test="$name = 'GlobalObject'">
            <xsl:apply-templates select="$functions">
              <xsl:sort select="@name" />
              <xsl:with-param name="use-function-keyword" select="true()"/>
              <xsl:with-param name="use-declare-keyword" select="true()"/>
            </xsl:apply-templates>
          </xsl:when>
          <xsl:when test="$name = 'alert'">
            <xsl:text>declare module </xsl:text>
            <xsl:value-of select="$name"/>
            <xsl:text> {{

</xsl:text>

            <xsl:apply-templates select="$functions">
              <xsl:sort select="@name" />
              <xsl:with-param name="use-function-keyword" select="true()"/>
            </xsl:apply-templates>

            <xsl:text>}}
</xsl:text>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text>interface </xsl:text>
            <xsl:value-of select="$name"/>
            <xsl:text>Functions {{

</xsl:text>

            <xsl:apply-templates select="$functions">
              <xsl:sort select="@name" />
            </xsl:apply-templates>

            <xsl:text>}}
</xsl:text>

            <xsl:text>declare var </xsl:text>
            <xsl:value-of select="$name"/>
            <xsl:text>:</xsl:text>
            <xsl:value-of select="$name"/>
            <xsl:text>Functions
</xsl:text>
          </xsl:otherwise>
          </xsl:choose>
        </xsl:for-each>
    </xsl:template>

    <xsl:function name="local:fixType">
      <xsl:param name="fullType"/>
      <xsl:param name="isForParameter"/>

      <xsl:variable name="fullType" select="translate($fullType, ' ', '')"/>
      <xsl:variable name="type" select="replace(replace($fullType, ',\.\.\.$', ''), '([?*+]|\[\])$', '')"/>
      <xsl:variable name="cardinality" select="substring($fullType, string-length($type) + 1)"/>
      <xsl:variable name="isArray" select="matches($cardinality, '^([*+]|\[\])')"/>
      <xsl:variable name="type" select="if (substring($type, 1, 1) = '(') then substring($type, 2, string-length($type) - 2) else $type"/>

      <xsl:value-of select="local:fixEachType($type, $isArray, $isForParameter)"/>
    </xsl:function>

    <xsl:function name="local:fixEachType">
      <xsl:param name="typeUnion"/>
      <xsl:param name="isArray"/>
      <xsl:param name="isForParameter"/>

      <xsl:variable name="type" select="substring-before(concat($typeUnion,'|'),'|')"/>
      <xsl:variable name="type" select="replace($type, '([?*+]|\[\])$', '')"/>

      <xsl:choose>
        <xsl:when test="matches($type, '^function\(.*\)as(.+)$')">
          <xsl:value-of select="local:fixFunctionType($type, $isArray)"/>
        </xsl:when>
        <xsl:when test="$isArray">
          <xsl:choose>
            <xsl:when test="$type = ('document-node()', 'binary()', 'element()', 'node()')">
              <xsl:value-of select="local:fixArrayType('any', $isForParameter)"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="local:fixArrayType(string-join(local:fixSingleType($type, $isForParameter), ''), $isForParameter)"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="local:fixSingleType($type, $isForParameter)"/>
        </xsl:otherwise>
      </xsl:choose>

      <xsl:if test="contains($typeUnion, '|')">
        <xsl:value-of select="concat('|', string-join(local:fixEachType(substring-after($typeUnion, '|'), $isArray, $isForParameter), ''))"/>
      </xsl:if>
    </xsl:function>

    <xsl:function name="local:fixArrayType">
      <xsl:param name="type"/>
      <xsl:param name="isForParameter"/>
      <xsl:value-of select="concat(concat(if($isForParameter) then 'MLArray<' else 'Sequence<', $type), '>')"/>
    </xsl:function>

    <xsl:function name="local:fixSingleType">
      <xsl:param name="type"/>
      <xsl:param name="isForParameter"/>
      <xsl:choose>
        <!-- workarounds for docs bugs -->
        <xsl:when test="$type = 'query-results-serialize($results)'">MLNode<any></xsl:when>
        <xsl:when test="$type = 'option'">Sequence<any></xsl:when>
        <xsl:when test="$type = 'genericDateTimeArg'">xs.GenericDateTimeArg</xsl:when>
        <xsl:when test="$type = 'rdf:collatedString'">sql.CollatedString</xsl:when>

        <xsl:when test="$type = 'any[]'">Array<any></xsl:when>
        <xsl:when test="$type = ('ValueIterator', 'Sequence')">Sequence<any></xsl:when>
        <xsl:when test="$type = 'document-node()'">DocumentNode<any></xsl:when>
        <xsl:when test="$type = ('binary()')">MLNode<any></xsl:when>
        <xsl:when test="$type = ('element()', 'node()')">
          <xsl:choose>
            <xsl:when test="$isForParameter">MLNodeOrObject<any></xsl:when>
            <xsl:otherwise>MLNode<any></xsl:otherwise>
          </xsl:choose>
        </xsl:when>
        <xsl:when test="$type = ('empty-seq', 'empty-sequence', 'empty-sequence()', 'null', 'Null')">null</xsl:when>
        <xsl:when test="$type = ('String', 'xs:anyURI', 'xs:NCName', 'xs:string', 'xs:time', 'xs:duration', 'xs:dayTimeDuration')">string</xsl:when>
        <xsl:when test="$type = ('json:array', 'Array')">Array<any></xsl:when>
        <xsl:when test="$type = ('json:object', 'map:map', 'Options')">{[key:string]:any}</xsl:when>
        <xsl:when test="$type = ('function()', 'xdmp:function', 'function(*', 'function(*)', 'function')">() => any</xsl:when>
        <xsl:when test="$type = 'xs:boolean'">boolean</xsl:when>
        <xsl:when test="$type = ('any', 'xs:anyAtomicType', 'item()')">any</xsl:when>
        <xsl:when test="$type = ('xs:dateTime', 'xs:date')">Date</xsl:when>
        <xsl:when test="$type = ('Int', 'double', 'xs:numeric', 'numeric', 'xs:decimal', 'xs:double', 'xs:unsigned', 'xs:unsingedLong', 'xs:unsignedLong', 'xs:int', 'xs:float', 'xs:integer', 'xs:long', 'xs:nonNegativeInteger', 'xs:positiveInteger', 'xs:unsignedInt')">number</xsl:when>
        <xsl:when test="matches($type, '^(schema-)?[Ee]lement\([^)]+\)')">
          <xsl:choose>
            <!-- TODO: Can we perform generics on this? -->
            <xsl:when test="$isForParameter">MLNodeOrObject<any></xsl:when>
            <xsl:otherwise>MLNode<any></xsl:otherwise>
          </xsl:choose>
        </xsl:when>
        <xsl:otherwise>
          <xsl:variable name="local-name" select="replace($type, '^([^:.]+[:.])?([^\(\)]+)\(?\)?$', '$2')"/>
          <xsl:variable name="fixed-local-name" select="string-join(local:fixName($local-name), '')"/>
          <xsl:variable name="type-name" select="concat(upper-case(substring($fixed-local-name, 1, 1)), substring($fixed-local-name, 2))"/>
          <xsl:choose>
            <xsl:when test="contains($type, ':') or contains($type, '.')">
              <xsl:variable name="prefix-name" select="replace($type, '^([^:.]+[:.])?(.+)$', '$1')"/>
              <xsl:value-of select="concat(substring($prefix-name, 1, string-length($prefix-name) - 1), concat('.', $type-name))"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="$type-name"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:function>

    <xsl:function name="local:fixFunctionType">
      <xsl:param name="type"/>
      <xsl:param name="isArray"/>
      <xsl:text>(</xsl:text>
      <xsl:if test="matches($type, '^function\((.+)\)as(.+)$')">
        <xsl:value-of select="local:fixParameters(replace($type, '^function\((.+)\)as(.+)$', '$1'), 1)"/>
      </xsl:if>
      <xsl:text>)=></xsl:text>
      <xsl:variable name="returnType" select="local:fixType(replace($type, '^function\(.*\)as(.+)$', '$1'), false())"/>
      <xsl:choose>
        <xsl:when test="$isArray">
          <xsl:value-of select="local:fixArrayType($returnType, false())"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$returnType"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:function>

    <xsl:function name="local:fixParameters">
      <xsl:param name="parameters"/>
      <xsl:param name="number"/>
      <xsl:value-of select="concat(concat('p', $number), ':')"/>
      <xsl:variable name="type" select="substring-before(concat($parameters,','),',')"/>
      <xsl:value-of select="local:fixType($type, true())"/>
      <xsl:if test="contains($parameters, ',')">
        <xsl:value-of select="concat(',', string-join(local:fixParameters(substring-after($parameters, ','), $number + 1), ''))"/>
      </xsl:if>
    </xsl:function>

    <xsl:function name="local:fixName">
      <xsl:param name="name"/>

      <xsl:choose>
        <xsl:when test="$name = 'default'">defaultVal</xsl:when>
        <xsl:when test="$name = 'function'">functionArg</xsl:when>
        <xsl:when test="$name = 'in'">input</xsl:when>
        <xsl:when test="$name = 'else'">else_</xsl:when>
        <xsl:when test="$name = 'new'">new_</xsl:when>
        <xsl:when test="$name = 'class'">class_</xsl:when>
        <xsl:when test="$name = 'delete'">delete_</xsl:when>
        <xsl:otherwise>
          <xsl:analyze-string select="replace($name, ' ', '_')" regex="-([a-zA-Z])">

            <xsl:matching-substring>
              <xsl:value-of select="upper-case(regex-group(1))"/>
            </xsl:matching-substring>

            <xsl:non-matching-substring>
              <xsl:value-of select="translate(., '-', '')"/>
            </xsl:non-matching-substring>

          </xsl:analyze-string>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:function>

  </xsl:stylesheet>, $xml)

return $definition

xquery version "1.0-ml";

declare variable $xml external;
let $xml := xdmp:unquote($xml)

let $definition := xdmp:xslt-eval(
  <xsl:stylesheet version="2.0" exclude-result-prefixes="#all" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:apidoc="http://marklogic.com/xdmp/apidoc" xmlns:local="local">

    <xsl:output method="text" indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="@*|node()" mode="#all">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()" mode="#current"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="apidoc:function" mode="#all">
      <xsl:param name="use-function-keyword" select="false()"/>
      <xsl:param name="use-declare-keyword" select="false()"/>
      <xsl:text>    /** </xsl:text>
      <xsl:value-of select="normalize-space(apidoc:summary[not(@class) or @class = 'javascript'])"/>
      <xsl:text> **/
</xsl:text>

      <xsl:text>  </xsl:text>
      <xsl:if test="$use-declare-keyword">
        <xsl:text>declare </xsl:text>
      </xsl:if>
      <xsl:if test="$use-function-keyword">
        <xsl:text>function </xsl:text>
      </xsl:if>
      <xsl:value-of select="local:fixName(@name)"/>
      <xsl:text>(</xsl:text>
      <xsl:for-each select="apidoc:params/apidoc:param[not(@class) or @class = 'javascript']">
        <xsl:variable name="is-multi" select ="substring(@type, string-length(@type) - 3) = ',...'"/>
        <xsl:if test="$is-multi">...</xsl:if>
        <xsl:value-of select="local:fixName(@name)"/>
        <xsl:if test="preceding-sibling::apidoc:param[not(@class) or @class = 'javascript'][@name = current()/@name]">2</xsl:if>
        <xsl:if test="not($is-multi) and string(@optional) = 'true'">?</xsl:if>
        <xsl:text>: </xsl:text>
        <xsl:value-of select="local:fixType(@type, true())"/>
        <xsl:if test="$is-multi">[]</xsl:if>
        <xsl:if test="not(position() = last())">, </xsl:if>
      </xsl:for-each>
      <xsl:text>): </xsl:text>
      <xsl:value-of select="local:fixType(string(apidoc:return[not(@class) or @class = 'javascript']), false())"/>
      <xsl:text>;

</xsl:text>
    </xsl:template>

    <xsl:template match="/">
      <xsl:variable name="root" select="."/>

      <xsl:text>// Type definitions for </xsl:text><xsl:value-of select="apidoc:module/@name"/><xsl:text>
</xsl:text>
      <xsl:text>// Definitions: </xsl:text><xsl:value-of select="base-uri(.)"/><xsl:text>

</xsl:text>

      <xsl:text>/**</xsl:text>
      <xsl:value-of select="apidoc:module/apidoc:summary[not(@class) or @class = 'javascript']"/>
      <xsl:text>**/

</xsl:text>

        <xsl:for-each select="distinct-values(((apidoc:module/@lib, 'xdmp')[1], //apidoc:function[empty(@http-verb)]/@lib))">
          <xsl:variable name="lib" select="."/>
          <xsl:variable name="name" select="string-join(local:fixName($lib), '')"/>

          <xsl:choose>
          <xsl:when test="$name = 'GlobalObject'">
            <xsl:apply-templates select="$root//apidoc:function[@lib = $lib][empty(@http-verb)][not(@class) or @class = 'javascript']">
              <xsl:with-param name="use-function-keyword" select="true()"/>
              <xsl:with-param name="use-declare-keyword" select="true()"/>
            </xsl:apply-templates>
          </xsl:when>
          <xsl:when test="$name = 'alert'">
            <xsl:text>declare module </xsl:text>
            <xsl:value-of select="$name"/>
            <xsl:text> {{

</xsl:text>

            <xsl:apply-templates select="$root//apidoc:function[@lib = $lib][empty(@http-verb)][not(@class) or @class = 'javascript']">
              <xsl:with-param name="use-function-keyword" select="true()"/>
            </xsl:apply-templates>

            <xsl:text>}}
</xsl:text>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text>interface </xsl:text>
            <xsl:value-of select="$name"/>
            <xsl:text>Functions {{

</xsl:text>

            <xsl:apply-templates select="$root//apidoc:function[@lib = $lib][empty(@http-verb)][not(@class) or @class = 'javascript']"/>

            <xsl:text>}}
</xsl:text>

            <xsl:text>declare var </xsl:text>
            <xsl:value-of select="$name"/>
            <xsl:text>:</xsl:text>
            <xsl:value-of select="$name"/>
            <xsl:text>Functions
</xsl:text>
          </xsl:otherwise>
          </xsl:choose>
        </xsl:for-each>
    </xsl:template>

    <xsl:function name="local:fixType">
      <xsl:param name="pType"/>
      <xsl:param name="isForParameter"/>

      <xsl:variable name="preTypeAndCardinality" select="replace(replace($pType, '^([^,]+)(,\.\.\.)?$', '$1'), ' ', '')"/>
      <xsl:variable name="lastCharacter" select="substring($preTypeAndCardinality, string-length($preTypeAndCardinality))"/>
      <xsl:variable name="preType" select="if (matches($lastCharacter, '^[?*+]$')) then substring($preTypeAndCardinality, 1, string-length($preTypeAndCardinality) - 1) else $preTypeAndCardinality"/>
      <xsl:variable name="isArray" select="matches($lastCharacter, '^[*+]$')"/>
      <xsl:variable name="type" select="if (substring($preType, 1, 1) = '(') then substring($preType, 2, string-length($preType) - 2) else $preType"/>

      <xsl:value-of select="local:fixEachType($type, $isArray, $isForParameter)"/>
    </xsl:function>

    <xsl:function name="local:fixEachType">
      <xsl:param name="typeUnion"/>
      <xsl:param name="isArray"/>
      <xsl:param name="isForParameter"/>

      <xsl:variable name="type" select="substring-before(concat($typeUnion,'|'),'|')"/>

      <xsl:choose>
        <xsl:when test="matches($type, '^function\(.*\)as(.+)$')">
          <xsl:value-of select="local:fixFunctionType($type, $isArray)"/>
        </xsl:when>
        <xsl:when test="$isArray">
          <xsl:choose>
            <xsl:when test="$type = ('document-node()', 'binary()', 'element()', 'node()')">
              <xsl:value-of select="local:fixArrayType('any', $isForParameter)"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="local:fixArrayType(string-join(local:fixSingleType($type, $isForParameter), ''), $isForParameter)"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="local:fixSingleType($type, $isForParameter)"/>
        </xsl:otherwise>
      </xsl:choose>

      <xsl:if test="contains($typeUnion, '|')">
        <xsl:value-of select="concat('|', string-join(local:fixEachType(substring-after($typeUnion, '|'), $isArray, $isForParameter), ''))"/>
      </xsl:if>
    </xsl:function>

    <xsl:function name="local:fixArrayType">
      <xsl:param name="type"/>
      <xsl:param name="isForParameter"/>
      <xsl:value-of select="concat(concat(if($isForParameter) then 'MLArray<' else 'ValueIterator<', $type), '>')"/>
    </xsl:function>

    <xsl:function name="local:fixSingleType">
      <xsl:param name="type"/>
      <xsl:param name="isForParameter"/>
      <xsl:choose>
        <xsl:when test="$type = 'ValueIterator'">ValueIterator<any></xsl:when>
        <xsl:when test="$type = 'document-node()'">DocumentNode<any></xsl:when>
        <xsl:when test="$type = ('binary()')">MLNode<any></xsl:when>
        <xsl:when test="$type = ('element()', 'node()')">
          <xsl:choose>
            <xsl:when test="$isForParameter">MLNodeOrObject<any></xsl:when>
            <xsl:otherwise>MLNode<any></xsl:otherwise>
          </xsl:choose>
        </xsl:when>
        <xsl:when test="$type = ('empty-sequence()', 'Null')">void</xsl:when>
        <xsl:when test="$type = ('String', 'xs:anyURI', 'xs:NCName', 'xs:string', 'xs:time', 'xs:duration', 'xs:dayTimeDuration')">string</xsl:when>
        <xsl:when test="$type = ('json:array', 'Array')">Array<any></xsl:when>
        <xsl:when test="$type = ('json:object', 'map:map')">{[key:string]:any}</xsl:when>
        <xsl:when test="$type = ('function()', 'xdmp:function', 'function(*', 'function(*)')">() => any</xsl:when>
        <xsl:when test="$type = 'xs:boolean'">boolean</xsl:when>
        <xsl:when test="$type = ('xs:anyAtomicType', 'item()')">any</xsl:when>
        <xsl:when test="$type = ('xs:dateTime', 'xs:date')">Date</xsl:when>
        <xsl:when test="$type = ('Int', 'double', 'xs:numeric', 'numeric', 'xs:decimal', 'xs:double', 'xs:unsignedLong', 'xs:int', 'xs:float', 'xs:integer', 'xs:long', 'xs:nonNegativeInteger', 'xs:positiveInteger', 'xs:unsignedInt')">number</xsl:when>
        <xsl:when test="matches($type, '^(schema-)?[Ee]lement\([^)]+\)$')">
          <xsl:choose>
            <!-- TODO: Can we perform generics on this? -->
            <xsl:when test="$isForParameter">MLNodeOrObject<any></xsl:when>
            <xsl:otherwise>MLNode<any></xsl:otherwise>
          </xsl:choose>
        </xsl:when>
        <xsl:otherwise>
          <xsl:variable name="local-name" select="replace($type, '^([^:.]+[:.])?([^\(\)]+)\(?\)?$', '$2')"/>
          <xsl:variable name="fixed-local-name" select="string-join(local:fixName($local-name), '')"/>
          <xsl:variable name="type-name" select="concat(upper-case(substring($fixed-local-name, 1, 1)), substring($fixed-local-name, 2))"/>
          <xsl:choose>
            <xsl:when test="contains($type, ':') or contains($type, '.')">
              <xsl:variable name="prefix-name" select="replace($type, '^([^:.]+[:.])?(.+)$', '$1')"/>
              <xsl:value-of select="concat(substring($prefix-name, 1, string-length($prefix-name) - 1), concat('.', $type-name))"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="$type-name"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:function>

    <xsl:function name="local:fixFunctionType">
      <xsl:param name="type"/>
      <xsl:param name="isArray"/>
      <xsl:text>(</xsl:text>
      <xsl:if test="matches($type, '^function\((.+)\)as(.+)$')">
        <xsl:value-of select="local:fixParameters(replace($type, '^function\((.+)\)as(.+)$', '$1'), 1)"/>
      </xsl:if>
      <xsl:text>)=></xsl:text>
      <xsl:variable name="returnType" select="local:fixType(replace($type, '^function\(.*\)as(.+)$', '$1'), false())"/>
      <xsl:choose>
        <xsl:when test="$isArray">
          <xsl:value-of select="local:fixArrayType($returnType, false())"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$returnType"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:function>

    <xsl:function name="local:fixParameters">
      <xsl:param name="parameters"/>
      <xsl:param name="number"/>
      <xsl:value-of select="concat(concat('p', $number), ':')"/>
      <xsl:variable name="type" select="substring-before(concat($parameters,','),',')"/>
      <xsl:value-of select="local:fixType($type, true())"/>
      <xsl:if test="contains($parameters, ',')">
        <xsl:value-of select="concat(',', string-join(local:fixParameters(substring-after($parameters, ','), $number + 1), ''))"/>
      </xsl:if>
    </xsl:function>

    <xsl:function name="local:fixName">
      <xsl:param name="name"/>

      <xsl:choose>
        <xsl:when test="$name = 'default'">defaultVal</xsl:when>
        <xsl:when test="$name = 'function'">functionArg</xsl:when>
        <xsl:when test="$name = 'in'">input</xsl:when>
        <xsl:when test="$name = 'else'">else_</xsl:when>
        <xsl:when test="$name = 'new'">new_</xsl:when>
        <xsl:when test="$name = 'class'">class_</xsl:when>
        <xsl:when test="$name = 'delete'">delete_</xsl:when>
        <xsl:otherwise>
          <xsl:analyze-string select="replace($name, ' ', '_')" regex="-([a-zA-Z])">

            <xsl:matching-substring>
              <xsl:value-of select="upper-case(regex-group(1))"/>
            </xsl:matching-substring>

            <xsl:non-matching-substring>
              <xsl:value-of select="translate(., '-', '')"/>
            </xsl:non-matching-substring>

          </xsl:analyze-string>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:function>

  </xsl:stylesheet>, $xml)

return $definition