config.xqm 6.29 KB
Newer Older
Mathias Goebel's avatar
Mathias Goebel committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
xquery version "3.1";

(:~
 : A set of helper functions to access the application context from
 : within a module.
 :)
module namespace config="http://textgrid.de/ns/SADE/config";

import module namespace config-params="http://exist-db.org/xquery/apps/config-params" at "config.xql";

declare namespace templates="http://exist-db.org/xquery/templates";
declare namespace repo="http://exist-db.org/xquery/repo";
declare namespace expkg="http://expath.org/ns/pkg";

Mathias Goebel's avatar
Mathias Goebel committed
15
(:
Mathias Goebel's avatar
Mathias Goebel committed
16
17
    Determine the application root collection from the current module load path.
:)
Mathias Goebel's avatar
Mathias Goebel committed
18
declare variable $config:app-root :=
Mathias Goebel's avatar
Mathias Goebel committed
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
    let $rawPath := system:get-module-load-path()
    let $modulePath :=
        (: strip the xmldb: part :)
        if (starts-with($rawPath, "xmldb:exist://")) then
            if (starts-with($rawPath, "xmldb:exist://embedded-eXist-server")) then
                substring($rawPath, 36)
            else
                substring($rawPath, 15)
        else
            $rawPath
    return
        substring-before($modulePath, "/modules")
;

declare variable $config:data-root := $config:app-root || "/data";

declare variable $config:repo-descriptor := doc(concat($config:app-root, "/repo.xml"))/repo:meta;

declare variable $config:expath-descriptor := doc(concat($config:app-root, "/expath-pkg.xml"))/expkg:package;

declare variable $config:projects-dir := $config-params:projects-dir;
(:~
 : Resolve the given path using the current application context.
 : If the app resides in the file system,
 :)
declare function config:resolve($relPath as xs:string) {
    if (starts-with($config:app-root, "/db")) then
        doc(concat($config:app-root, "/", $relPath))
    else
        doc(concat("file://", $config:app-root, "/", $relPath))
};

(:~
 : Returns the repo.xml descriptor for the current application.
 :)
declare function config:repo-descriptor() as element(repo:meta) {
    $config:repo-descriptor
};

(:~
 : Returns the expath-pkg.xml descriptor for the current application.
 :)
declare function config:expath-descriptor() as element(expkg:package) {
    $config:expath-descriptor
};

declare %templates:wrap function config:app-title($node as node(), $model as map(*)) as text() {
    $config:expath-descriptor/expkg:title/text()
};

declare function config:app-meta($node as node(), $model as map(*)) as element()* {
    <meta xmlns="http://www.w3.org/1999/xhtml" name="description" content="{$config:repo-descriptor/repo:description/text()}"/>,
    for $author in $config:repo-descriptor/repo:author
    return
        <meta xmlns="http://www.w3.org/1999/xhtml" name="creator" content="{$author/text()}"/>
};


declare variable $config:project :=
  let $value:= try { request:get-url() => substring-after("SADE/") => substring-before("/") } catch * { "textgrid" }
  return if($value="") then "textgrid" else $value;
declare variable $config:configDoc := doc( $config-params:projects-dir || $config:project || "/config.xml" );
declare variable $config:configMap := map:new(
82
                                for $param in $config:configDoc/config/*[./@key]
Mathias Goebel's avatar
Mathias Goebel committed
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
                                return map:entry(string($param/@key), string($param))
                            );

declare function config:get($key as xs:string) as xs:string {
let $return :=
    switch ($key)
        case "data-dir" return $config-params:projects-dir || $config:project || "/" || $config:configMap($key)
        case "project-dir" return $config-params:projects-dir || $config:project
        default return $config:configMap($key)

return
    if(string($return) != "")
    then $return
    else
        let $doc := doc( $config-params:projects-dir || $config:project || "/config.xml" )
Mathias Goebel's avatar
Mathias Goebel committed
98
        let $map := map:new(for $param in $doc/config/*[./@key] return map:entry(string($param/@key), string($param)))
Mathias Goebel's avatar
Mathias Goebel committed
99
100
101
102
103
104
105
106
107
108
109
110
111
        return
            switch ($key)
                case "data-dir" return $config-params:projects-dir || $config:project || "/" || $map($key)
                case "project-dir" return $config-params:projects-dir || $config:project
                default return $map($key)

};

declare function config:keys() {
    map:keys($config:configMap)
};

declare function config:module-get($module-name as xs:string, $key as xs:string) as item()? {
Mathias Goebel's avatar
Mathias Goebel committed
112
    let $module := $config:configDoc//*[string(@key)=$module-name]
Mathias Goebel's avatar
Mathias Goebel committed
113
114
115
116
117
    return
        $module/param[ string(@key)=$key ]/node()
};

declare function config:module-get($module-name as xs:string, $key as xs:string, $default as item()?) as item()? {
Mathias Goebel's avatar
Mathias Goebel committed
118
    let $value := config:module-get($module-name, $key)
Mathias Goebel's avatar
Mathias Goebel committed
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
    return if (empty($value)) then
            $default
        else
            $value
};

(:~ checks if there is a config-file for given project
 @author SADE-Team
 @param $project project identifier
:)
declare function config:project-exists($projectname as xs:string) as xs:boolean {
    let $project-config-path := $config-params:projects-dir || $project || "/config.xml"
       return doc-available($project-config-path)
};

(:~ lists all existing modules (i.e. present in the modules-collection) :)
declare function config:list-modules() {
    let $modules-dir := //expkg:package[@abbrev="SADE"]/base-uri() => replace("expath\-pkg\.xml", "modules/")
    return
       xmldb:get-child-collections($modules-dir)
};

(:~ lists all existing modules (i.e. present in the modules-collection) :)
declare function config:list-projects() as xs:string+ {
   xmldb:get-child-collections($config-params:projects-dir)
Mathias Goebel's avatar
Mathias Goebel committed
144
145
};

Mathias Goebel's avatar
Mathias Goebel committed
146
147
148
149
150
151
152
153
154
155
156
157
158
159
declare function local:mkcol-recursive($collection, $components) {
  if (exists($components)) then
    let $newColl := concat($collection, "/", $components[1])
    return
        if(xmldb:collection-available($newColl))
        then local:mkcol-recursive($newColl, subsequence($components, 2))
        else (
          xmldb:create-collection($collection, $components[1]),
          local:mkcol-recursive($newColl, subsequence($components, 2))
    )
  else
    ()
};
(: Helper function to recursively create a collection hierarchy. :)
Mathias Goebel's avatar
Mathias Goebel committed
160
declare function config:mkcol($path) {
Mathias Goebel's avatar
Mathias Goebel committed
161
162
163
164
165
166
167
  if(not(starts-with($path, "/")))
  then error(QName("error", "path"), "Invalid path. Absolute path required.")
  else
  if($path => matches("[^a-zA-Z0-9\-\.\+]"))
  then error(QName("error", "charset"), "Invalid path. use characters that match [a-zA-Z0-9\-\.\+] only.")
  else

Mathias Goebel's avatar
Mathias Goebel committed
168
    let $components := tokenize($path, "/")[.!=""]
Mathias Goebel's avatar
Mathias Goebel committed
169
170
    return
      local:mkcol-recursive($components[1], subsequence($components, 2))
Mathias Goebel's avatar
Mathias Goebel committed
171
};