isidorus-cvs
Threads by month
- ----- 2025 -----
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
November 2010
- 1 participants
- 23 discussions
Author: lgiessmann
Date: Sun Nov 21 16:03:08 2010
New Revision: 346
Log:
TM-SPARQL: added some unit-tests for parsing of literals => fixed some bugs
Modified:
trunk/src/TM-SPARQL/sparql_parser.lisp
trunk/src/unit_tests/sparql_test.lisp
Modified: trunk/src/TM-SPARQL/sparql_parser.lisp
==============================================================================
--- trunk/src/TM-SPARQL/sparql_parser.lisp (original)
+++ trunk/src/TM-SPARQL/sparql_parser.lisp Sun Nov 21 16:03:08 2010
@@ -193,8 +193,9 @@
(parse-literal-number-value trimmed-str query-object)))))
(list :next-query (getf value-type-lang-query :next-query)
:value (list :value (getf value-type-lang-query :value)
- :literal-type (getf value-type-lang-query :value)
- :type 'LITERAL))))
+ :literal-type (getf value-type-lang-query :type)
+ :type 'LITERAL
+ :literal-lang (getf value-type-lang-query :lang)))))
(defun parse-literal-string-value (query-string query-object)
@@ -209,12 +210,12 @@
(l-value (getf result-1 :literal))
(result-2 (separate-literal-lang-or-type
after-literal-value query-object))
- (l-type (getf result-2 :type))
- (l-lang (if (getf result-2 :lang)
- (getf result-2 :lang)
+ (l-type (if (getf result-2 :type)
+ (getf result-2 :type)
*xml-string*))
+ (l-lang (getf result-2 :lang))
(next-query (getf result-2 :next-query)))
- (list :next-query next-query :lang l-lang :type l-lang
+ (list :next-query next-query :lang l-lang :type l-type
:value (cast-literal l-value l-type))))
@@ -225,8 +226,8 @@
(cond ((string= literal-type *xml-string*)
literal-value)
((string= literal-type *xml-boolean*)
- (when (or (string/= literal-value "false")
- (string/= literal-value "true"))
+ (when (and (string/= literal-value "false")
+ (string/= literal-value "true"))
(error (make-condition
'sparql-parser-error
:message (format nil "Could not cast from ~a to ~a"
@@ -259,10 +260,14 @@
after the closing literal bounding."
(declare (String query-string)
(SPARQL-Query query-object))
- (let ((delimiters (list "." ";" "}" " " (string #\tab)
- (string #\newline))))
+ (let ((delimiters-1 (list "." ";" "}" " " (string #\tab)
+ (string #\newline)))
+ (delimiters-2 (list " ." ". " ";" "}" " " (string #\tab)
+ (string #\newline)
+ (concatenate 'string "." (string #\newline))
+ (concatenate 'string "." (string #\tab)))))
(cond ((string-starts-with query-string "@")
- (let ((end-pos (search-first delimiters
+ (let ((end-pos (search-first delimiters-1
(subseq query-string 1))))
(unless end-pos
(error (make-sparql-parser-condition
@@ -272,7 +277,7 @@
:lang (subseq (subseq query-string 1) 0 end-pos)
:type nil)))
((string-starts-with query-string "^^")
- (let ((end-pos (search-first delimiters (subseq query-string 2))))
+ (let ((end-pos (search-first delimiters-2 (subseq query-string 2))))
(unless end-pos
(error (make-sparql-parser-condition
query-string (original-query query-object)
@@ -282,9 +287,10 @@
(final-type (if (get-prefix query-object type-str)
(get-prefix query-object type-str)
type-str)))
- (list :next-query next-query :type final-type :lang nil))))
+ (list :next-query (cut-comment next-query)
+ :type final-type :lang nil))))
(t
- (list :next-query query-string :type nil :lang nil)))))
+ (list :next-query (cut-comment query-string) :type nil :lang nil)))))
(defun separate-literal-value (query-string query-object)
@@ -323,7 +329,7 @@
(find-literal-end (subseq query-string (+ current-pos
(length delimiter)))
delimiter (+ overall-pos current-pos 1))
- (+ overall-pos current-pos 1))
+ (+ overall-pos current-pos (length delimiter)))
nil)))
@@ -370,8 +376,9 @@
(not (base-value query-object)))
(getf result :value)
(concatenate-uri (base-value query-object)
- (getf result :value)))))
- (list :next-query (getf result :next-query)
+ (getf result :value))))
+ (next-query (getf result :next-query)))
+ (list :next-query next-query
:value (list :value result-uri :type 'IRI))))
Modified: trunk/src/unit_tests/sparql_test.lisp
==============================================================================
--- trunk/src/unit_tests/sparql_test.lisp (original)
+++ trunk/src/unit_tests/sparql_test.lisp Sun Nov 21 16:03:08 2010
@@ -15,7 +15,8 @@
:constants)
(:export :run-sparql-tests
:sparql-tests
- :test-prefix-and-base))
+ :test-prefix-and-base
+ :test-parse-literals))
(in-package :sparql-test)
@@ -152,18 +153,82 @@
(TM-SPARQL::variables query-object-3)))))
-;(test test-parse-literal-string-value
-; "Tests the helper function parse-literal-string-value."
-; (let ((query-1 " \"literal-value\"@de.")
-; (query-2 "true.")
-; (query-3 "false}")
-; (query-4 "1234.43e10")
-; (query-4 (concatenate 'string "'''true'''\"^^" *xml-boolean* " ;"))
-
-
- ;TODO: delimiter " ;" or " ."
- ;TODO: handle: subject predicate object; predicate object
-; )
+(test test-parse-literals
+ "Tests the helper functions for parsing literals."
+ (let ((query-1 " \"literal-value\"@de.")
+ (query-2 "true.")
+ (query-3 "false}")
+ (query-4 (concatenate 'string "1234.43e10" (string #\tab)))
+ (query-5 (concatenate 'string "'''true'''^^" *xml-boolean* " ;"))
+ (query-6 (concatenate 'string "'123.4'^^" *xml-double*
+ "." (string #\newline)))
+ (query-7 "\"Just a test
+
+literal with some \\\"quoted\\\" words!\"@en.")
+ (query-8 (concatenate 'string "'''12.4'''^^" *xml-integer* ". "))
+ (query-9 (concatenate 'string "\"13e4\"^^" *xml-boolean* " ."))
+ (dummy-object (make-instance 'SPARQL-Query :query "")))
+ (is-true dummy-object)
+ (let ((result (tm-sparql::parse-literal-elem query-1 dummy-object)))
+ (is (string= (getf result :next-query) "."))
+ (is (string= (getf (getf result :value) :value)
+ "literal-value"))
+ (is (string= (getf (getf result :value) :literal-lang)
+ "de"))
+ (is (string= (getf (getf result :value) :literal-type)
+ *xml-string*))
+ (is (eql (getf (getf result :value) :type) 'TM-SPARQL::LITERAL)))
+ (let ((result (tm-sparql::parse-literal-elem query-2 dummy-object)))
+ (is (string= (getf result :next-query) "."))
+ (is (eql (getf (getf result :value) :value) t))
+ (is-false (getf (getf result :value) :literal-lang))
+ (is (string= (getf (getf result :value) :literal-type)
+ *xml-boolean*))
+ (is (eql (getf (getf result :value) :type) 'TM-SPARQL::LITERAL)))
+ (let ((result (tm-sparql::parse-literal-elem query-3 dummy-object)))
+ (is (string= (getf result :next-query) "}"))
+ (is (eql (getf (getf result :value) :value) nil))
+ (is-false (getf (getf result :value) :literal-lang))
+ (is (string= (getf (getf result :value) :literal-type)
+ *xml-boolean*))
+ (is (eql (getf (getf result :value) :type) 'TM-SPARQL::LITERAL)))
+ (let ((result (tm-sparql::parse-literal-elem query-4 dummy-object)))
+ (is (string= (getf result :next-query) (string #\tab)))
+ (is (= (getf (getf result :value) :value) 1234.43e10))
+ (is-false (getf (getf result :value) :literal-lang))
+ (is (string= (getf (getf result :value) :literal-type)
+ *xml-double*))
+ (is (eql (getf (getf result :value) :type) 'TM-SPARQL::LITERAL)))
+ (let ((result (tm-sparql::parse-literal-elem query-5 dummy-object)))
+ (is (string= (getf result :next-query) ";"))
+ (is (eql (getf (getf result :value) :value) t))
+ (is-false (getf (getf result :value) :literal-lang))
+ (is (string= (getf (getf result :value) :literal-type)
+ *xml-boolean*))
+ (is (eql (getf (getf result :value) :type) 'TM-SPARQL::LITERAL)))
+ (let ((result (tm-sparql::parse-literal-elem query-6 dummy-object)))
+ (is (string= (getf result :next-query)
+ (concatenate 'string "." (string #\newline))))
+ (is (= (getf (getf result :value) :value) 123.4))
+ (is-false (getf (getf result :value) :literal-lang))
+ (is (string= (getf (getf result :value) :literal-type)
+ *xml-double*))
+ (is (eql (getf (getf result :value) :type) 'TM-SPARQL::LITERAL)))
+ (let ((result (tm-sparql::parse-literal-elem query-7 dummy-object)))
+ (is (string= (getf result :next-query) "."))
+ (is (string= (getf (getf result :value) :value)
+ "Just a test
+
+literal with some \\\"quoted\\\" words!"))
+ (is (string= (getf (getf result :value) :literal-lang)
+ "en"))
+ (is (string= (getf (getf result :value) :literal-type)
+ *xml-string*))
+ (is (eql (getf (getf result :value) :type) 'TM-SPARQL::LITERAL)))
+ (signals sparql-parser-error
+ (tm-sparql::parse-literal-elem query-8 dummy-object))
+ (signals sparql-parser-error
+ (tm-sparql::parse-literal-elem query-9 dummy-object))))
(defun run-sparql-tests ()
1
0
Author: lgiessmann
Date: Sun Nov 21 14:57:58 2010
New Revision: 345
Log:
TM-SPARQL: fixed a bug by calling the next function from a group-pattern
Modified:
trunk/src/TM-SPARQL/sparql_parser.lisp
trunk/src/unit_tests/sparql_test.lisp
Modified: trunk/src/TM-SPARQL/sparql_parser.lisp
==============================================================================
--- trunk/src/TM-SPARQL/sparql_parser.lisp (original)
+++ trunk/src/TM-SPARQL/sparql_parser.lisp Sun Nov 21 14:57:58 2010
@@ -23,6 +23,27 @@
(make-condition 'sparql-parser-error :message message)))
+(defun parse-closed-value(query-string query-object &key (open "<") (close ">"))
+ "A helper function that checks the value of a statement within
+ two brackets, i.e. <prefix-value>. A list of the
+ form (:next-query string :value string) is returned."
+ (declare (String query-string open close)
+ (SPARQL-Query query-object))
+ (let ((trimmed-string (cut-comment query-string)))
+ (if (string-starts-with trimmed-string open)
+ (let* ((pref-url (string-until (string-after trimmed-string open) close))
+ (next-query-str (string-after trimmed-string close)))
+ (unless next-query-str
+ (error (make-sparql-parser-condition
+ trimmed-string (original-query query-object)
+ close)))
+ (list :next-query next-query-str
+ :value pref-url))
+ (error (make-sparql-parser-condition
+ trimmed-string (original-query query-object)
+ close)))))
+
+
(defun cut-comment (query-string)
"Returns the given string back. If the query starts with a # or
space # the characters until the nextline are removed."
@@ -70,8 +91,8 @@
(unless (string-starts-with next-query "WHERE")
(error (make-sparql-parser-condition
next-query (original-query construct) "WHERE")))
- (let* ((tripples (string-after next-query "WHERE"))
- (query-tail (parse-where construct tripples)))
+ (let* ((triples (string-after next-query "WHERE"))
+ (query-tail (parse-where construct triples)))
(or query-tail) ;TODO: process tail-of query, e.g. order by, ...
construct))))
@@ -83,12 +104,15 @@
(unless (string-starts-with trimmed-str "{")
(error (make-sparql-parser-condition trimmed-str
(original-query construct) "{")))
- (parse-group construct (subseq trimmed-str 1) nil))))
+ (let ((query-tail (parse-group construct (subseq trimmed-str 1) nil nil)))
+ ;TODO: process query-tail
+ query-tail))))
-(defgeneric parse-group (construct query-string values)
+(defgeneric parse-group (construct query-string values filters)
(:documentation "The entry-point for the parsing of a {} statement.")
- (:method ((construct SPARQL-Query) (query-string String) (values List))
+ (:method ((construct SPARQL-Query) (query-string String)
+ (values List) (filters List))
(let ((trimmed-str (cut-comment query-string)))
(cond ((string-starts-with trimmed-str "BASE")
(parse-base construct (string-after trimmed-str "BASE")
@@ -96,26 +120,29 @@
((string-starts-with trimmed-str "{")
(error (make-sparql-parser-condition
trimmed-str (original-query construct)
- "FILTER, BASE, or tripple. Grouping is currently no implemented.")))
+ "FILTER, BASE, or triple. Grouping is currently no implemented.")))
((string-starts-with trimmed-str "FILTER")
- nil) ;TODO: implement => save the filters and call
- ;it after invoking parse-tripples
+ nil) ;TODO: call parse-group with added filter
((string-starts-with trimmed-str "OPTIONAL")
(error (make-sparql-parser-condition
trimmed-str (original-query construct)
- "FILTER, BASE, or tripple. Grouping is currently no implemented.")))
+ "FILTER, BASE, or triple. Grouping is currently no implemented.")))
((string-starts-with trimmed-str "UNION")
(error (make-sparql-parser-condition
trimmed-str (original-query construct)
- "FILTER, BASE, or tripple. Grouping is currently no implemented.")))
+ "FILTER, BASE, or triple. Grouping is currently no implemented.")))
((string-starts-with trimmed-str "}") ;ending of this group
+ ;TODO: invoke filters with all results
(subseq trimmed-str 1))
(t
- (parse-tripple construct trimmed-str values))))))
+ (let ((result (parse-triple construct trimmed-str values)))
+ (parse-group construct (getf result :next-query)
+ (getf result :values) filters)))))))
+
-(defun parse-tripple-elem (query-string query-object &key (literal-allowed nil))
- "A helper function to parse a subject or predicate of an RDF tripple.
+(defun parse-triple-elem (query-string query-object &key (literal-allowed nil))
+ "A helper function to parse a subject or predicate of an RDF triple.
Returns an entry of the form (:value (:value string :type <'VAR|'IRI|'LITERAL>)
:next-query string)."
(declare (String query-string)
@@ -188,7 +215,7 @@
*xml-string*))
(next-query (getf result-2 :next-query)))
(list :next-query next-query :lang l-lang :type l-lang
- :value (cast-literal l-value l-type query-object))))
+ :value (cast-literal l-value l-type))))
(defun cast-literal (literal-value literal-type)
@@ -232,10 +259,10 @@
after the closing literal bounding."
(declare (String query-string)
(SPARQL-Query query-object))
- (let ((delimiters (list " ." ". " ";" "}" " " (string #\tab)
+ (let ((delimiters (list "." ";" "}" " " (string #\tab)
(string #\newline))))
(cond ((string-starts-with query-string "@")
- (let ((end-pos (search-first (append delimiters (list "."))
+ (let ((end-pos (search-first delimiters
(subseq query-string 1))))
(unless end-pos
(error (make-sparql-parser-condition
@@ -303,19 +330,19 @@
(defun parse-literal-number-value (query-string query-object)
"A helper function that parses any number that is a literal.
The return value is of the form
- (list :value nil :type string :pos int)."
+ (list :value nil :type string :next-query string."
(declare (String query-string)
(SPARQL-Query query-object))
(let* ((trimmed-str (cut-comment query-string))
(triple-delimiters
- (list ". " ". " ";" " " (string #\tab)
+ (list ". " ";" " " (string #\tab)
(string #\newline) "}"))
(end-pos (search-first triple-delimiters
trimmed-str)))
(unless end-pos
(error (make-sparql-parser-condition
trimmed-str (original-query query-object)
- "'. ', ' .', ';' ' ', '\\t', '\\n' or '}'")))
+ "'. ', , ';' ' ', '\\t', '\\n' or '}'")))
(let* ((literal-number
(read-from-string (subseq trimmed-str 0 end-pos)))
(number-type
@@ -374,53 +401,39 @@
:type 'IRI))))
-(defgeneric parse-tripple (construct query-string values)
- (:documentation "Parses a tripple within a trippel group and returns a
+(defgeneric parse-triple (construct query-string values &key last-subject)
+ (:documentation "Parses a triple within a trippel group and returns a
a list of the form (:next-query :subject (:type <'VAR|'IRI>
:value string) :predicate (:type <'VAR|'IRI> :value string)
:object (:type <'VAR|'IRI|'LITERAL> :value string)).")
- (:method ((construct SPARQL-Query) (query-string String) (values List))
+ (:method ((construct SPARQL-Query) (query-string String) (values List)
+ &key (last-subject nil))
+ (declare (List last-subject))
(let* ((trimmed-str (cut-comment query-string))
- (subject
- (let ((result (parse-tripple-elem trimmed-str construct)))
- (setf trimmed-str (getf result :next-query))
- (getf result :value)))
- (predicate
- (let ((result (parse-tripple-elem trimmed-str construct)))
- (setf trimmed-str (getf result :next-query))
- (getf result :value)))
- (object
- (let ((result (parse-tripple-elem trimmed-str construct
- :literal-allowed t)))
- (setf trimmed-str (getf result :next-query))
- (getf result :value))))
- (or subject object predicate);;TODO: implement
- ;; 0) ; => use last subject
- ;; 1) search for <url> => if full-url use it otherwise set bse
- ;; 2) search for label:suffix
- ;; 3) varname => ?|$
- ;; 4) literal => only the object
-
- ;; => BASE is also allowed
- ;; => ;-shortcut
-
- ;; <full-url>
- ;; <base-suffix>
- ;; label:pref-suffix
- ;; ?var
- ;; $var
- ;; "literal"
- ;; 'literal'
- ;; "literal"@language
- ;; "literal"^^type
- ;; '''"literal"'''
- ;; 1, which is the same as "1"^^xsd:integer
- ;; 1.3, which is the same as "1.3"^^xsd:decimal
- ;; 1.300, which is the same as "1.300"^^xsd:decimal
- ;; 1.0e6, which is the same as "1.0e6"^^xsd:double
- ;; true, which is the same as "true"^^xsd:boolean
- ;; false, which is the same as "false"^^xsd:boolean
- )))
+ (subject-result (if last-subject ;;is used after a ";"
+ last-subject
+ (parse-triple-elem trimmed-str construct)))
+ (predicate-result (parse-triple-elem
+ (if last-subject
+ trimmed-str
+ (getf subject-result :next-query))
+ construct))
+ (object-result (parse-triple-elem (getf predicate-result :next-query)
+ construct :literal-allowed t))
+ (all-values (append values
+ (list :subject (getf subject-result :value)
+ :predicate (getf predicate-result :value)
+ :object (getf object-result :value)))))
+ (let ((tr-str (cut-comment (getf object-result :next-query))))
+ (cond ((string-starts-with tr-str ";")
+ (parse-triple construct (subseq tr-str 1) all-values
+ :last-subject (list :value
+ (getf subject-result :value))))
+ ((string-starts-with tr-str ".")
+ (parse-triple construct (subseq tr-str 1) all-values))
+ ((string-starts-with tr-str "}") ;no other triples follows
+ (list :next-query tr-str
+ :values all-values)))))))
(defgeneric parse-variables (construct query-string)
@@ -498,25 +511,4 @@
(error (make-sparql-parser-condition
trimmed-string (original-query construct) ":")))
(add-prefix construct label-name (getf results :value))
- (parser-start construct (getf results :next-query)))))))
-
-
-(defun parse-closed-value(query-string query-object &key (open "<") (close ">"))
- "A helper function that checks the value of a statement within
- two brackets, i.e. <prefix-value>. A list of the
- form (:next-query string :value string) is returned."
- (declare (String query-string open close)
- (SPARQL-Query query-object))
- (let ((trimmed-string (cut-comment query-string)))
- (if (string-starts-with trimmed-string open)
- (let* ((pref-url (string-until (string-after trimmed-string open) close))
- (next-query-str (string-after trimmed-string close)))
- (unless next-query-str
- (error (make-sparql-parser-condition
- trimmed-string (original-query query-object)
- close)))
- (list :next-query next-query-str
- :value pref-url))
- (error (make-sparql-parser-condition
- trimmed-string (original-query query-object)
- close)))))
\ No newline at end of file
+ (parser-start construct (getf results :next-query)))))))
\ No newline at end of file
Modified: trunk/src/unit_tests/sparql_test.lisp
==============================================================================
--- trunk/src/unit_tests/sparql_test.lisp (original)
+++ trunk/src/unit_tests/sparql_test.lisp Sun Nov 21 14:57:58 2010
@@ -11,7 +11,8 @@
(:use :cl
:it.bese.FiveAM
:TM-SPARQL
- :exceptions)
+ :exceptions
+ :constants)
(:export :run-sparql-tests
:sparql-tests
:test-prefix-and-base))
@@ -151,5 +152,19 @@
(TM-SPARQL::variables query-object-3)))))
+;(test test-parse-literal-string-value
+; "Tests the helper function parse-literal-string-value."
+; (let ((query-1 " \"literal-value\"@de.")
+; (query-2 "true.")
+; (query-3 "false}")
+; (query-4 "1234.43e10")
+; (query-4 (concatenate 'string "'''true'''\"^^" *xml-boolean* " ;"))
+
+
+ ;TODO: delimiter " ;" or " ."
+ ;TODO: handle: subject predicate object; predicate object
+; )
+
+
(defun run-sparql-tests ()
(it.bese.fiveam:run! 'sparql-test:sparql-tests))
\ No newline at end of file
1
0

[isidorus-cvs] r344 - in trunk/src: . TM-SPARQL base-tools unit_tests xml/rdf xml/xtm
by Lukas Giessmann 21 Nov '10
by Lukas Giessmann 21 Nov '10
21 Nov '10
Author: lgiessmann
Date: Sun Nov 21 13:16:32 2010
New Revision: 344
Log:
TM-SAPRQL: added the parsing of tripples in the SELECT-WHERE statement
Modified:
trunk/src/TM-SPARQL/sparql.lisp
trunk/src/TM-SPARQL/sparql_parser.lisp
trunk/src/base-tools/base-tools.lisp
trunk/src/constants.lisp
trunk/src/isidorus.asd
trunk/src/unit_tests/sparql_test.lisp
trunk/src/xml/rdf/rdf_tools.lisp
trunk/src/xml/xtm/importer.lisp
trunk/src/xml/xtm/tools.lisp
Modified: trunk/src/TM-SPARQL/sparql.lisp
==============================================================================
--- trunk/src/TM-SPARQL/sparql.lisp (original)
+++ trunk/src/TM-SPARQL/sparql.lisp Sun Nov 21 13:16:32 2010
@@ -8,7 +8,7 @@
;;+-----------------------------------------------------------------------------
(defpackage :TM-SPARQL
- (:use :cl :datamodel :base-tools :exceptions)
+ (:use :cl :datamodel :base-tools :exceptions :constants)
(:export :SPARQL-Query))
@@ -16,8 +16,20 @@
(defvar *empty-label* "_empty_label_symbol")
+(defclass Variable-Container ()
+ ((variables :initarg :variables
+ :accessor variables ;this value is only for internal purposes
+ ;purposes and mustn't be reset
+ :type List
+ :initform nil
+ :documentation "A list of the form ((:variable var-name
+ :value value-object)), that contains tuples
+ for each variable and its result."))
+ (:documentation "This class is used to store all variable in a WHERE{}
+ statement"))
-(defclass SPARQL-Query ()
+
+(defclass SPARQL-Query (Variable-Container)
((original-query :initarg :query
:accessor original-query ;this value is only for internal
;purposes and mustn't be reset
@@ -40,22 +52,15 @@
:type String
:initform nil
:documentation "Contains the last set base-value.")
- (variables :initarg :variables
- :accessor variables ;this value is only for internal purposes
- ;purposes and mustn't be reset
- :type List
- :initform nil
- :documentation "A list of the form ((:variable var-name
- :value value-object)), that contains tuples
- for each variable and its result.")
(select-statements :initarg :select-statements
:accessor select-statements ;this value is only for
;internal purposes purposes
;and mustn't be reset
- :type List
+ :type List
:initform nil
:documentation "A list of the form ((:statement 'statement'
- :value value-object))")))
+ :value value-object))"))
+ (:documentation "This class represents the entire request."))
(defgeneric add-prefix (construct prefix-label prefix-value)
@@ -73,12 +78,26 @@
(prefixes construct))))))
+(defgeneric get-prefix (construct string-with-prefix)
+ (:documentation "Returns the URL corresponding to the found prefix-label
+ followed by : and the variable. Otherwise the return
+ value is nil.")
+ (:method ((construct SPARQL-query) (string-with-prefix String))
+ (loop for entry in (prefixes construct)
+ when (string-starts-with string-with-prefix
+ (concatenate 'string (getf entry :label) ":"))
+ return (concatenate
+ 'string (getf entry :value) ":"
+ (string-after string-with-prefix
+ (concatenate 'string (getf entry :label) ":"))))))
+
+
(defgeneric add-variable (construct variable-name variable-value)
(:documentation "Adds a new variable-name with its value to the aexisting list.
If a variable-already exists the existing entry will be
overwritten. An entry is of the form
(:variable string :value any-type).")
- (:method ((construct SPARQL-Query) (variable-name String) variable-value)
+ (:method ((construct Variable-Container) (variable-name String) variable-value)
(let ((existing-tuple
(find-if #'(lambda(x)
(string= (getf x :variable) variable-name))
Modified: trunk/src/TM-SPARQL/sparql_parser.lisp
==============================================================================
--- trunk/src/TM-SPARQL/sparql_parser.lisp (original)
+++ trunk/src/TM-SPARQL/sparql_parser.lisp Sun Nov 21 13:16:32 2010
@@ -23,10 +23,23 @@
(make-condition 'sparql-parser-error :message message)))
+(defun cut-comment (query-string)
+ "Returns the given string back. If the query starts with a # or
+ space # the characters until the nextline are removed."
+ (declare (String query-string))
+ (let ((trimmed-str (trim-whitespace-left query-string)))
+ (if (string-starts-with trimmed-str "#")
+ (let ((next-query (string-after trimmed-str (string #\newline))))
+ (if next-query
+ next-query
+ ""))
+ trimmed-str)))
+
+
(defgeneric parser-start(construct query-string)
(:documentation "The entry point of the SPARQL-parser.")
(:method ((construct SPARQL-Query) (query-string String))
- (let ((trimmed-query-string (trim-whitespace-left query-string)))
+ (let ((trimmed-query-string (cut-comment query-string)))
(cond ((string-starts-with trimmed-query-string "SELECT")
(parse-select
construct (string-after trimmed-query-string "SELECT")))
@@ -50,7 +63,7 @@
(:documentation "The entry-point of the parsing of the select - where
statement.")
(:method ((construct SPARQL-Query) (query-string String))
- (let* ((trimmed-str (trim-whitespace-left query-string))
+ (let* ((trimmed-str (cut-comment query-string))
(next-query (if (string-starts-with trimmed-str "WHERE")
trimmed-str
(parse-variables construct trimmed-str))))
@@ -66,19 +79,363 @@
(defgeneric parse-where (construct query-string)
(:documentation "The entry-point for the parsing of the WHERE statement.")
(:method ((construct SPARQL-Query) (query-string String))
- ))
+ (let ((trimmed-str (cut-comment query-string)))
+ (unless (string-starts-with trimmed-str "{")
+ (error (make-sparql-parser-condition trimmed-str
+ (original-query construct) "{")))
+ (parse-group construct (subseq trimmed-str 1) nil))))
+
+
+(defgeneric parse-group (construct query-string values)
+ (:documentation "The entry-point for the parsing of a {} statement.")
+ (:method ((construct SPARQL-Query) (query-string String) (values List))
+ (let ((trimmed-str (cut-comment query-string)))
+ (cond ((string-starts-with trimmed-str "BASE")
+ (parse-base construct (string-after trimmed-str "BASE")
+ #'parse-where))
+ ((string-starts-with trimmed-str "{")
+ (error (make-sparql-parser-condition
+ trimmed-str (original-query construct)
+ "FILTER, BASE, or tripple. Grouping is currently no implemented.")))
+ ((string-starts-with trimmed-str "FILTER")
+ nil) ;TODO: implement => save the filters and call
+ ;it after invoking parse-tripples
+ ((string-starts-with trimmed-str "OPTIONAL")
+ (error (make-sparql-parser-condition
+ trimmed-str (original-query construct)
+ "FILTER, BASE, or tripple. Grouping is currently no implemented.")))
+ ((string-starts-with trimmed-str "UNION")
+ (error (make-sparql-parser-condition
+ trimmed-str (original-query construct)
+ "FILTER, BASE, or tripple. Grouping is currently no implemented.")))
+ ((string-starts-with trimmed-str "}") ;ending of this group
+ (subseq trimmed-str 1))
+ (t
+ (parse-tripple construct trimmed-str values))))))
+
+
+(defun parse-tripple-elem (query-string query-object &key (literal-allowed nil))
+ "A helper function to parse a subject or predicate of an RDF tripple.
+ Returns an entry of the form (:value (:value string :type <'VAR|'IRI|'LITERAL>)
+ :next-query string)."
+ (declare (String query-string)
+ (SPARQL-Query query-object)
+ (Boolean literal-allowed))
+ (let ((trimmed-str (cut-comment query-string)))
+ (cond ((string-starts-with trimmed-str "<")
+ (parse-base-suffix-pair trimmed-str query-object))
+ ((or (string-starts-with trimmed-str "?")
+ (string-starts-with trimmed-str "$"))
+ (let ((result (parse-variable-name trimmed-str query-object)))
+ (list :next-query (getf result :next-query)
+ :value (list :value (getf result :value)
+ :type 'VAR))))
+ (t
+ (if (or (string-starts-with-digit trimmed-str)
+ (string-starts-with trimmed-str "\"")
+ (string-starts-with trimmed-str "true")
+ (string-starts-with trimmed-str "false")
+ (string-starts-with trimmed-str "'"))
+ (progn
+ (unless literal-allowed
+ (error (make-sparql-parser-condition
+ trimmed-str (original-query query-object)
+ "an IRI of the form prefix:suffix or <iri> but found a literal.")))
+ (parse-literal-elem trimmed-str query-object))
+ (parse-prefix-suffix-pair trimmed-str query-object))))))
+
+
+(defun parse-literal-elem (query-string query-object)
+ "A helper-function that returns a literal vaue of the form
+ (:value (:value object :literal-type string :literal-lang
+ string :type <'LITERAL>) :next-query string)."
+ (declare (String query-string)
+ (SPARQL-Query query-object))
+ (let* ((trimmed-str (cut-comment query-string))
+ (value-type-lang-query
+ (cond ((or (string-starts-with trimmed-str "\"")
+ (string-starts-with trimmed-str "'"))
+ (parse-literal-string-value trimmed-str query-object))
+ ((string-starts-with trimmed-str "true")
+ (list :value t :type *xml-boolean*
+ :next-query (subseq trimmed-str (length "true"))))
+ ((string-starts-with trimmed-str "false")
+ (list :value nil :type *xml-boolean*
+ :next-query (subseq trimmed-str (length "false"))))
+ ((string-starts-with-digit trimmed-str)
+ (parse-literal-number-value trimmed-str query-object)))))
+ (list :next-query (getf value-type-lang-query :next-query)
+ :value (list :value (getf value-type-lang-query :value)
+ :literal-type (getf value-type-lang-query :value)
+ :type 'LITERAL))))
+
+
+(defun parse-literal-string-value (query-string query-object)
+ "A helper function that parses a string that is a literal.
+ The return value is of the form
+ (list :value object :type string :lang string :next-query string)."
+ (declare (String query-string)
+ (SPARQL-Query query-object))
+ (let* ((trimmed-str (cut-comment query-string))
+ (result-1 (separate-literal-value trimmed-str query-object))
+ (after-literal-value (getf result-1 :next-query))
+ (l-value (getf result-1 :literal))
+ (result-2 (separate-literal-lang-or-type
+ after-literal-value query-object))
+ (l-type (getf result-2 :type))
+ (l-lang (if (getf result-2 :lang)
+ (getf result-2 :lang)
+ *xml-string*))
+ (next-query (getf result-2 :next-query)))
+ (list :next-query next-query :lang l-lang :type l-lang
+ :value (cast-literal l-value l-type query-object))))
+
+
+(defun cast-literal (literal-value literal-type)
+ "A helper function that casts the passed string value of the literal
+ corresponding to the passed literal-type."
+ (declare (String literal-value literal-type))
+ (cond ((string= literal-type *xml-string*)
+ literal-value)
+ ((string= literal-type *xml-boolean*)
+ (when (or (string/= literal-value "false")
+ (string/= literal-value "true"))
+ (error (make-condition
+ 'sparql-parser-error
+ :message (format nil "Could not cast from ~a to ~a"
+ literal-value literal-type))))
+ (if (string= literal-value "false")
+ nil
+ t))
+ ((string= literal-type *xml-integer*)
+ (handler-case (parse-integer literal-value)
+ (condition ()
+ (error (make-condition
+ 'sparql-parser-error
+ :message (format nil "Could not cast from ~a to ~a"
+ literal-value literal-type))))))
+ ((or (string= literal-type *xml-decimal*) ;;both types are
+ (string= literal-type *xml-double*)) ;;handled the same way
+ (let ((value (read-from-string literal-value)))
+ (unless (numberp value)
+ (error (make-condition
+ 'sparql-parser-error
+ :message (format nil "Could not cast from ~a to ~a"
+ literal-value literal-type))))
+ value))))
+
+
+(defun separate-literal-lang-or-type (query-string query-object)
+ "A helper function that returns (:next-query string :lang string
+ :type string). Only one of :lang and :type can be set, the other
+ element is set to nil. The query string must be the string direct
+ after the closing literal bounding."
+ (declare (String query-string)
+ (SPARQL-Query query-object))
+ (let ((delimiters (list " ." ". " ";" "}" " " (string #\tab)
+ (string #\newline))))
+ (cond ((string-starts-with query-string "@")
+ (let ((end-pos (search-first (append delimiters (list "."))
+ (subseq query-string 1))))
+ (unless end-pos
+ (error (make-sparql-parser-condition
+ query-string (original-query query-object)
+ "'.', ';', '}', ' ', '\t', or '\n'")))
+ (list :next-query (subseq (subseq query-string 1) end-pos)
+ :lang (subseq (subseq query-string 1) 0 end-pos)
+ :type nil)))
+ ((string-starts-with query-string "^^")
+ (let ((end-pos (search-first delimiters (subseq query-string 2))))
+ (unless end-pos
+ (error (make-sparql-parser-condition
+ query-string (original-query query-object)
+ "'. ', ,' .', ';', '}', ' ', '\t', or '\n'")))
+ (let* ((type-str (subseq (subseq query-string 2) 0 end-pos))
+ (next-query (subseq (subseq query-string 2) end-pos))
+ (final-type (if (get-prefix query-object type-str)
+ (get-prefix query-object type-str)
+ type-str)))
+ (list :next-query next-query :type final-type :lang nil))))
+ (t
+ (list :next-query query-string :type nil :lang nil)))))
+
+
+(defun separate-literal-value (query-string query-object)
+ "A helper function that returns (:next-query string :literal string).
+ The literal string contains the pure literal value."
+ (declare (String query-string)
+ (SPARQL-Query query-object))
+ (let* ((trimmed-str (cut-comment query-string))
+ (delimiter (cond ((string-starts-with trimmed-str "\"")
+ "\"")
+ ((string-starts-with trimmed-str "'''")
+ "'''")
+ ((string-starts-with trimmed-str "'")
+ "'")
+ (t
+ (error (make-sparql-parser-condition
+ trimmed-str (original-query query-object)
+ "a literal starting with ', ''', or \"")))))
+ (literal-end (find-literal-end (subseq trimmed-str (length delimiter))
+ delimiter 0)))
+ (list :next-query (subseq trimmed-str (+ literal-end (length delimiter)))
+ :literal (subseq trimmed-str (length delimiter) literal-end))))
+
+
+(defun find-literal-end (query-string delimiter &optional (overall-pos 0))
+ "Returns the end of the literal corresponding to the passed delimiter
+ string. The query-string must start after the opening literal delimiter.
+ The return value is an int that represents the start index of closing
+ delimiter. delimiter must be either \", ', or '''.
+ If the returns value is nil, there is no closing delimiter."
+ (declare (String query-string delimiter)
+ (Integer overall-pos))
+ (let ((current-pos (search delimiter query-string)))
+ (if current-pos
+ (if (string-ends-with (subseq query-string 0 current-pos) "\\")
+ (find-literal-end (subseq query-string (+ current-pos
+ (length delimiter)))
+ delimiter (+ overall-pos current-pos 1))
+ (+ overall-pos current-pos 1))
+ nil)))
+
+
+(defun parse-literal-number-value (query-string query-object)
+ "A helper function that parses any number that is a literal.
+ The return value is of the form
+ (list :value nil :type string :pos int)."
+ (declare (String query-string)
+ (SPARQL-Query query-object))
+ (let* ((trimmed-str (cut-comment query-string))
+ (triple-delimiters
+ (list ". " ". " ";" " " (string #\tab)
+ (string #\newline) "}"))
+ (end-pos (search-first triple-delimiters
+ trimmed-str)))
+ (unless end-pos
+ (error (make-sparql-parser-condition
+ trimmed-str (original-query query-object)
+ "'. ', ' .', ';' ' ', '\\t', '\\n' or '}'")))
+ (let* ((literal-number
+ (read-from-string (subseq trimmed-str 0 end-pos)))
+ (number-type
+ (if (search "." (subseq trimmed-str 0 end-pos))
+ *xml-double* ;could also be an xml:decimal, since the doucble has
+ ;a bigger range it shouldn't matter
+ *xml-integer*)))
+ (unless (numberp literal-number)
+ (error (make-sparql-parser-condition
+ trimmed-str (original-query query-object)
+ "a valid number of the form '1', '1.3', 1.0e6'")))
+ (list :value literal-number :type number-type
+ :next-query (subseq trimmed-str end-pos)))))
+
+
+(defun parse-base-suffix-pair (query-string query-object)
+ "A helper function that returns a list of the form
+ (list :next-query string :value (:value uri :type 'IRI))."
+ (declare (String query-string)
+ (SPARQL-Query query-object))
+ (let* ((trimmed-str (cut-comment query-string))
+ (result (parse-closed-value trimmed-str query-object))
+ (result-uri
+ (if (or (absolute-uri-p (getf result :value))
+ (not (base-value query-object)))
+ (getf result :value)
+ (concatenate-uri (base-value query-object)
+ (getf result :value)))))
+ (list :next-query (getf result :next-query)
+ :value (list :value result-uri :type 'IRI))))
+
+
+(defun parse-prefix-suffix-pair(query-string query-object)
+ "A helper function that returns a list of the form
+ (list :next-query string :value (:value uri :type 'IRI))."
+ (declare (String query-string)
+ (SPARQL-Query query-object))
+ (let* ((trimmed-str (cut-comment query-string))
+ (delimiters (list "." ";" "}" "<" " " (string #\newline)
+ (string #\tab) "#"))
+ (end-pos (search-first delimiters trimmed-str))
+ (elem-str (when end-pos
+ (subseq trimmed-str 0 end-pos)))
+ (prefix (when elem-str
+ (string-until elem-str ":")))
+ (suffix (when prefix
+ (string-after elem-str ":"))))
+ (unless (and end-pos prefix suffix)
+ (error (make-sparql-parser-condition
+ trimmed-str (original-query query-object)
+ "An IRI of the form prefix:suffix")))
+ (list :next-query (string-after
+ trimmed-str
+ (concatenate 'string prefix ":" suffix))
+ :value (list :value (concatenate 'string prefix ":" suffix)
+ :type 'IRI))))
+
+
+(defgeneric parse-tripple (construct query-string values)
+ (:documentation "Parses a tripple within a trippel group and returns a
+ a list of the form (:next-query :subject (:type <'VAR|'IRI>
+ :value string) :predicate (:type <'VAR|'IRI> :value string)
+ :object (:type <'VAR|'IRI|'LITERAL> :value string)).")
+ (:method ((construct SPARQL-Query) (query-string String) (values List))
+ (let* ((trimmed-str (cut-comment query-string))
+ (subject
+ (let ((result (parse-tripple-elem trimmed-str construct)))
+ (setf trimmed-str (getf result :next-query))
+ (getf result :value)))
+ (predicate
+ (let ((result (parse-tripple-elem trimmed-str construct)))
+ (setf trimmed-str (getf result :next-query))
+ (getf result :value)))
+ (object
+ (let ((result (parse-tripple-elem trimmed-str construct
+ :literal-allowed t)))
+ (setf trimmed-str (getf result :next-query))
+ (getf result :value))))
+ (or subject object predicate);;TODO: implement
+ ;; 0) ; => use last subject
+ ;; 1) search for <url> => if full-url use it otherwise set bse
+ ;; 2) search for label:suffix
+ ;; 3) varname => ?|$
+ ;; 4) literal => only the object
+
+ ;; => BASE is also allowed
+ ;; => ;-shortcut
+
+ ;; <full-url>
+ ;; <base-suffix>
+ ;; label:pref-suffix
+ ;; ?var
+ ;; $var
+ ;; "literal"
+ ;; 'literal'
+ ;; "literal"@language
+ ;; "literal"^^type
+ ;; '''"literal"'''
+ ;; 1, which is the same as "1"^^xsd:integer
+ ;; 1.3, which is the same as "1.3"^^xsd:decimal
+ ;; 1.300, which is the same as "1.300"^^xsd:decimal
+ ;; 1.0e6, which is the same as "1.0e6"^^xsd:double
+ ;; true, which is the same as "true"^^xsd:boolean
+ ;; false, which is the same as "false"^^xsd:boolean
+ )))
(defgeneric parse-variables (construct query-string)
(:documentation "Parses the variables of the SELECT statement
and adds them to the passed construct.")
(:method ((construct SPARQL-Query) (query-string String))
- (let ((trimmed-str (trim-whitespace-left query-string)))
+ (let ((trimmed-str (cut-comment query-string)))
(if (string-starts-with trimmed-str "WHERE")
trimmed-str
- (let ((result (parse-variable-name trimmed-str construct)))
- (add-variable construct (getf result :value) nil)
- (parse-variables construct (getf result :next-query)))))))
+ (if (string-starts-with trimmed-str "*")
+ (progn (add-variable construct "*" nil)
+ (parse-variables construct (string-after trimmed-str "*")))
+ (let ((result (parse-variable-name trimmed-str construct)))
+ (add-variable construct (getf result :value) nil)
+ (parse-variables construct (getf result :next-query))))))))
(defun parse-variable-name (query-string query-object)
@@ -88,19 +445,19 @@
(:next-query string :value string)."
(declare (String query-string)
(SPARQL-Query query-object))
- (let ((trimmed-str (trim-whitespace-left query-string))
- (delimiters (list " " "?" "$" (string #\newline) (string #\tab))))
+ (let ((trimmed-str (cut-comment query-string))
+ (delimiters (list " " "?" "$" "." (string #\newline) (string #\tab))))
(unless (or (string-starts-with trimmed-str "?")
(string-starts-with trimmed-str "$"))
- (make-sparql-parser-condition
- trimmed-str (original-query query-object) "? or $"))
+ (error (make-sparql-parser-condition
+ trimmed-str (original-query query-object) "? or $")))
(let* ((var-name-end (search-first delimiters (subseq trimmed-str 1)))
(var-name
(if var-name-end
(subseq trimmed-str 0 (+ 1 var-name-end))
(error (make-sparql-parser-condition
trimmed-str (original-query query-object)
- "space, newline, tab, ?, $ or WHERE"))))
+ "space, newline, tab, ?, ., $ or WHERE"))))
(next-query (string-after trimmed-str var-name))
(normalized-var-name
(if (<= (length var-name) 1)
@@ -117,7 +474,7 @@
may appear in different states the next-fun defines the next
call function that calls the next transitions and states.")
(:method ((construct SPARQL-Query) (query-string String) (next-fun Function))
- (let* ((trimmed-str (trim-whitespace-left query-string))
+ (let* ((trimmed-str (cut-comment query-string))
(result (parse-closed-value trimmed-str construct)))
(setf (base-value construct) (getf result :value))
(funcall next-fun construct (getf result :next-query)))))
@@ -126,7 +483,7 @@
(defgeneric parse-prefixes (construct query-string)
(:documentation "Sets the correponding prefix-tuples in the passed object.")
(:method ((construct SPARQL-Query) (query-string String))
- (let ((trimmed-string (trim-whitespace-left query-string)))
+ (let ((trimmed-string (cut-comment query-string)))
(if (string-starts-with trimmed-string ":")
(let ((results
(parse-closed-value (subseq trimmed-string 1) construct)))
@@ -150,7 +507,7 @@
form (:next-query string :value string) is returned."
(declare (String query-string open close)
(SPARQL-Query query-object))
- (let ((trimmed-string (trim-whitespace-left query-string)))
+ (let ((trimmed-string (cut-comment query-string)))
(if (string-starts-with trimmed-string open)
(let* ((pref-url (string-until (string-after trimmed-string open) close))
(next-query-str (string-after trimmed-string close)))
@@ -162,43 +519,4 @@
:value pref-url))
(error (make-sparql-parser-condition
trimmed-string (original-query query-object)
- close)))))
-
-
-
-;((PREFIX bounding: <uri-prefix>)|(PREFIX : <uri-prefix>)*
-;(BASE <base-uri>)*)*
-;SELECT ?varName+
-;WHERE {
-;(({?subjectOrVarName predicateOrVarName objectOrVarName}?)*
-;({?FILTER (filterExpression)}?)*
-;(BASE <base-uri>)*)*
-;}
-;Grouping
-;{}
-;Base
-;BASE <uri>
-;…
-;<book>
-;-> uri/book
-;Literals
-;(“anyCharacter*“)|(‘anyCharacter*‘)((anyUri)|(@languageTag)){0,1}
-;
-;Variables
-;($anyChar*)|(?anyChar*)
-;?var = $var
-;Predicate object-lists
-;?x foaf:name ?name ;
-;foaf:mbox ?mbox .
-;This is the same as writing the triple patterns:
-;?x foaf:name ?name .
-;?x foaf:mbox ?mbox .
-;rdf:type
-;rdf:type = a
-;Empty Graph Pattern
-;The group pattern:
-;{ }
-;matches any graph (including the empty graph) with one solution that does not bind any variables. For example:
-;SELECT ?x
-;WHERE {}
-;matches with one solution in which variable x is not bound."
\ No newline at end of file
+ close)))))
\ No newline at end of file
Modified: trunk/src/base-tools/base-tools.lisp
==============================================================================
--- trunk/src/base-tools/base-tools.lisp (original)
+++ trunk/src/base-tools/base-tools.lisp Sun Nov 21 13:16:32 2010
@@ -18,10 +18,14 @@
:trim-whitespace-right
:trim-whitespace
:string-starts-with
+ :string-ends-with
:string-starts-with-char
:string-until
:string-after
- :search-first))
+ :search-first
+ :concatenate-uri
+ :absolute-uri-p
+ :string-starts-with-digit))
(in-package :base-tools)
@@ -81,12 +85,46 @@
(string-trim '(#\Space #\Tab #\Newline) value))
-(defun string-starts-with (str prefix)
+(defun string-starts-with (str prefix &key (ignore-case nil))
"Checks if string str starts with a given prefix."
- (declare (string str prefix))
- (string= str prefix :start1 0 :end1
- (min (length prefix)
- (length str))))
+ (declare (String str prefix)
+ (Boolean ignore-case))
+ (let ((str-i (if ignore-case
+ (string-downcase str :start 0 :end (min (length str)
+ (length prefix)))
+ str))
+ (prefix-i (if ignore-case
+ (string-downcase prefix)
+ prefix)))
+ (string= str-i prefix-i :start1 0 :end1
+ (min (length prefix-i)
+ (length str-i)))))
+
+
+(defun string-ends-with (str suffix &key (ignore-case nil))
+ "Checks if string str ends with a given suffix."
+ (declare (String str suffix)
+ (Boolean ignore-case))
+ (let ((str-i (if ignore-case
+ (string-downcase str :start (max (- (length str)
+ (length suffix))
+ 0)
+ :end (length str))
+ str))
+ (suffix-i (if ignore-case
+ (string-downcase suffix)
+ suffix)))
+ (string= str-i suffix-i :start1 (max (- (length str)
+ (length suffix))
+ 0))))
+
+
+(defun string-starts-with-digit (str)
+ "Checks whether the passed string starts with a digit."
+ (declare (String str))
+ (loop for item in (list 0 1 2 3 4 5 6 7 8 9)
+ when (string-starts-with str (write-to-string item))
+ return t))
(defun string-starts-with-char (begin str)
@@ -123,4 +161,53 @@
search-strings))))
(let ((sorted-positions (sort positions #'<)))
(when sorted-positions
- (first sorted-positions)))))
\ No newline at end of file
+ (first sorted-positions)))))
+
+
+(defun concatenate-uri (absolute-ns value)
+ "Returns a string conctenated of the absolut namespace an the given value
+ separated by either '#' or '/'."
+ (declare (string absolute-ns value))
+ (unless (and (> (length absolute-ns) 0)
+ (> (length value) 0))
+ (error "From concatenate-uri(): absolute-ns and value must be of length > 0"))
+ (unless (absolute-uri-p absolute-ns)
+ (error "From concatenate-uri(): absolute-ns has to be an absolute URI: ~a" absolute-ns))
+ (let ((last-char
+ (elt absolute-ns (- (length absolute-ns) 1)))
+ (first-char
+ (elt value 0)))
+ (let ((separator
+ (cond
+ ((or (eql first-char #\#)
+ (eql first-char #\/))
+ "")
+ ((or (eql last-char #\#)
+ (eql last-char #\/))
+ "")
+ (t
+ "/"))))
+ (let ((prep-ns
+ (if (and (eql last-char first-char)
+ (or (eql last-char #\#)
+ (eql last-char #\/)))
+ (subseq absolute-ns 0 (- (length absolute-ns) 1))
+ (if (and (eql last-char #\#)
+ (find #\/ value))
+ (progn
+ (when (not (eql first-char #\/))
+ (setf separator "/"))
+ (subseq absolute-ns 0 (- (length absolute-ns) 1)))
+ absolute-ns))))
+ (concatenate 'string prep-ns separator value)))))
+
+
+(defun absolute-uri-p (uri)
+ "Returns t if the passed uri is an absolute one. This
+ is indicated by a ':' with no leadgin '/'."
+ (when uri
+ (let ((position-of-colon
+ (position #\: uri)))
+ (declare (string uri))
+ (and position-of-colon (> position-of-colon 0)
+ (not (find #\/ (subseq uri 0 position-of-colon)))))))
\ No newline at end of file
Modified: trunk/src/constants.lisp
==============================================================================
--- trunk/src/constants.lisp (original)
+++ trunk/src/constants.lisp Sun Nov 21 13:16:32 2010
@@ -26,6 +26,10 @@
:*xml-ns*
:*xmlns-ns*
:*xml-string*
+ :*xml-boolean*
+ :*xml-decimal*
+ :*xml-double*
+ :*xml-integer*
:*xml-uri*
:*rdf2tm-ns*
:*rdf-statement*
@@ -100,6 +104,14 @@
(defparameter *xml-string* "http://www.w3.org/2001/XMLSchema#string")
+(defparameter *xml-boolean* "http://www.w3.org/2001/XMLSchema#boolean")
+
+(defparameter *xml-integer* "http://www.w3.org/2001/XMLSchema#integer")
+
+(defparameter *xml-decimal* "http://www.w3.org/2001/XMLSchema#decimal")
+
+(defparameter *xml-double* "http://www.w3.org/2001/XMLSchema#double")
+
(defparameter *xml-uri* "http://www.w3.org/2001/XMLSchema#anyURI")
(defparameter *rdf2tm-ns* "http://isidorus/rdf2tm_mapping/")
Modified: trunk/src/isidorus.asd
==============================================================================
--- trunk/src/isidorus.asd (original)
+++ trunk/src/isidorus.asd Sun Nov 21 13:16:32 2010
@@ -78,8 +78,8 @@
"base-tools"))
(:module "atom"
:components ((:file "atom")
-;; (:file "configuration"
-;; :depends-on ("atom"))
+ ;; (:file "configuration"
+ ;; :depends-on ("atom"))
(:file "collection"
:depends-on ("atom"))
(:file "snapshots"
@@ -156,7 +156,7 @@
(:file "exporter_xtm2.0_test"
:depends-on ("fixtures"))
(:file "exporter_xtm1.0_test"
- :depends-on ("fixtures" "exporter_xtm2.0_test"))
+ :depends-on ("fixtures" "exporter_xtm2.0_test"))
(:file "atom_test"
:depends-on ("fixtures"))
(:file "json_test"
Modified: trunk/src/unit_tests/sparql_test.lisp
==============================================================================
--- trunk/src/unit_tests/sparql_test.lisp (original)
+++ trunk/src/unit_tests/sparql_test.lisp Sun Nov 21 13:16:32 2010
@@ -111,10 +111,13 @@
$var3 ?var3 WHERE{}")
(query-2 "SELECT ?var1$var2 $var3 ?var3 WHERE{}")
(query-3 "SELECT ?var1$var2 $var3 ?var3WHERE{}")
+ (query-4 "SELECT * WHERE{}")
(query-object-1 (make-instance 'SPARQL-Query :query query-1))
- (query-object-2 (make-instance 'SPARQL-Query :query query-2)))
+ (query-object-2 (make-instance 'SPARQL-Query :query query-2))
+ (query-object-3 (make-instance 'SPARQL-QUERY :query query-4)))
(is-true query-object-1)
(is-true query-object-2)
+ (is-true query-object-3)
(signals sparql-parser-error (make-instance 'SPARQL-Query :query query-3))
(is (= (length (TM-SPARQL::variables query-object-1)) 3))
(is-true (find-if #'(lambda(elem)
@@ -141,7 +144,11 @@
(is-true (find-if #'(lambda(elem)
(and (string= (getf elem :variable) "var3")
(null (getf elem :value))))
- (TM-SPARQL::variables query-object-2)))))
+ (TM-SPARQL::variables query-object-2)))
+ (is-true (find-if #'(lambda(elem)
+ (and (string= (getf elem :variable) "*")
+ (null (getf elem :value))))
+ (TM-SPARQL::variables query-object-3)))))
(defun run-sparql-tests ()
Modified: trunk/src/xml/rdf/rdf_tools.lisp
==============================================================================
--- trunk/src/xml/rdf/rdf_tools.lisp (original)
+++ trunk/src/xml/rdf/rdf_tools.lisp Sun Nov 21 13:16:32 2010
@@ -9,88 +9,8 @@
(defpackage :rdf-importer
(:use :cl :cxml :elephant :datamodel :isidorus-threading :datamodel
- :base-tools)
- (:import-from :constants
- *rdf-ns*
- *rdfs-ns*
- *xml-ns*
- *xmlns-ns*
- *xml-string*
- *rdf2tm-ns*
- *xtm2.0-ns*
- *type-instance-psi*
- *type-psi*
- *instance-psi*
- *rdf-statement*
- *rdf-object*
- *rdf-subject*
- *rdf-predicate*
- *rdf2tm-object*
- *rdf2tm-subject*
- *supertype-psi*
- *subtype-psi*
- *supertype-subtype-psi*
- *rdf-nil*
- *rdf-first*
- *rdf-rest*
- *rdf2tm-scope-prefix*
- *tm2rdf-topic-type-uri*
- *tm2rdf-name-type-uri*
- *tm2rdf-name-property*
- *tm2rdf-variant-type-uri*
- *tm2rdf-variant-property*
- *tm2rdf-occurrence-type-uri*
- *tm2rdf-occurrence-property*
- *tm2rdf-role-type-uri*
- *tm2rdf-role-property*
- *tm2rdf-association-type-uri*
- *tm2rdf-association-property*
- *tm2rdf-subjectIdentifier-property*
- *tm2rdf-itemIdentity-property*
- *tm2rdf-subjectLocator-property*
- *tm2rdf-ns*
- *tm2rdf-value-property*
- *tm2rdf-scope-property*
- *tm2rdf-nametype-property*
- *tm2rdf-occurrencetype-property*
- *tm2rdf-roletype-property*
- *tm2rdf-player-property*
- *tm2rdf-associationtype-property*
- *rdf2tm-blank-node-prefix*
- *tm2rdf-reifier-property*)
- (:import-from :xml-constants
- *rdf_core_psis.xtm*
- *core_psis.xtm*)
- (:import-from :xml-tools
- get-attribute
- xpath-fn-string
- xpath-child-elems-by-qname
- xpath-single-child-elem-by-qname
- xpath-select-location-path
- xpath-select-single-location-path
- get-ns-attribute
- clear-child-nodes
- has-qname
- absolute-uri-p
- get-node-name
- child-nodes-or-text
- get-xml-lang
- get-xml-base
- absolutize-value
- absolutize-id
- concatenate-uri
- node-to-string)
- (:import-from :xml-importer
- get-uuid
- get-store-spec
- with-tm
- from-topic-elem-to-stub)
- (:import-from :isidorus-threading
- with-reader-lock
- with-writer-lock)
- (:import-from :exceptions
- missing-reference-error
- duplicate-identifier-error)
+ :base-tools :constants :xml-constants :xml-tools
+ :xml-importer :isidorus-threading :exceptions)
(:export :setup-rdf-module
:rdf-importer
:init-rdf-module
Modified: trunk/src/xml/xtm/importer.lisp
==============================================================================
--- trunk/src/xml/xtm/importer.lisp (original)
+++ trunk/src/xml/xtm/importer.lisp Sun Nov 21 13:16:32 2010
@@ -72,6 +72,7 @@
:merge-topic-elem-xtm1.0
:from-association-elem-xtm1.0
:importer-xtm1.0
+ :get-uuid
:with-tm))
(in-package :xml-importer)
Modified: trunk/src/xml/xtm/tools.lisp
==============================================================================
--- trunk/src/xml/xtm/tools.lisp (original)
+++ trunk/src/xml/xtm/tools.lisp Sun Nov 21 13:16:32 2010
@@ -21,56 +21,16 @@
:xpath-select-single-location-path
:get-ns-attribute
:clear-child-nodes
- :absolute-uri-p
:get-node-name
:child-nodes-or-text
:get-xml-lang
:get-xml-base
:absolutize-value
:absolutize-id
- :concatenate-uri
:node-to-string))
(in-package :xml-tools)
-(defun concatenate-uri (absolute-ns value)
- "Returns a string conctenated of the absolut namespace an the given value
- separated by either '#' or '/'."
- (declare (string absolute-ns value))
- (unless (and (> (length absolute-ns) 0)
- (> (length value) 0))
- (error "From concatenate-uri(): absolute-ns and value must be of length > 0"))
- (unless (absolute-uri-p absolute-ns)
- (error "From concatenate-uri(): absolute-ns has to be an absolute URI: ~a" absolute-ns))
- (let ((last-char
- (elt absolute-ns (- (length absolute-ns) 1)))
- (first-char
- (elt value 0)))
- (let ((separator
- (cond
- ((or (eql first-char #\#)
- (eql first-char #\/))
- "")
- ((or (eql last-char #\#)
- (eql last-char #\/))
- "")
- (t
- "/"))))
- (let ((prep-ns
- (if (and (eql last-char first-char)
- (or (eql last-char #\#)
- (eql last-char #\/)))
- (subseq absolute-ns 0 (- (length absolute-ns) 1))
- (if (and (eql last-char #\#)
- (find #\/ value))
- (progn
- (when (not (eql first-char #\/))
- (setf separator "/"))
- (subseq absolute-ns 0 (- (length absolute-ns) 1)))
- absolute-ns))))
- (concatenate 'string prep-ns separator value)))))
-
-
(defun absolutize-id (id xml-base tm-id)
"Returns the passed id as an absolute uri computed
with the given base and tm-id."
@@ -206,17 +166,6 @@
nil))))) ;there were no text nodes available
-(defun absolute-uri-p (uri)
- "Returns t if the passed uri is an absolute one. This
- is indicated by a ':' with no leadgin '/'."
- (when uri
- (let ((position-of-colon
- (position #\: uri)))
- (declare (string uri))
- (and position-of-colon (> position-of-colon 0)
- (not (find #\/ (subseq uri 0 position-of-colon)))))))
-
-
(defun get-node-name (elem)
"Returns the node's name without a prefix."
(if (find #\: (dom:node-name elem))
1
0

[isidorus-cvs] r343 - in trunk/src: TM-SPARQL base-tools model unit_tests
by Lukas Giessmann 19 Nov '10
by Lukas Giessmann 19 Nov '10
19 Nov '10
Author: lgiessmann
Date: Fri Nov 19 07:22:30 2010
New Revision: 343
Log:
TM-SPARQL: addded the parsing of variables in the SELECT statement; added some unit-tests
Modified:
trunk/src/TM-SPARQL/sparql.lisp
trunk/src/TM-SPARQL/sparql_parser.lisp
trunk/src/base-tools/base-tools.lisp
trunk/src/model/exceptions.lisp
trunk/src/unit_tests/sparql_test.lisp
Modified: trunk/src/TM-SPARQL/sparql.lisp
==============================================================================
--- trunk/src/TM-SPARQL/sparql.lisp (original)
+++ trunk/src/TM-SPARQL/sparql.lisp Fri Nov 19 07:22:30 2010
@@ -24,17 +24,17 @@
:type String
:initform (error
(make-condition
- 'missing-query-string-error
+ 'missing-argument-error
:message "From TM-Query(): original-query must be set"))
:documentation "Containst the original received querry as string")
- (prefix-list :initarg :prefix-list
- :accessor prefix-list ;this value is only for internal purposes
- ;purposes and mustn't be reset
- :type List
- :initform nil
- :documentation "A list of the form
- ((:label 'id' :value 'prefix'))")
- (base-value :initarg :base-value ;initialy the requester's address
+ (prefixes :initarg :prefixes
+ :accessor prefixes ;this value is only for internal purposes
+ ;purposes and mustn't be reset
+ :type List
+ :initform nil
+ :documentation "A list of the form
+ ((:label 'id' :value 'prefix'))")
+ (base-value :initarg :base ;initialy the requester's address
:accessor base-value ;this value is only for internal purposes
;purposes and mustn't be reset
:type String
@@ -44,7 +44,8 @@
:accessor variables ;this value is only for internal purposes
;purposes and mustn't be reset
:type List
- :documentation "A list of the form ((:variable var-symbol
+ :initform nil
+ :documentation "A list of the form ((:variable var-name
:value value-object)), that contains tuples
for each variable and its result.")
(select-statements :initarg :select-statements
@@ -52,6 +53,7 @@
;internal purposes purposes
;and mustn't be reset
:type List
+ :initform nil
:documentation "A list of the form ((:statement 'statement'
:value value-object))")))
@@ -64,15 +66,30 @@
(let ((existing-tuple
(find-if #'(lambda(x)
(string= (getf x :label) prefix-label))
- (prefix-list construct))))
+ (prefixes construct))))
(if existing-tuple
(setf (getf existing-tuple :value) prefix-value)
(push (list :label prefix-label :value prefix-value)
- (prefix-list construct))))))
-
+ (prefixes construct))))))
+
+
+(defgeneric add-variable (construct variable-name variable-value)
+ (:documentation "Adds a new variable-name with its value to the aexisting list.
+ If a variable-already exists the existing entry will be
+ overwritten. An entry is of the form
+ (:variable string :value any-type).")
+ (:method ((construct SPARQL-Query) (variable-name String) variable-value)
+ (let ((existing-tuple
+ (find-if #'(lambda(x)
+ (string= (getf x :variable) variable-name))
+ (variables construct))))
+ (if existing-tuple
+ (setf (getf existing-tuple :value) variable-value)
+ (push (list :variable variable-name :value variable-value)
+ (variables construct))))))
(defmethod initialize-instance :after ((construct SPARQL-Query) &rest args)
(declare (ignorable args))
(parser-start construct (original-query construct))
- construct)
+ construct)
\ No newline at end of file
Modified: trunk/src/TM-SPARQL/sparql_parser.lisp
==============================================================================
--- trunk/src/TM-SPARQL/sparql_parser.lisp (original)
+++ trunk/src/TM-SPARQL/sparql_parser.lisp Fri Nov 19 07:22:30 2010
@@ -14,9 +14,11 @@
"Creates a spqrql-parser-error object."
(declare (String rest-of-query entire-query expected))
(let ((message
- (format nil "The query:~%~a bad token on position ~a. Expected: ~a"
+ (format nil "The query:~%\"~a\"~%~%has a bad token at position ~a => ~a.~%Expected: ~a"
entire-query (- (length entire-query)
(length rest-of-query))
+ (subseq entire-query (- (length entire-query)
+ (length rest-of-query)))
expected)))
(make-condition 'sparql-parser-error :message message)))
@@ -26,14 +28,17 @@
(:method ((construct SPARQL-Query) (query-string String))
(let ((trimmed-query-string (trim-whitespace-left query-string)))
(cond ((string-starts-with trimmed-query-string "SELECT")
- nil) ;;TODO: implement
+ (parse-select
+ construct (string-after trimmed-query-string "SELECT")))
((string-starts-with trimmed-query-string "PREFIX")
- (parse-prefixes construct
- (string-after trimmed-query-string "PREFIX")))
+ (parse-prefixes
+ construct (string-after trimmed-query-string "PREFIX")))
((string-starts-with trimmed-query-string "BASE")
(parse-base construct (string-after trimmed-query-string "BASE")
#'parser-start))
- ((= (length trimmed-query-string) 0) ;TODO: remove, only for debugging purposes
+ ((= (length trimmed-query-string) 0)
+ ;; If there is only a BASE and/or PREFIX statement return an
+ ;; query-object with the result nil
construct)
(t
(error (make-sparql-parser-condition
@@ -41,6 +46,71 @@
"SELECT, PREFIX or BASE")))))))
+(defgeneric parse-select (construct query-string)
+ (:documentation "The entry-point of the parsing of the select - where
+ statement.")
+ (:method ((construct SPARQL-Query) (query-string String))
+ (let* ((trimmed-str (trim-whitespace-left query-string))
+ (next-query (if (string-starts-with trimmed-str "WHERE")
+ trimmed-str
+ (parse-variables construct trimmed-str))))
+ (unless (string-starts-with next-query "WHERE")
+ (error (make-sparql-parser-condition
+ next-query (original-query construct) "WHERE")))
+ (let* ((tripples (string-after next-query "WHERE"))
+ (query-tail (parse-where construct tripples)))
+ (or query-tail) ;TODO: process tail-of query, e.g. order by, ...
+ construct))))
+
+
+(defgeneric parse-where (construct query-string)
+ (:documentation "The entry-point for the parsing of the WHERE statement.")
+ (:method ((construct SPARQL-Query) (query-string String))
+ ))
+
+
+(defgeneric parse-variables (construct query-string)
+ (:documentation "Parses the variables of the SELECT statement
+ and adds them to the passed construct.")
+ (:method ((construct SPARQL-Query) (query-string String))
+ (let ((trimmed-str (trim-whitespace-left query-string)))
+ (if (string-starts-with trimmed-str "WHERE")
+ trimmed-str
+ (let ((result (parse-variable-name trimmed-str construct)))
+ (add-variable construct (getf result :value) nil)
+ (parse-variables construct (getf result :next-query)))))))
+
+
+(defun parse-variable-name (query-string query-object)
+ "A helper function that parses the first non-whitespace character
+ in the query. since it must be a variable, it must be prefixed
+ by a ? or $. The return value is of the form
+ (:next-query string :value string)."
+ (declare (String query-string)
+ (SPARQL-Query query-object))
+ (let ((trimmed-str (trim-whitespace-left query-string))
+ (delimiters (list " " "?" "$" (string #\newline) (string #\tab))))
+ (unless (or (string-starts-with trimmed-str "?")
+ (string-starts-with trimmed-str "$"))
+ (make-sparql-parser-condition
+ trimmed-str (original-query query-object) "? or $"))
+ (let* ((var-name-end (search-first delimiters (subseq trimmed-str 1)))
+ (var-name
+ (if var-name-end
+ (subseq trimmed-str 0 (+ 1 var-name-end))
+ (error (make-sparql-parser-condition
+ trimmed-str (original-query query-object)
+ "space, newline, tab, ?, $ or WHERE"))))
+ (next-query (string-after trimmed-str var-name))
+ (normalized-var-name
+ (if (<= (length var-name) 1)
+ (error (make-sparql-parser-condition
+ next-query (original-query query-object)
+ "a variable name"))
+ (subseq var-name 1))))
+ (list :next-query next-query :value normalized-var-name))))
+
+
(defgeneric parse-base (construct query-string next-fun)
(:documentation "Parses the Base statment and sets the corresponding
attribute in the query-construct. Since the BASE statement
@@ -48,7 +118,7 @@
call function that calls the next transitions and states.")
(:method ((construct SPARQL-Query) (query-string String) (next-fun Function))
(let* ((trimmed-str (trim-whitespace-left query-string))
- (result (parse-bracketed-value trimmed-str construct)))
+ (result (parse-closed-value trimmed-str construct)))
(setf (base-value construct) (getf result :value))
(funcall next-fun construct (getf result :next-query)))))
@@ -59,14 +129,14 @@
(let ((trimmed-string (trim-whitespace-left query-string)))
(if (string-starts-with trimmed-string ":")
(let ((results
- (parse-bracketed-value (subseq trimmed-string 1) construct)))
+ (parse-closed-value (subseq trimmed-string 1) construct)))
(add-prefix construct *empty-label* (getf results :value))
(parser-start construct (getf results :next-query)))
(let* ((label-name
(trim-whitespace-right (string-until trimmed-string ":")))
(next-query-str
(trim-whitespace-left (string-after trimmed-string ":")))
- (results (parse-bracketed-value next-query-str construct)))
+ (results (parse-closed-value next-query-str construct)))
(when (string= label-name trimmed-string)
(error (make-sparql-parser-condition
trimmed-string (original-query construct) ":")))
@@ -74,7 +144,7 @@
(parser-start construct (getf results :next-query)))))))
-(defun parse-bracketed-value(query-string query-object &key (open "<") (close ">"))
+(defun parse-closed-value(query-string query-object &key (open "<") (close ">"))
"A helper function that checks the value of a statement within
two brackets, i.e. <prefix-value>. A list of the
form (:next-query string :value string) is returned."
Modified: trunk/src/base-tools/base-tools.lisp
==============================================================================
--- trunk/src/base-tools/base-tools.lisp (original)
+++ trunk/src/base-tools/base-tools.lisp Fri Nov 19 07:22:30 2010
@@ -20,7 +20,8 @@
:string-starts-with
:string-starts-with-char
:string-until
- :string-after))
+ :string-after
+ :search-first))
(in-package :base-tools)
@@ -108,4 +109,18 @@
(let ((pos (search prefix str)))
(if pos
(subseq str (+ pos (length prefix)))
- nil)))
\ No newline at end of file
+ nil)))
+
+
+(defun search-first (search-strings main-string)
+ "Returns the position of one of the search-strings. The returned position
+ is the one closest to 0. If no search-string is found, nil is returned."
+ (declare (String main-string)
+ (List search-strings))
+ (let ((positions
+ (remove-null (map 'list #'(lambda(search-str)
+ (search search-str main-string))
+ search-strings))))
+ (let ((sorted-positions (sort positions #'<)))
+ (when sorted-positions
+ (first sorted-positions)))))
\ No newline at end of file
Modified: trunk/src/model/exceptions.lisp
==============================================================================
--- trunk/src/model/exceptions.lisp (original)
+++ trunk/src/model/exceptions.lisp Fri Nov 19 07:22:30 2010
@@ -18,18 +18,11 @@
:missing-argument-error
:tm-reference-error
:bad-type-error
- :missing-query-string-error
:sparql-parser-error))
(in-package :exceptions)
-(define-condition missing-query-string-error(error)
- ((message
- :initarg :message
- :accessor message)))
-
-
(define-condition sparql-parser-error(error)
((message
:initarg :message
Modified: trunk/src/unit_tests/sparql_test.lisp
==============================================================================
--- trunk/src/unit_tests/sparql_test.lisp (original)
+++ trunk/src/unit_tests/sparql_test.lisp Fri Nov 19 07:22:30 2010
@@ -10,26 +10,138 @@
(defpackage :sparql-test
(:use :cl
:it.bese.FiveAM
- :TM-SPARQL)
+ :TM-SPARQL
+ :exceptions)
(:export :run-sparql-tests
- :sparql-tests))
+ :sparql-tests
+ :test-prefix-and-base))
(in-package :sparql-test)
-(def-suite sparql-test
+(def-suite sparql-tests
:description "tests various key functions of the TM-SPARQL module")
-(in-suite sparql-test)
+(in-suite sparql-tests)
-;TODO: prefix tests
-;PREFIX foaf : <http://xmlns.com/foaf/0.1/>
-;PREFIX org: <http://example.com/ns#>
-;PREFIX isi:<http://isidor.us>
-;PREFIX :<http://some.where>
-;PREFIX foaf : <http://overwrite.foaf>"
+(test test-prefix-and-base
+ "Tests the sparql parser when parsing PREFIX and BASE statements."
+ (let* ((query-1 "PREFIX foaf : <http://xmlns.com/foaf/0.1/>
+ PREFIX org: <http://example.com/ns#>
+ PREFIX isi:<http://isidor.us>
+ PREFIX :<http://some.where>
+ BASE <http://base.one>
+ PREFIX foaf : <http://overwrite.foaf>
+ BASE<http://base.two>")
+ (query-2 "PREFIX foaf : <http://xmlns.com/foaf/0.1/>
+ PREFIX org:
+<http://example.com/ns#>
+ PREFIX isi:<http://isidor.us>
+ PREFIX
+:<http://some.where>
+ BASE <http://base.one>
+ PREFIX foaf : <http://overwrite.foaf>
+ BASE<http://base.two>")
+ (query-object-1 (make-instance 'SPARQL-Query :query query-1))
+ (query-object-2 (make-instance 'SPARQL-Query :query query-2
+ :base "http://any-base")))
+ (signals missing-argument-error (make-instance 'SPARQL-Query))
+ (is-true query-object-1)
+ (is-true query-object-2)
+ (is (string= (TM-SPARQL::base-value query-object-1) "http://base.two"))
+ (is (string= (TM-SPARQL::base-value query-object-2) "http://base.two"))
+ (is (= (length (TM-SPARQL::prefixes query-object-1)) 4))
+ (is (= (length (TM-SPARQL::prefixes query-object-2)) 4))
+ (is-true (find-if #'(lambda(elem)
+ (and (string= (getf elem :label) "foaf")
+ (string= (getf elem :value)
+ "http://overwrite.foaf")))
+ (TM-SPARQL::prefixes query-object-1)))
+ (is-true (find-if #'(lambda(elem)
+ (and (string= (getf elem :label) "org")
+ (string= (getf elem :value)
+ "http://example.com/ns#")))
+ (TM-SPARQL::prefixes query-object-1)))
+ (is-true (find-if #'(lambda(elem)
+ (and (string= (getf elem :label) "isi")
+ (string= (getf elem :value)
+ "http://isidor.us")))
+ (TM-SPARQL::prefixes query-object-1)))
+ (is-true (find-if #'(lambda(elem)
+ (and (string= (getf elem :label)
+ TM-SPARQL::*empty-label*)
+ (string= (getf elem :value)
+ "http://some.where")))
+ (TM-SPARQL::prefixes query-object-1)))
+ (is-true (find-if #'(lambda(elem)
+ (and (string= (getf elem :label) "foaf")
+ (string= (getf elem :value)
+ "http://overwrite.foaf")))
+ (TM-SPARQL::prefixes query-object-2)))
+ (is-true (find-if #'(lambda(elem)
+ (and (string= (getf elem :label) "org")
+ (string= (getf elem :value)
+ "http://example.com/ns#")))
+ (TM-SPARQL::prefixes query-object-2)))
+ (is-true (find-if #'(lambda(elem)
+ (and (string= (getf elem :label) "isi")
+ (string= (getf elem :value)
+ "http://isidor.us")))
+ (TM-SPARQL::prefixes query-object-2)))
+ (is-true (find-if #'(lambda(elem)
+ (and (string= (getf elem :label)
+ TM-SPARQL::*empty-label*)
+ (string= (getf elem :value)
+ "http://some.where")))
+ (TM-SPARQL::prefixes query-object-2)))))
+
+
+(test test-variable-names
+ "Tests the sparql parser when parsing variables in the SELECT statement."
+ (let* ((query-1 "PREFIX foaf : <http://xmlns.com/foaf/0.1/>
+ PREFIX org: <http://example.com/ns#>
+ PREFIX isi:<http://isidor.us>
+ PREFIX :<http://some.where>
+ BASE <http://base.one>
+ PREFIX foaf : <http://overwrite.foaf>
+ BASE<http://base.two>
+ SELECT ?var1$var2
+$var3 ?var3 WHERE{}")
+ (query-2 "SELECT ?var1$var2 $var3 ?var3 WHERE{}")
+ (query-3 "SELECT ?var1$var2 $var3 ?var3WHERE{}")
+ (query-object-1 (make-instance 'SPARQL-Query :query query-1))
+ (query-object-2 (make-instance 'SPARQL-Query :query query-2)))
+ (is-true query-object-1)
+ (is-true query-object-2)
+ (signals sparql-parser-error (make-instance 'SPARQL-Query :query query-3))
+ (is (= (length (TM-SPARQL::variables query-object-1)) 3))
+ (is-true (find-if #'(lambda(elem)
+ (and (string= (getf elem :variable) "var1")
+ (null (getf elem :value))))
+ (TM-SPARQL::variables query-object-1)))
+ (is-true (find-if #'(lambda(elem)
+ (and (string= (getf elem :variable) "var2")
+ (null (getf elem :value))))
+ (TM-SPARQL::variables query-object-1)))
+ (is-true (find-if #'(lambda(elem)
+ (and (string= (getf elem :variable) "var3")
+ (null (getf elem :value))))
+ (TM-SPARQL::variables query-object-1)))
+ (is (= (length (TM-SPARQL::variables query-object-2)) 3))
+ (is-true (find-if #'(lambda(elem)
+ (and (string= (getf elem :variable) "var1")
+ (null (getf elem :value))))
+ (TM-SPARQL::variables query-object-2)))
+ (is-true (find-if #'(lambda(elem)
+ (and (string= (getf elem :variable) "var2")
+ (null (getf elem :value))))
+ (TM-SPARQL::variables query-object-2)))
+ (is-true (find-if #'(lambda(elem)
+ (and (string= (getf elem :variable) "var3")
+ (null (getf elem :value))))
+ (TM-SPARQL::variables query-object-2)))))
(defun run-sparql-tests ()
1
0
Author: lgiessmann
Date: Fri Nov 19 04:29:06 2010
New Revision: 342
Log:
TM-SPARQL: added parsing of BASE statements
Modified:
trunk/src/TM-SPARQL/sparql.lisp
trunk/src/TM-SPARQL/sparql_parser.lisp
Modified: trunk/src/TM-SPARQL/sparql.lisp
==============================================================================
--- trunk/src/TM-SPARQL/sparql.lisp (original)
+++ trunk/src/TM-SPARQL/sparql.lisp Fri Nov 19 04:29:06 2010
@@ -19,7 +19,8 @@
(defclass SPARQL-Query ()
((original-query :initarg :query
- :reader original-query
+ :accessor original-query ;this value is only for internal
+ ;purposes and mustn't be reset
:type String
:initform (error
(make-condition
@@ -27,19 +28,29 @@
:message "From TM-Query(): original-query must be set"))
:documentation "Containst the original received querry as string")
(prefix-list :initarg :prefix-list
- :reader prefix-list
+ :accessor prefix-list ;this value is only for internal purposes
+ ;purposes and mustn't be reset
:type List
:initform nil
:documentation "A list of the form
((:label 'id' :value 'prefix'))")
+ (base-value :initarg :base-value ;initialy the requester's address
+ :accessor base-value ;this value is only for internal purposes
+ ;purposes and mustn't be reset
+ :type String
+ :initform nil
+ :documentation "Contains the last set base-value.")
(variables :initarg :variables
- :accessor :variables
+ :accessor variables ;this value is only for internal purposes
+ ;purposes and mustn't be reset
:type List
:documentation "A list of the form ((:variable var-symbol
:value value-object)), that contains tuples
for each variable and its result.")
(select-statements :initarg :select-statements
- :accessor select-statements
+ :accessor select-statements ;this value is only for
+ ;internal purposes purposes
+ ;and mustn't be reset
:type List
:documentation "A list of the form ((:statement 'statement'
:value value-object))")))
@@ -57,7 +68,7 @@
(if existing-tuple
(setf (getf existing-tuple :value) prefix-value)
(push (list :label prefix-label :value prefix-value)
- (slot-value construct 'prefix-list))))))
+ (prefix-list construct))))))
Modified: trunk/src/TM-SPARQL/sparql_parser.lisp
==============================================================================
--- trunk/src/TM-SPARQL/sparql_parser.lisp (original)
+++ trunk/src/TM-SPARQL/sparql_parser.lisp Fri Nov 19 04:29:06 2010
@@ -9,6 +9,7 @@
(in-package :TM-SPARQL)
+
(defun make-sparql-parser-condition(rest-of-query entire-query expected)
"Creates a spqrql-parser-error object."
(declare (String rest-of-query entire-query expected))
@@ -20,7 +21,6 @@
(make-condition 'sparql-parser-error :message message)))
-
(defgeneric parser-start(construct query-string)
(:documentation "The entry point of the SPARQL-parser.")
(:method ((construct SPARQL-Query) (query-string String))
@@ -31,38 +31,53 @@
(parse-prefixes construct
(string-after trimmed-query-string "PREFIX")))
((string-starts-with trimmed-query-string "BASE")
- nil) ;TODO: implement
+ (parse-base construct (string-after trimmed-query-string "BASE")
+ #'parser-start))
+ ((= (length trimmed-query-string) 0) ;TODO: remove, only for debugging purposes
+ construct)
(t
(error (make-sparql-parser-condition
trimmed-query-string (original-query construct)
"SELECT, PREFIX or BASE")))))))
+(defgeneric parse-base (construct query-string next-fun)
+ (:documentation "Parses the Base statment and sets the corresponding
+ attribute in the query-construct. Since the BASE statement
+ may appear in different states the next-fun defines the next
+ call function that calls the next transitions and states.")
+ (:method ((construct SPARQL-Query) (query-string String) (next-fun Function))
+ (let* ((trimmed-str (trim-whitespace-left query-string))
+ (result (parse-bracketed-value trimmed-str construct)))
+ (setf (base-value construct) (getf result :value))
+ (funcall next-fun construct (getf result :next-query)))))
+
+
(defgeneric parse-prefixes (construct query-string)
(:documentation "Sets the correponding prefix-tuples in the passed object.")
(:method ((construct SPARQL-Query) (query-string String))
(let ((trimmed-string (trim-whitespace-left query-string)))
(if (string-starts-with trimmed-string ":")
(let ((results
- (parse-bracket-value (subseq trimmed-string 1) construct)))
+ (parse-bracketed-value (subseq trimmed-string 1) construct)))
(add-prefix construct *empty-label* (getf results :value))
- (parser-start construct (getf results :query-string)))
+ (parser-start construct (getf results :next-query)))
(let* ((label-name
(trim-whitespace-right (string-until trimmed-string ":")))
(next-query-str
(trim-whitespace-left (string-after trimmed-string ":")))
- (results (parse-bracket-value next-query-str construct)))
+ (results (parse-bracketed-value next-query-str construct)))
(when (string= label-name trimmed-string)
(error (make-sparql-parser-condition
trimmed-string (original-query construct) ":")))
(add-prefix construct label-name (getf results :value))
- (parser-start construct (getf results :query-string)))))))
+ (parser-start construct (getf results :next-query)))))))
-(defun parse-bracket-value(query-string query-object &key (open "<") (close ">"))
+(defun parse-bracketed-value(query-string query-object &key (open "<") (close ">"))
"A helper function that checks the value of a statement within
two brackets, i.e. <prefix-value>. A list of the
- form (:query-string string :value string) is returned."
+ form (:next-query string :value string) is returned."
(declare (String query-string open close)
(SPARQL-Query query-object))
(let ((trimmed-string (trim-whitespace-left query-string)))
@@ -73,7 +88,7 @@
(error (make-sparql-parser-condition
trimmed-string (original-query query-object)
close)))
- (list :query-string next-query-str
+ (list :next-query next-query-str
:value pref-url))
(error (make-sparql-parser-condition
trimmed-string (original-query query-object)
1
0
Author: lgiessmann
Date: Thu Nov 18 15:04:16 2010
New Revision: 341
Log:
fixed several bugs in the processing of PREFIX-statements
Modified:
trunk/src/TM-SPARQL/sparql.lisp
trunk/src/TM-SPARQL/sparql_parser.lisp
trunk/src/unit_tests/sparql_test.lisp
Modified: trunk/src/TM-SPARQL/sparql.lisp
==============================================================================
--- trunk/src/TM-SPARQL/sparql.lisp (original)
+++ trunk/src/TM-SPARQL/sparql.lisp Thu Nov 18 15:04:16 2010
@@ -18,7 +18,7 @@
(defclass SPARQL-Query ()
- ((original-query :initarg :original-query
+ ((original-query :initarg :query
:reader original-query
:type String
:initform (error
@@ -29,6 +29,7 @@
(prefix-list :initarg :prefix-list
:reader prefix-list
:type List
+ :initform nil
:documentation "A list of the form
((:label 'id' :value 'prefix'))")
(variables :initarg :variables
@@ -48,10 +49,10 @@
(:documentation "Adds the new prefix tuple to the list of all existing.
If there already exists a tuple with the same label
the label's value will be overwritten by the new value.")
- (:method ((construct SPARQL-Query) (prefix-label Symbol) (prefix-value String))
+ (:method ((construct SPARQL-Query) (prefix-label String) (prefix-value String))
(let ((existing-tuple
(find-if #'(lambda(x)
- (eql (getf x :label) prefix-label))
+ (string= (getf x :label) prefix-label))
(prefix-list construct))))
(if existing-tuple
(setf (getf existing-tuple :value) prefix-value)
@@ -62,5 +63,5 @@
(defmethod initialize-instance :after ((construct SPARQL-Query) &rest args)
(declare (ignorable args))
- (parser-start construct)
+ (parser-start construct (original-query construct))
construct)
Modified: trunk/src/TM-SPARQL/sparql_parser.lisp
==============================================================================
--- trunk/src/TM-SPARQL/sparql_parser.lisp (original)
+++ trunk/src/TM-SPARQL/sparql_parser.lisp Thu Nov 18 15:04:16 2010
@@ -26,10 +26,10 @@
(:method ((construct SPARQL-Query) (query-string String))
(let ((trimmed-query-string (trim-whitespace-left query-string)))
(cond ((string-starts-with trimmed-query-string "SELECT")
- (parse-prefixes construct
- (string-after trimmed-query-string "SELECT")))
+ nil) ;;TODO: implement
((string-starts-with trimmed-query-string "PREFIX")
- nil) ;TODO: implement
+ (parse-prefixes construct
+ (string-after trimmed-query-string "PREFIX")))
((string-starts-with trimmed-query-string "BASE")
nil) ;TODO: implement
(t
@@ -52,6 +52,9 @@
(next-query-str
(trim-whitespace-left (string-after trimmed-string ":")))
(results (parse-bracket-value next-query-str construct)))
+ (when (string= label-name trimmed-string)
+ (error (make-sparql-parser-condition
+ trimmed-string (original-query construct) ":")))
(add-prefix construct label-name (getf results :value))
(parser-start construct (getf results :query-string)))))))
@@ -63,12 +66,9 @@
(declare (String query-string open close)
(SPARQL-Query query-object))
(let ((trimmed-string (trim-whitespace-left query-string)))
- (if (and (string-starts-with trimmed-string open)
- (> (length (string-after trimmed-string close)) 0))
- (let* ((pref-url
- (string-until (string-after trimmed-string open) close))
- (next-query-str
- (string-after pref-url close)))
+ (if (string-starts-with trimmed-string open)
+ (let* ((pref-url (string-until (string-after trimmed-string open) close))
+ (next-query-str (string-after trimmed-string close)))
(unless next-query-str
(error (make-sparql-parser-condition
trimmed-string (original-query query-object)
@@ -77,7 +77,7 @@
:value pref-url))
(error (make-sparql-parser-condition
trimmed-string (original-query query-object)
- open)))))
+ close)))))
Modified: trunk/src/unit_tests/sparql_test.lisp
==============================================================================
--- trunk/src/unit_tests/sparql_test.lisp (original)
+++ trunk/src/unit_tests/sparql_test.lisp Thu Nov 18 15:04:16 2010
@@ -24,5 +24,13 @@
(in-suite sparql-test)
+;TODO: prefix tests
+;PREFIX foaf : <http://xmlns.com/foaf/0.1/>
+;PREFIX org: <http://example.com/ns#>
+;PREFIX isi:<http://isidor.us>
+;PREFIX :<http://some.where>
+;PREFIX foaf : <http://overwrite.foaf>"
+
+
(defun run-sparql-tests ()
(it.bese.fiveam:run! 'sparql-test:sparql-tests))
\ No newline at end of file
1
0

[isidorus-cvs] r340 - in trunk/src: . TM-SPARQL base-tools model xml/rdf xml/xtm
by Lukas Giessmann 17 Nov '10
by Lukas Giessmann 17 Nov '10
17 Nov '10
Author: lgiessmann
Date: Wed Nov 17 16:41:59 2010
New Revision: 340
Log:
added a SPARQL-Query class with several accessor-methods. This class contains the actual query-string, some query-attributes and the result objects; started to implement a SPARQL-parser => currently the PREFIX parts can be processed; added some functions to base-tools
Added:
trunk/src/TM-SPARQL/sparql_parser.lisp
- copied, changed from r336, /trunk/src/TM-SPARQL/sparql_tokenizer.lisp
Removed:
trunk/src/TM-SPARQL/sparql_tokenizer.lisp
Modified:
trunk/src/TM-SPARQL/sparql.lisp
trunk/src/base-tools/base-tools.lisp
trunk/src/isidorus.asd
trunk/src/model/datamodel.lisp
trunk/src/model/exceptions.lisp
trunk/src/xml/rdf/exporter.lisp
trunk/src/xml/xtm/tools.lisp
Modified: trunk/src/TM-SPARQL/sparql.lisp
==============================================================================
--- trunk/src/TM-SPARQL/sparql.lisp (original)
+++ trunk/src/TM-SPARQL/sparql.lisp Wed Nov 17 16:41:59 2010
@@ -7,4 +7,60 @@
;;+ trunk/docs/LGPL-LICENSE.txt.
;;+-----------------------------------------------------------------------------
+(defpackage :TM-SPARQL
+ (:use :cl :datamodel :base-tools :exceptions)
+ (:export :SPARQL-Query))
+
+
(in-package :TM-SPARQL)
+
+(defvar *empty-label* "_empty_label_symbol")
+
+
+(defclass SPARQL-Query ()
+ ((original-query :initarg :original-query
+ :reader original-query
+ :type String
+ :initform (error
+ (make-condition
+ 'missing-query-string-error
+ :message "From TM-Query(): original-query must be set"))
+ :documentation "Containst the original received querry as string")
+ (prefix-list :initarg :prefix-list
+ :reader prefix-list
+ :type List
+ :documentation "A list of the form
+ ((:label 'id' :value 'prefix'))")
+ (variables :initarg :variables
+ :accessor :variables
+ :type List
+ :documentation "A list of the form ((:variable var-symbol
+ :value value-object)), that contains tuples
+ for each variable and its result.")
+ (select-statements :initarg :select-statements
+ :accessor select-statements
+ :type List
+ :documentation "A list of the form ((:statement 'statement'
+ :value value-object))")))
+
+
+(defgeneric add-prefix (construct prefix-label prefix-value)
+ (:documentation "Adds the new prefix tuple to the list of all existing.
+ If there already exists a tuple with the same label
+ the label's value will be overwritten by the new value.")
+ (:method ((construct SPARQL-Query) (prefix-label Symbol) (prefix-value String))
+ (let ((existing-tuple
+ (find-if #'(lambda(x)
+ (eql (getf x :label) prefix-label))
+ (prefix-list construct))))
+ (if existing-tuple
+ (setf (getf existing-tuple :value) prefix-value)
+ (push (list :label prefix-label :value prefix-value)
+ (slot-value construct 'prefix-list))))))
+
+
+
+(defmethod initialize-instance :after ((construct SPARQL-Query) &rest args)
+ (declare (ignorable args))
+ (parser-start construct)
+ construct)
Copied: trunk/src/TM-SPARQL/sparql_parser.lisp (from r336, /trunk/src/TM-SPARQL/sparql_tokenizer.lisp)
==============================================================================
--- /trunk/src/TM-SPARQL/sparql_tokenizer.lisp (original)
+++ trunk/src/TM-SPARQL/sparql_parser.lisp Wed Nov 17 16:41:59 2010
@@ -7,8 +7,113 @@
;;+ trunk/docs/LGPL-LICENSE.txt.
;;+-----------------------------------------------------------------------------
-(defpackage :TM-SPARQL
- (:use :cl :datamodel))
+(in-package :TM-SPARQL)
+(defun make-sparql-parser-condition(rest-of-query entire-query expected)
+ "Creates a spqrql-parser-error object."
+ (declare (String rest-of-query entire-query expected))
+ (let ((message
+ (format nil "The query:~%~a bad token on position ~a. Expected: ~a"
+ entire-query (- (length entire-query)
+ (length rest-of-query))
+ expected)))
+ (make-condition 'sparql-parser-error :message message)))
-(in-package :TM-SPARQL)
+
+
+(defgeneric parser-start(construct query-string)
+ (:documentation "The entry point of the SPARQL-parser.")
+ (:method ((construct SPARQL-Query) (query-string String))
+ (let ((trimmed-query-string (trim-whitespace-left query-string)))
+ (cond ((string-starts-with trimmed-query-string "SELECT")
+ (parse-prefixes construct
+ (string-after trimmed-query-string "SELECT")))
+ ((string-starts-with trimmed-query-string "PREFIX")
+ nil) ;TODO: implement
+ ((string-starts-with trimmed-query-string "BASE")
+ nil) ;TODO: implement
+ (t
+ (error (make-sparql-parser-condition
+ trimmed-query-string (original-query construct)
+ "SELECT, PREFIX or BASE")))))))
+
+
+(defgeneric parse-prefixes (construct query-string)
+ (:documentation "Sets the correponding prefix-tuples in the passed object.")
+ (:method ((construct SPARQL-Query) (query-string String))
+ (let ((trimmed-string (trim-whitespace-left query-string)))
+ (if (string-starts-with trimmed-string ":")
+ (let ((results
+ (parse-bracket-value (subseq trimmed-string 1) construct)))
+ (add-prefix construct *empty-label* (getf results :value))
+ (parser-start construct (getf results :query-string)))
+ (let* ((label-name
+ (trim-whitespace-right (string-until trimmed-string ":")))
+ (next-query-str
+ (trim-whitespace-left (string-after trimmed-string ":")))
+ (results (parse-bracket-value next-query-str construct)))
+ (add-prefix construct label-name (getf results :value))
+ (parser-start construct (getf results :query-string)))))))
+
+
+(defun parse-bracket-value(query-string query-object &key (open "<") (close ">"))
+ "A helper function that checks the value of a statement within
+ two brackets, i.e. <prefix-value>. A list of the
+ form (:query-string string :value string) is returned."
+ (declare (String query-string open close)
+ (SPARQL-Query query-object))
+ (let ((trimmed-string (trim-whitespace-left query-string)))
+ (if (and (string-starts-with trimmed-string open)
+ (> (length (string-after trimmed-string close)) 0))
+ (let* ((pref-url
+ (string-until (string-after trimmed-string open) close))
+ (next-query-str
+ (string-after pref-url close)))
+ (unless next-query-str
+ (error (make-sparql-parser-condition
+ trimmed-string (original-query query-object)
+ close)))
+ (list :query-string next-query-str
+ :value pref-url))
+ (error (make-sparql-parser-condition
+ trimmed-string (original-query query-object)
+ open)))))
+
+
+
+;((PREFIX bounding: <uri-prefix>)|(PREFIX : <uri-prefix>)*
+;(BASE <base-uri>)*)*
+;SELECT ?varName+
+;WHERE {
+;(({?subjectOrVarName predicateOrVarName objectOrVarName}?)*
+;({?FILTER (filterExpression)}?)*
+;(BASE <base-uri>)*)*
+;}
+;Grouping
+;{}
+;Base
+;BASE <uri>
+;…
+;<book>
+;-> uri/book
+;Literals
+;(“anyCharacter*“)|(‘anyCharacter*‘)((anyUri)|(@languageTag)){0,1}
+;
+;Variables
+;($anyChar*)|(?anyChar*)
+;?var = $var
+;Predicate object-lists
+;?x foaf:name ?name ;
+;foaf:mbox ?mbox .
+;This is the same as writing the triple patterns:
+;?x foaf:name ?name .
+;?x foaf:mbox ?mbox .
+;rdf:type
+;rdf:type = a
+;Empty Graph Pattern
+;The group pattern:
+;{ }
+;matches any graph (including the empty graph) with one solution that does not bind any variables. For example:
+;SELECT ?x
+;WHERE {}
+;matches with one solution in which variable x is not bound."
\ No newline at end of file
Modified: trunk/src/base-tools/base-tools.lisp
==============================================================================
--- trunk/src/base-tools/base-tools.lisp (original)
+++ trunk/src/base-tools/base-tools.lisp Wed Nov 17 16:41:59 2010
@@ -13,7 +13,14 @@
(:export :push-string
:when-do
:remove-null
- :full-path))
+ :full-path
+ :trim-whitespace-left
+ :trim-whitespace-right
+ :trim-whitespace
+ :string-starts-with
+ :string-starts-with-char
+ :string-until
+ :string-after))
(in-package :base-tools)
@@ -52,4 +59,53 @@
(full-path-string ""))
(dolist (segment segments)
(push-string segment full-path-string))
- (concatenate 'string full-path-string "/" (pathname-name pathname))))
\ No newline at end of file
+ (concatenate 'string full-path-string "/" (pathname-name pathname))))
+
+
+(defun trim-whitespace-left (value)
+ "Uses string-left-trim with a predefined character-list."
+ (declare (String value))
+ (string-left-trim '(#\Space #\Tab #\Newline) value))
+
+
+(defun trim-whitespace-right (value)
+ "Uses string-right-trim with a predefined character-list."
+ (declare (String value))
+ (string-right-trim '(#\Space #\Tab #\Newline) value))
+
+
+(defun trim-whitespace (value)
+ "Uses string-trim with a predefined character-list."
+ (declare (String value))
+ (string-trim '(#\Space #\Tab #\Newline) value))
+
+
+(defun string-starts-with (str prefix)
+ "Checks if string str starts with a given prefix."
+ (declare (string str prefix))
+ (string= str prefix :start1 0 :end1
+ (min (length prefix)
+ (length str))))
+
+
+(defun string-starts-with-char (begin str)
+ (equal (char str 0) begin))
+
+
+(defun string-until (str anchor)
+ "Returns a substring until the position of the passed anchor."
+ (declare (String str anchor))
+ (let ((pos (search anchor str)))
+ (if pos
+ (subseq str 0 pos)
+ str)))
+
+
+(defun string-after (str prefix)
+ "Returns the substring after the found prefix.
+ If there is no substring equal to prefix nil is returned."
+ (declare (String str prefix))
+ (let ((pos (search prefix str)))
+ (if pos
+ (subseq str (+ pos (length prefix)))
+ nil)))
\ No newline at end of file
Modified: trunk/src/isidorus.asd
==============================================================================
--- trunk/src/isidorus.asd (original)
+++ trunk/src/isidorus.asd Wed Nov 17 16:41:59 2010
@@ -41,9 +41,9 @@
:depends-on ("exceptions")))
:depends-on ("constants" "base-tools"))
(:module "TM-SPARQL"
- :components ((:file "sparql"
- :depends-on ("sparql_tokenizer"))
- (:file "sparql_tokenizer"))
+ :components ((:file "sparql")
+ (:file "sparql_parser"
+ :depends-on ("sparql")))
:depends-on ("constants" "base-tools" "model"))
(:module "xml"
:components ((:module "xtm"
Modified: trunk/src/model/datamodel.lisp
==============================================================================
--- trunk/src/model/datamodel.lisp (original)
+++ trunk/src/model/datamodel.lisp Wed Nov 17 16:41:59 2010
@@ -135,7 +135,6 @@
:list-instanceOf
:list-super-types
:in-topicmap
- :string-starts-with
:get-fragments
:get-fragment
:get-all-revisions
@@ -884,14 +883,6 @@
(slot-value construct (find-symbol "OID" 'elephant)))
-(defun string-starts-with (str prefix)
- "Checks if string str starts with a given prefix."
- (declare (string str prefix))
- (string= str prefix :start1 0 :end1
- (min (length prefix)
- (length str))))
-
-
;;; generic definitions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defgeneric mark-as-deleted (construct &key source-locator revision)
(:documentation "Mark a construct as deleted if it comes from the source
Modified: trunk/src/model/exceptions.lisp
==============================================================================
--- trunk/src/model/exceptions.lisp (original)
+++ trunk/src/model/exceptions.lisp Wed Nov 17 16:41:59 2010
@@ -17,10 +17,25 @@
:not-mergable-error
:missing-argument-error
:tm-reference-error
- :bad-type-error))
+ :bad-type-error
+ :missing-query-string-error
+ :sparql-parser-error))
(in-package :exceptions)
+
+(define-condition missing-query-string-error(error)
+ ((message
+ :initarg :message
+ :accessor message)))
+
+
+(define-condition sparql-parser-error(error)
+ ((message
+ :initarg :message
+ :accessor message)))
+
+
(define-condition inconsistent-file-error(error)
((message
:initarg :message
Modified: trunk/src/xml/rdf/exporter.lisp
==============================================================================
--- trunk/src/xml/rdf/exporter.lisp (original)
+++ trunk/src/xml/rdf/exporter.lisp Wed Nov 17 16:41:59 2010
@@ -8,7 +8,8 @@
;;+-----------------------------------------------------------------------------
(defpackage :rdf-exporter
- (:use :cl :cxml :elephant :datamodel :isidorus-threading :datamodel)
+ (:use :cl :cxml :elephant :datamodel :isidorus-threading
+ :datamodel :base-tools)
(:import-from :constants
*rdf-ns*
*rdfs-ns*
Modified: trunk/src/xml/xtm/tools.lisp
==============================================================================
--- trunk/src/xml/xtm/tools.lisp (original)
+++ trunk/src/xml/xtm/tools.lisp Wed Nov 17 16:41:59 2010
@@ -275,15 +275,11 @@
(defun xpath-single-child-elem-by-qname (elem namespace-uri local-name)
- "Returns some child of elem that has qname (namespace-uri local-name) or
-nil if no such child exists."
+ "Returns some child of elem that has qname (namespace-uri local-name)
+ or nil if no such child exists."
(declare (dom:element elem))
- (find-if (lambda (el) (has-qname el namespace-uri local-name)) (dom:child-nodes elem))
- )
-
-
-(defun string-starts-with (begin str)
- (equal (char str 0) begin))
+ (find-if (lambda (el) (has-qname el namespace-uri local-name))
+ (dom:child-nodes elem)))
(defun xpath-select-location-path (elem list-of-qnames)
@@ -297,7 +293,7 @@
(cond
(list-of-qnames
(cond
- ((string-starts-with #\@ local-name)
+ ((string-starts-with-char #\@ local-name)
(list (dom:get-attribute-node-ns elem namespace-uri (string-left-trim "@" local-name))))
(t
(apply #'append
1
0

[isidorus-cvs] r339 - tags/textgrid-service/src/rest_interface trunk/src trunk/src/rest_interface
by Lukas Giessmann 12 Nov '10
by Lukas Giessmann 12 Nov '10
12 Nov '10
Author: lgiessmann
Date: Fri Nov 12 18:23:19 2010
New Revision: 339
Log:
fixed ticket #93 => implemented a hunchentoot post handler that imports the received data via the xtm2.0 importer
Modified:
tags/textgrid-service/src/rest_interface/rest-interface.lisp
tags/textgrid-service/src/rest_interface/set-up-json-interface.lisp
trunk/src/isidorus.asd
trunk/src/rest_interface/rest-interface.lisp
trunk/src/rest_interface/set-up-json-interface.lisp
Modified: tags/textgrid-service/src/rest_interface/rest-interface.lisp
==============================================================================
--- tags/textgrid-service/src/rest_interface/rest-interface.lisp (original)
+++ tags/textgrid-service/src/rest_interface/rest-interface.lisp Fri Nov 12 18:23:19 2010
@@ -41,7 +41,8 @@
:*ajax-user-interface-file-path*
:*ajax-javascript-directory-path*
:*ajax-javascript-url-prefix*
- :*mark-as-deleted-url*))
+ :*mark-as-deleted-url*
+ :*xtm-commit-prefix*))
(in-package :rest-interface)
Modified: tags/textgrid-service/src/rest_interface/set-up-json-interface.lisp
==============================================================================
--- tags/textgrid-service/src/rest_interface/set-up-json-interface.lisp (original)
+++ tags/textgrid-service/src/rest_interface/set-up-json-interface.lisp Fri Nov 12 18:23:19 2010
@@ -25,8 +25,9 @@
(defparameter *ajax-user-interface-css-directory-path* "ajax/css") ;the directory contains the css files
(defparameter *ajax-user-interface-file-path* "ajax/isidorus.html") ;the file path to the HTML file implements the user interface
(defparameter *ajax-javascript-directory-path* "ajax/javascripts") ;the directory which contains all necessary javascript files
-(defparameter *ajax-javascript-url-prefix* "/javascripts") ; the url prefix of all javascript files
-(defparameter *mark-as-deleted-url* "/mark-as-deleted") ; the url suffix that calls the mark-as-deleted handler
+(defparameter *ajax-javascript-url-prefix* "/javascripts") ;the url prefix of all javascript files
+(defparameter *mark-as-deleted-url* "/mark-as-deleted") ;the url suffix that calls the mark-as-deleted handler
+(defparameter *xtm-commit-prefix* "/import/xtm/2.0/(.+)$") ;the url to commit a TM-fragment in XTM 2.0 format, the regular expression represents the topic map id
(defun set-up-json-interface (&key (json-get-prefix *json-get-prefix*)
(get-rdf-prefix *get-rdf-prefix*)
@@ -45,7 +46,8 @@
(ajax-user-interface-css-directory-path *ajax-user-interface-css-directory-path*)
(ajax-javascripts-directory-path *ajax-javascript-directory-path*)
(ajax-javascripts-url-prefix *ajax-javascript-url-prefix*)
- (mark-as-deleted-url *mark-as-deleted-url*))
+ (mark-as-deleted-url *mark-as-deleted-url*)
+ (xtm-commit-prefix *xtm-commit-prefix*))
"registers the json im/exporter to the passed base-url in hunchentoot's dispatch-table
and also registers a file-hanlder to the html-user-interface"
@@ -112,6 +114,9 @@
(create-regex-dispatcher json-commit-url #'json-commit)
hunchentoot:*dispatch-table*)
(push
+ (create-regex-dispatcher xtm-commit-prefix #'xtm-import-handler)
+ hunchentoot:*dispatch-table*)
+ (push
(create-regex-dispatcher json-get-summary-url #'return-topic-summaries)
hunchentoot:*dispatch-table*)
(push
@@ -378,6 +383,29 @@
(setf (hunchentoot:return-code*) hunchentoot:+http-bad-request+))))
+(defun xtm-import-handler (&optional tm-id)
+ "Imports the received data as XTM 2.0 topic map."
+ (assert tm-id)
+ (handler-case
+ (if (eql (hunchentoot:request-method*) :POST)
+ (let ((external-format (flexi-streams:make-external-format
+ :UTF-8 :eol-style :LF)))
+ (let ((xml-data (hunchentoot:raw-post-data
+ :external-format external-format
+ :force-text t)))
+ (let ((xml-dom
+ (dom:document-element
+ (cxml:parse xml-data (cxml-dom:make-dom-builder)))))
+ (xml-importer:importer xml-dom :tm-id tm-id
+ :xtm-id (xml-importer::get-uuid))
+ (format nil ""))))
+ (setf (hunchentoot:return-code*) hunchentoot:+http-bad-request+))
+ (condition (err)
+ (progn
+ (setf (hunchentoot:return-code*) hunchentoot:+http-internal-server-error+)
+ (setf (hunchentoot:content-type*) "text")
+ (format nil "Condition: \"~a\"" err)))))
+
;; =============================================================================
;; --- some helper functions ---------------------------------------------------
;; =============================================================================
Modified: trunk/src/isidorus.asd
==============================================================================
--- trunk/src/isidorus.asd (original)
+++ trunk/src/isidorus.asd Fri Nov 12 18:23:19 2010
@@ -101,8 +101,8 @@
:depends-on ("rest-interface"))
(:file "read"
:depends-on ("rest-interface")))
- :depends-on ("model"
- "atom"
+ :depends-on ("model"
+ "atom"
"xml"
"json"
"threading"))
Modified: trunk/src/rest_interface/rest-interface.lisp
==============================================================================
--- trunk/src/rest_interface/rest-interface.lisp (original)
+++ trunk/src/rest_interface/rest-interface.lisp Fri Nov 12 18:23:19 2010
@@ -10,6 +10,7 @@
(defpackage :rest-interface
(:nicknames :rest)
(:use :cl :hunchentoot
+ :cxml
:constants
:atom
:datamodel
@@ -40,7 +41,8 @@
:*ajax-user-interface-url*
:*ajax-user-interface-file-path*
:*ajax-javascript-directory-path*
- :*ajax-javascript-url-prefix*))
+ :*ajax-javascript-url-prefix*
+ :*xtm-commit-prefix*))
(in-package :rest-interface)
Modified: trunk/src/rest_interface/set-up-json-interface.lisp
==============================================================================
--- trunk/src/rest_interface/set-up-json-interface.lisp (original)
+++ trunk/src/rest_interface/set-up-json-interface.lisp Fri Nov 12 18:23:19 2010
@@ -20,6 +20,9 @@
(defparameter *get-rdf-prefix* "/json/get/rdf/(.+)$")
;the url to commit a json fragment by "put" or "post"
(defparameter *json-commit-url* "/json/commit/?$")
+;the url to commit a TM-fragment in XTM 2.0 format, the regular
+;expression represents the topic map id
+(defparameter *xtm-commit-prefix* "/import/xtm/2.0/(.+)$")
;the url to get all topic psis of isidorus -> localhost:8000/json/psis
(defparameter *json-get-all-psis* "/json/psis/?$")
;the url to get a summary of all topic stored in isidorus; you have to set the
@@ -75,7 +78,8 @@
(ajax-javascripts-directory-path *ajax-javascript-directory-path*)
(ajax-javascripts-url-prefix *ajax-javascript-url-prefix*)
(mark-as-deleted-url *mark-as-deleted-url*)
- (latest-revision-url *latest-revision-url*))
+ (latest-revision-url *latest-revision-url*)
+ (xtm-commit-prefix *xtm-commit-prefix*))
"registers the json im/exporter to the passed base-url in hunchentoot's dispatch-table
and also registers a file-hanlder to the html-user-interface"
@@ -153,6 +157,9 @@
(create-regex-dispatcher mark-as-deleted-url #'mark-as-deleted-handler)
hunchentoot:*dispatch-table*)
(push
+ (create-regex-dispatcher xtm-commit-prefix #'xtm-import-handler)
+ hunchentoot:*dispatch-table*)
+ (push
(create-regex-dispatcher latest-revision-url #'return-latest-revision)
hunchentoot:*dispatch-table*))
@@ -450,9 +457,31 @@
(setf (hunchentoot:return-code*) hunchentoot:+http-internal-server-error+)
(setf (hunchentoot:content-type*) "text")
(format nil "Condition: \"~a\"" err)))))
-
+(defun xtm-import-handler (&optional tm-id)
+ "Imports the received data as XTM 2.0 topic map."
+ (assert tm-id)
+ (handler-case
+ (if (eql (hunchentoot:request-method*) :POST)
+ (let ((external-format (flexi-streams:make-external-format
+ :UTF-8 :eol-style :LF)))
+ (let ((xml-data (hunchentoot:raw-post-data
+ :external-format external-format
+ :force-text t)))
+ (let ((xml-dom
+ (dom:document-element
+ (cxml:parse xml-data (cxml-dom:make-dom-builder)))))
+ (xml-importer:importer xml-dom :tm-id tm-id
+ :xtm-id (xml-importer::get-uuid))
+ (format nil ""))))
+ (setf (hunchentoot:return-code*) hunchentoot:+http-bad-request+))
+ (condition (err)
+ (progn
+ (setf (hunchentoot:return-code*) hunchentoot:+http-internal-server-error+)
+ (setf (hunchentoot:content-type*) "text")
+ (format nil "Condition: \"~a\"" err)))))
+
;; =============================================================================
;; --- some helper functions ---------------------------------------------------
;; =============================================================================
1
0
Author: lgiessmann
Date: Fri Nov 12 16:57:51 2010
New Revision: 338
Log:
added the new textgrid-TMCL as XTM 2.0 file
Added:
trunk/src/unit_tests/textgrid.xtm
trunk/src/unit_tests/textgrid_old.xtm
Modified:
trunk/src/isidorus.asd
trunk/src/model/trivial-queries.lisp
Modified: trunk/src/isidorus.asd
==============================================================================
--- trunk/src/isidorus.asd (original)
+++ trunk/src/isidorus.asd Fri Nov 12 16:57:51 2010
@@ -107,7 +107,9 @@
"json"
"threading"))
(:module "unit_tests"
- :components ((:static-file "dangling_topicref.xtm")
+ :components ((:static-file "textgrid.xtm")
+ (:static-file "textgrid_old.xtm")
+ (:static-file "dangling_topicref.xtm")
(:static-file "inconsistent.xtm")
(:static-file "notificationbase.xtm")
(:static-file "notification_merge1.xtm")
Modified: trunk/src/model/trivial-queries.lisp
==============================================================================
--- trunk/src/model/trivial-queries.lisp (original)
+++ trunk/src/model/trivial-queries.lisp Fri Nov 12 16:57:51 2010
@@ -338,4 +338,4 @@
(declare (integer revision))
(let ((all-supertypes (supertypes construct :revision revision)))
(when (find supertype all-supertypes)
- all-supertypes))))
\ No newline at end of file
+ all-supertypes))))
Added: trunk/src/unit_tests/textgrid.xtm
==============================================================================
--- (empty file)
+++ trunk/src/unit_tests/textgrid.xtm Fri Nov 12 16:57:51 2010
@@ -0,0 +1,4826 @@
+<?xml version="1.0" encoding="utf-8"?>
+<tm:topicMap version="2.0" xmlns:tm="http://www.topicmaps.org/xtm/">
+ <!-- ===================================================================== -->
+ <!-- === TMCL meta-model topics ========================================== -->
+ <!-- ===================================================================== -->
+ <tm:topic id="topictype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-type"/>
+ <!-- naming of psis: Prague, March 25-27, 2008, page 12 -->
+ <tm:instanceOf>
+ <tm:topicRef href="#topictype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="occurrencetype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-type"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topictype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="associationtype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-type"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topictype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="roletype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/role-type"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topictype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="nametype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/name-type"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topictype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="scopetype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/scope-type"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topictype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- role types used to include the topictype metatypes in associations -->
+ <tm:topic id="topictype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-type-role"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#roletype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="occurrencetype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-type-role"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#roletype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="associationtype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-type-role"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#roletype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="roletype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/role-type-role"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#roletype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="otherroletype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/other-role-type-role"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#roletype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="othertopictype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/other-topic-type-role"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#roletype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="nametype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/name-type-role"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#roletype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="scopetype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/scope-type-role"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#roletype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- the constraint roletype -->
+ <tm:topic id="constraint-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/constraint-role"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#roletype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- ===================================================================== -->
+ <!-- === TMCL model topics =============================================== -->
+ <!-- ===================================================================== -->
+
+ <!-- the constraint topic is the common supertype of all constraint types
+ defined by TMCL. -->
+ <tm:topic id="constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topictype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- this occurrence type is used to type a single occurrence on each
+ constraint type. This occurrence holds the TMQL value used to
+ evaluate constraint instances for validity. -->
+ <tm:topic id="validation-expression">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/validation-expression"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- the association type used to bind different components into a
+ constraint -->
+ <tm:topic id="applies-to">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/applies-to"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#associationtype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- the card min facet is used on many constraint types -->
+ <tm:topic id="card-min">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/card-min"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- the card max facet is used on many constraint types -->
+ <tm:topic id="card-max">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/card-max"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- the reg exp facet is used on many constraint types -->
+ <tm:topic id="regexp">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/reg-exp"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- the datatype facet is used on many constraint types -->
+ <tm:topic id="datatype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/datatype"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- ===================================================================== -->
+ <!-- === topics for super-subtype-associations (ako) ===================== -->
+ <!-- ===================================================================== -->
+
+ <tm:topic id="supertype-subtype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/iso13250/model/supertype-subtype"/>
+ </tm:topic>
+
+ <tm:topic id="supertype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/iso13250/model/supertype"/>
+ </tm:topic>
+
+ <tm:topic id="subtype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/iso13250/model/subtype"/>
+ </tm:topic>
+
+
+ <!-- ===================================================================== -->
+ <!-- === schema type and ?schema definitions ============================= -->
+ <!-- ===================================================================== -->
+
+ <!-- constraints can be bound to a schema -->
+ <tm:topic id="schema">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/schema"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topictype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- ===================================================================== -->
+ <!-- === TMCL constraint types =========================================== -->
+ <!-- ===================================================================== -->
+
+ <!-- topictype-constraint -->
+ <tm:topic id="topictype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-type-constraint"/>
+ </tm:topic>
+ <!-- standard constraints doesn't own a validation-expression-occurrence: Prague, March 25-27, 2008, page 34-36 -->
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#topictype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- associationtype-constraint -->
+ <tm:topic id="associationtype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-type-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#associationtype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- roletype-constraint -->
+ <tm:topic id="roletype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/role-type-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#roletype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- occurrencetype-constraint -->
+ <tm:topic id="occurrencetype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-type-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#occurrencetype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- nametype-constraint -->
+ <tm:topic id="nametype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/name-type-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#nametype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- abstract-topictype-constraint -->
+ <tm:topic id="abstract-topictype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/abstract-topic-type-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#abstract-topictype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- exclusive-instance -->
+ <tm:topic id="exclusive-instance">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/exclusive-instance"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#exclusive-instance"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+ <!-- ===================================================================== -->
+ <!-- === subjectidentifier/locator constraints =========================== -->
+ <!-- ===================================================================== -->
+
+ <!-- subjectlocator-constraint -->
+ <tm:topic id="subjectlocator-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/subject-locator-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#subjectlocator-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- subjectidentifier-constraint -->
+ <tm:topic id="subjectidentifier-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/subject-identifier-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#subjectidentifier-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- ===================================================================== -->
+ <!-- === names/occurrences/associations/association roles ================ -->
+ <!-- ===================================================================== -->
+
+ <!-- topicname-constraint -->
+ <tm:topic id="topicname-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-name-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#topicname-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- topicoccurrence-constraint -->
+ <tm:topic id="topicoccurrence-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-occurrence-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- occurrencedatatype-constraint -->
+ <tm:topic id="occurrencedatatype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-datatype-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#occurrencedatatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- uniqueoccurrence-constraint -->
+ <tm:topic id="uniqueoccurrence-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/unique-occurrence-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#uniqueoccurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- associationrole-constraint -->
+ <tm:topic id="associationrole-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-role-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#associationrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- roleplayer-constraint -->
+ <tm:topic id="roleplayer-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/role-player-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#roleplayer-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- otherrole-constraint -->
+ <tm:topic id="otherrole-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/other-role-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- ===================================================================== -->
+ <!-- === scopes ========================================================== -->
+ <!-- ===================================================================== -->
+
+ <!-- nametypescope-constraint -->
+ <tm:topic id="nametypescope-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/name-type-scope-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#nametypescope-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- occurrencetypescope-constraint -->
+ <tm:topic id="occurrencetypescope-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-type-scope-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#occurrencetypescope-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- associationtypescope-constraint -->
+ <tm:topic id="associationtypescope-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-type-scope-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#supertype-subtype"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#subtype"/>
+ </tm:type>
+ <tm:topicRef href="#associationtypescope-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#supertype"/>
+ </tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: type handling ==================================== -->
+ <!-- ===================================================================== -->
+
+ <!-- only topics that are instances of topictype are allowed as topic
+ types -->
+ <tm:topic id="ttc">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/ttc"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topictype-constraint"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- only topics that are instances of associationtype are allowed as
+ association types -->
+ <tm:topic id="atc">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/atc"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#associationtype-constraint"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- only topics that are instances of roletype are allowed as
+ association role types -->
+ <tm:topic id="rtc">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/rtc"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#roletype-constraint"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- only topics that are instances of occurrencetype are allowed as
+ occurrence types -->
+ <tm:topic id="otc">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/otc"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype-constraint"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- only topics that are instances of nametype are allowed as
+ name types -->
+ <tm:topic id="ntc">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/ntc"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#nametype-constraint"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: base types ======================================= -->
+ <!-- ===================================================================== -->
+
+ <!-- ===================================================================== -->
+ <!-- === topictype service =============================================== -->
+ <!-- ===================================================================== -->
+ <tm:topic id="service">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Service"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topictype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- name types for the topictype service -->
+ <tm:topic id="service-name">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Service-Name"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#nametype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- occurrence types for the topictype service-->
+ <tm:topic id="service-operation">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Service-Operation"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="service-type">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Service-Type"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="service-description">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Service-Description"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="service-keywords">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Service-Keywords"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="description-location-uri">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Description-Location-URI"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="inline-description-location">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Inline-Description-Location"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="description-location-body">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Description-Location-Body"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="target-namespace">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Target-Namespace"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="use-target-ns">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Use-Target-NS"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="service-owner">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Service-Owner"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="service-identifier">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Service-Identifier"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="textgrid-url">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Textgrid-URL"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="tg-approved">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/TG-Approved"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+
+ <!-- ===================================================================== -->
+ <!-- === topictype hash-object =========================================== -->
+ <!-- ===================================================================== -->
+ <tm:topic id="hash-object">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Hash-Object"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topictype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- occurrence types for the topic type hash-object -->
+ <tm:topic id="hash-type">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Hash-Type"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="hash-key">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Hash-Key"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="hash-value">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Hash-Value"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="hash-environment">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Hash-Environment"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+
+ <!-- ===================================================================== -->
+ <!-- === topictype parameter ============================================ -->
+ <!-- ===================================================================== -->
+ <tm:topic id="parameter">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Parameter"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topictype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- name types for the topic type parameter -->
+ <tm:topic id="parameter-name">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Parameter-Name"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#nametype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- occurrence types for the topic type parameter -->
+ <tm:topic id="parameter-type">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Parameter-Type"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="parameter-id">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Parameter-ID"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="parameter-param">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Parameter-Param"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="parameter-mime-type">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Parameter-Mime-Type"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="parameter-multiple">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Parameter-Multiple"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="parameter-crud">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Parameter-Crud"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="parameter-needs-b64-encoding">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Parameter-Needs-B64-Encoding"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+
+ <!-- ===================================================================== -->
+ <!-- === topictype parameter-config ====================================== -->
+ <!-- ===================================================================== -->
+ <tm:topic id="parameter-config">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Parameter-Config"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topictype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- name types for the topic type parameter -->
+ <tm:topic id="parameter-config-name">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Parameter-Config-Name"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#nametype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- occurrence types for the topic type parameter -->
+ <tm:topic id="parameter-config-id">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Parameter-Config-ID"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="parameter-config-default">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Parameter-Config-Default"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="parameter-config-form">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Parameter-Config-Form"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="parameter-config-data">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Parameter-Config-Data"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencetype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+
+ <!-- ===================================================================== -->
+ <!-- === association type has-hash ======================================= -->
+ <!-- ===================================================================== -->
+
+ <!-- association has-hash -->
+ <tm:topic id="has-hash">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Has-Hash"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#associationtype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- roles -->
+ <tm:topic id="service-role">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Service-Role"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#roletype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="hash-role">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Hash-Role"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#roletype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+
+ <!-- ===================================================================== -->
+ <!-- === association type has-parameter ================================== -->
+ <!-- ===================================================================== -->
+
+ <!-- association has-parameter -->
+ <tm:topic id="has-parameter">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Has-parameter"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#associationtype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- roles -->
+ <!-- service role as in has-hash-->
+
+ <tm:topic id="parameter-role">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Parameter-Role"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#roletype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+
+
+ <!-- ===================================================================== -->
+ <!-- === association type has-config ===================================== -->
+ <!-- ===================================================================== -->
+
+ <!-- association has-config -->
+ <tm:topic id="has-config">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Has-config"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#associationtype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <!-- roles -->
+ <!-- parameter role as in has-parameter-->
+
+ <tm:topic id="config-role">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/Config-role"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#roletype"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: exclusive type constraint ======================== -->
+ <!-- ===================================================================== -->
+
+ <!-- instances composed of the types service, hash-object, parameter,
+ parameter-config are not allowed-->
+ <tm:topic id="exc">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/exc"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#exclusive-instance"/>
+ </tm:instanceOf>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#exc"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#exc"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-object"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#exc"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#exc"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: subjectIdentifier constraints ==================== -->
+ <!-- ===================================================================== -->
+ <!-- a topic of the type service has to have a psi of the form
+ "^http://textgrid.org/serviceregistry/service/.+$",
+ a topic of the type parameter has to have a psi of the form
+ "^http://textgrid.org/serviceregistry/parameter/.+$",
+ a topic of the type hash-object has to have a psi of the form
+ "^http://textgrid.org/serviceregistry/hash/.+$",
+ and a topic of the parameter-config poem has to have a psi of the form
+ "^http://some.where/psis/parameter-config/.+$".
+ further all topics can have mor psis of the form "^.+$" -->
+
+ <!-- subjectidentifier of service -->
+ <tm:topic id="sic-service">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/sic-service"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#subjectidentifier-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^http://textgrid.org/serviceregistry/service/.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#sic-service"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- subjectidentifier of hash-object -->
+ <tm:topic id="sic-hash-object">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/sic-hash-object"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#subjectidentifier-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^http://textgrid.org/serviceregistry/hash/.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#sic-hash-object"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-object"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- subjectidentifier of parameter -->
+ <tm:topic id="sic-parameter">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/sic-parameter"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#subjectidentifier-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^http://textgrid.org/serviceregistry/parameter/.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#sic-parameter"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- subjectidentifier of parameter-config -->
+ <tm:topic id="sic-parameter-config">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/sic-parameter-config"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#subjectidentifier-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^http://textgrid.org/serviceregistry/parameter-config/.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#sic-parameter-config"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: subjectLocator constraints ======================= -->
+ <!-- ===================================================================== -->
+ <!-- all instances of service, parameter, hash-object and parameter-config
+ are not allowed to own a subjectLocator -->
+
+ <tm:topic id="slc-all">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/slc-all"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#subjectlocator-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.*</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#slc-all"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#slc-all"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#slc-all"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-object"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#slc-all"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: name constraints ================================= -->
+ <!-- ===================================================================== -->
+ <!-- instances of the type service has to own a name of the type service-name.
+ it must be valid to the regular expression ".+".
+ instances of the type parameter has one name of the type parameter-name
+ with the regular expression ".+" -->
+
+ <!-- service service name -->
+ <tm:topic id="service-name-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/service-name-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicname-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#nametype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-name"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- parameter parameter name -->
+ <tm:topic id="parameter-name-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/parameter-name-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicname-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#nametype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-name"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- parameter-config parameter-config name -->
+ <tm:topic id="parameter-config-name-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/parameter-config-name-constra…"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicname-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#nametype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-name"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: occurence constraints ============================ -->
+ <!-- ===================================================================== -->
+ <!-- the topictype service owns the foolowing occurrences:
+ *service-operation => xml:string => ".+" => {1}
+ *sericve-type => xml:string => ".+" => {1}
+ *service-description => xml:string => ".+" => {1}
+ *service-keywords => xml:string => ".+" => {0,1}
+ *description-location-uri => xml:anyUri => ".+" => {0,1}
+ *inline-description-location => xml:string => ".+" => {0,1}
+ *description-loction-body => xml:string => ".+" => {0,1}
+ *target-namespace => xml:string => ".+" => {0,1}
+ *use-target-ns => xml:Boolean => "(true)|(false)" => {0,1}
+ *service-owner => xml:string => ".+" => {1}
+ *service-identifier => xml:string => ".+" => {1} => unique-constraint
+ *textgrid-url => xml:anyUri => ".+" => {1}
+ *tg-approved => xml:Boolean => "(true)|(false)" => {1}
+
+ the topictype hash-object owns the following occurrences:
+ *hash-type => xml:string => ".+" => {1}
+ *hash-key => xml:string => ".+" => {1}
+ *hash-value => xml:string => ".+" => {1}
+ *hash-environment => xml:string => ".+" => {1}
+
+ the topictype parameter owns the following occurrences:
+ *parameter-type => xml:string => ".+" => {1}
+ *parameter-id => xml:string => ".+" => {1} => unique-constraint
+ *parameter-param => xml:string => ".+" => {1}
+ *parameter-mime-type => xml:string => ".+" => {1}
+ *parameter-multiple => xml:Boolean => "(true)|(false)" => {0,1}
+ *parameter-crud => xml:Boolean => "(true)|(false)" => {0,1}
+ *parameter-needs-b64-encoding => xml:Boolean => "(true)|(false)" => {1}
+
+ the topictype parameter-config owns the following occurrences:
+ *parameter-config-id => xml:string => ".+" => {1} => unique-constraint
+ *parameter-config-default => xml:string => "(true)|(false)" => {0,1}
+ *parameter-config-form => xml:string => ".+" => {1}
+ *parameter-config-data => xml:string => ".+" => {0,1}-->
+
+ <!-- unique occurence constraint -->
+ <tm:topic id="unique-id-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/unique-id-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#uniqueoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.*</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <!-- occurrence datatypes -->
+ <tm:topic id="string-datatype-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/string-datatype-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencedatatype-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#datatype"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">http://www.w3.org/2001/XMLSchema#string</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="uri-datatype-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/uri-datatype-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencedatatype-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#datatype"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">http://www.w3.org/2001/XMLSchema#anyUri</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="boolean-datatype-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/boolean-datatype-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#occurrencedatatype-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#datatype"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">http://www.w3.org/2001/XMLSchema#boolean</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <!-- service operation occurrence -->
+ <tm:topic id="service-operation-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/service-operation-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-operation-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-operation-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-operation"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-operation"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- service type occurrence -->
+ <tm:topic id="service-type-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/service-type-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-type-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-type-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-type"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-type"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- service description occurrence -->
+ <tm:topic id="service-description-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/service-description-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-description-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-description-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-description"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-description"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- service keywords occurrence -->
+ <tm:topic id="service-keywords-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/service-keywords-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-keywords-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-keywords-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-keywords"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-keywords"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- service description location uri occurrence -->
+ <tm:topic id="description-location-uri-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/description-location-uri-cons…"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#description-location-uri-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#description-location-uri-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#description-location-uri"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#uri-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#description-location-uri"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- service inline description location occurrence -->
+ <tm:topic id="inline-description-location-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/inline-description-location-c…"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">(true)|(false)</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#inline-description-location-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#inline-description-location-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#inline-description-location"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#boolean-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#inline-description-location"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- service description location body occurrence -->
+ <tm:topic id="description-location-body-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/description-location-body-con…"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#description-location-body-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#description-location-body-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#description-location-body"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#description-location-body"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- service target namespace occurrence -->
+ <tm:topic id="target-namespace-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/target-namespace-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#target-namespace-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#target-namespace-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#target-namespace"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#target-namespace"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- service use target ns occurrence -->
+ <tm:topic id="use-target-ns-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/use-target-ns-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">(true)|(false)</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#use-target-ns-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#use-target-ns-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#use-target-ns"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#boolean-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#use-target-ns"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- service owner occurrence -->
+ <tm:topic id="service-owner-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/service-owner-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-owner-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-owner-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-owner"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-owner"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- service identifier occurrence -->
+ <tm:topic id="service-identifier-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/service-identifier-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-identifier-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-identifier-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-identifier"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-identifier"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#unique-id-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#unique-id-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-identifier"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- service textgrid url occurrence -->
+ <tm:topic id="textgrid-url-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/textgrid-url-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#textgrid-url-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#textgrid-url-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#textgrid-url"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#uri-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#textgrid-url"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- service tg-approved occurrence -->
+ <tm:topic id="tg-approved-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/tg-approved-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">(true)|(false)</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#tg-approved-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#tg-approved-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#tg-approved"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#boolean-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#tg-approved"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- hash-object type occurrence -->
+ <tm:topic id="hash-type-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/hash-type-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-type-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-object"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-type-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-type"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-type"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- hash-object key occurrence -->
+ <tm:topic id="hash-key-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/hash-key-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-key-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-object"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-key-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-key"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-key"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- hash-object value occurrence -->
+ <tm:topic id="hash-value-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/hash-value-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-value-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-object"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-value-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-value"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-value"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- hash-object environment occurrence -->
+ <tm:topic id="hash-environment-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/hash-environment-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-environment-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-object"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-environment-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-environment"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-environment"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- parameter type occurrence -->
+ <tm:topic id="parameter-type-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/parameter-type-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-type-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-type-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-type"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-type"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- parameter id occurrence -->
+ <tm:topic id="parameter-id-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/parameter-id-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-id-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-id-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-id"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-id"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#unique-id-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#unique-id-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-id"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- parameter param occurrence -->
+ <tm:topic id="parameter-param-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/parameter-param-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-param-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-param-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-param"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-param"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- parameter mime type occurrence -->
+ <tm:topic id="parameter-mime-type-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/parameter-mime-type-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-mime-type-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-mime-type-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-mime-type"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-mime-type"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- parameter multiple occurrence -->
+ <tm:topic id="parameter-multiple-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/parameter-multiple-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">(true)|(false)</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-multiple-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-multiple-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-multiple"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#boolean-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-multiple"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- parameter crud occurrence -->
+ <tm:topic id="parameter-crud-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/parameter-crud-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">(true)|(false)</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-crud-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-crud-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-crud"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#boolean-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-crud"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- parameter needs b64 encoding occurrence -->
+ <tm:topic id="parameter-needs-b64-encoding-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/parameter-needs-b64-encoding-…"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">(false)|(true)</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-needs-b64-encoding-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-needs-b64-encoding-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-needs-b64-encoding"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#boolean-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-needs-b64-encoding"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- parameter-config id occurrence -->
+ <tm:topic id="parameter-config-id-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/parameter-config-id-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-id-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-id-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-id"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-id"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#unique-id-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#unique-id-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-id"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- parameter-config default occurrence -->
+ <tm:topic id="parameter-config-default-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/parameter-config-default-cons…"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">(false)|(true)</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-default-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-default-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-default"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#boolean-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-default"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- parameter-config form occurrence -->
+ <tm:topic id="parameter-config-form-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/parameter-config-form-constra…"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-form-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-form-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-form"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-form"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- parameter-config data occurrence -->
+ <tm:topic id="parameter-config-data-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/parameter-config-data-constra…"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.+</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-data-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-data-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-data"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config-data"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: association (-role) constraints ================== -->
+ <!-- ===================================================================== -->
+ <!-- the topictype service is related with the topictype hash-object via an
+ association of the type has-hash with the roles service-role|service and
+ hash-role|hash-object -->
+
+ <!-- the hash role has to appear exactly once in an association of type
+ has-hash -->
+ <tm:topic id="hash-role-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/hash-role-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#associationrole-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#associationtype-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-hash"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#roletype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-role"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- the hash role owns a player of the type hash-object -->
+ <tm:topic id="hash-role-player-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/hash-role-player-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#roleplayer-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-object"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#associationtype-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-hash"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#roletype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-role"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- otherrole-constraint:
+ If there is a role of the type hash-role with a player of the type
+ hash-object there must be another role of the type service-role with
+ a player of the type service. -->
+ <tm:topic id="has-hash-otherrole-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/has-hash-otherrole-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#otherrole-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-hash-otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#associationtype-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-hash"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-hash-otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#roletype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-role"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-hash-otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#hash-object"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-hash-otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#otherroletype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-role"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-hash-otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#othertopictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- the parameter role has to appear exactly once in an association of type
+ has-parameter -->
+ <tm:topic id="parameter-role-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/parameter-role-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#associationrole-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#associationtype-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#roletype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-role"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- the parameter role owns a player of the type hash-object -->
+ <tm:topic id="parameter-role-player-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/parameter-role-player-constra…"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#roleplayer-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#associationtype-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#roletype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-role"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- otherrole-constraint:
+ If there is a role of the type parameter-role with a player of the type
+ parameter there must be another role of the type service-role with
+ a player of the type service. -->
+ <tm:topic id="has-parameter-otherrole-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/has-parameter-otherrole-const…"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#otherrole-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-parameter-otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#associationtype-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-parameter-otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#roletype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-role"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-parameter-otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-parameter-otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#otherroletype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service-role"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-parameter-otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#othertopictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- the config role has to appear exactly once in an association of type
+ has-config -->
+ <tm:topic id="config-role-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/config-role-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#associationrole-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#config-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#associationtype-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-config"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#config-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#roletype-role"/>
+ </tm:type>
+ <tm:topicRef href="#config-role"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- the config role owns a player of the type parameter-config -->
+ <tm:topic id="config-role-player-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/config-role-player-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#roleplayer-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#config-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#config-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#associationtype-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-config"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#config-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#roletype-role"/>
+ </tm:type>
+ <tm:topicRef href="#config-role"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- otherrole-constraint:
+ If there is a role of the type config-role with a player of the type
+ parameter-config there must be another role of the type parameter-role
+ with a player of the type parameter. -->
+ <tm:topic id="has-config-otherrole-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/metamodel/has-config-otherrole-constrai…"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#otherrole-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-config-otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#associationtype-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-config"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-config-otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#roletype-role"/>
+ </tm:type>
+ <tm:topicRef href="#config-role"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-config-otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-config"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-config-otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#otherroletype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter-role"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#has-config-otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#othertopictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+</tm:topicMap>
\ No newline at end of file
Added: trunk/src/unit_tests/textgrid_old.xtm
==============================================================================
--- (empty file)
+++ trunk/src/unit_tests/textgrid_old.xtm Fri Nov 12 16:57:51 2010
@@ -0,0 +1,3282 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<tm:topicMap version="2.0" xmlns:tm="http://www.topicmaps.org/xtm/">
+ <!-- ======================================================================= -->
+ <!-- Isidorus -->
+ <!-- (c) 2008-2010 Marc Kuester, Christoph Ludwig, Lukas Georgieff -->
+ <!-- -->
+ <!-- Isidorus is freely distributable under the LLGPL license. -->
+ <!-- This ajax module uses the frameworks PrototypeJs and Scriptaculous, -->
+ <!-- both are distributed under the MIT license. -->
+ <!-- You can find a detailed description in trunk/docs/LLGPL-LICENSE.txt, -->
+ <!-- trunk/docs/LGPL-LICENSE.txt and in -->
+ <!-- trunk/src/ajax/javascripts/external/MIT-LICENSE.txt. -->
+ <!-- ======================================================================= -->
+
+
+ <!-- ===================================================================== -->
+ <!-- === TMCL meta-model topics ========================================== -->
+ <!-- ===================================================================== -->
+ <tm:topic id="topictype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-type"/> <!-- naming of psis: Prague, March 25-27, 2008, page 12 -->
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="occurrencetype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-type"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="associationtype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-type"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="roletype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/role-type"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="nametype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/name-type"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="scopetype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/scope-type"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- role types used to include the topictype metatypes in associations -->
+ <tm:topic id="topictype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-type-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="occurrencetype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-type-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="associationtype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-type-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="roletype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/role-type-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="otherroletype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/other-role-type-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="othertopictype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/other-topic-type-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="nametype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/name-type-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="scopetype-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/scope-type-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- the constraint roletype -->
+ <tm:topic id="constraint-role">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/constraint-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- ===================================================================== -->
+ <!-- === TMCL model topics =============================================== -->
+ <!-- ===================================================================== -->
+
+ <!-- the constraint topic is the common supertype of all constraint types
+ defined by TMCL. -->
+ <tm:topic id="constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- this occurrence type is used to type a single occurrence on each
+ constraint type. This occurrence holds the TMQL value used to
+ evaluate constraint instances for validity. -->
+ <tm:topic id="validation-expression">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/validation-expression"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- the association type used to bind different components into a
+ constraint -->
+ <tm:topic id="applies-to">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/applies-to"/>
+ <tm:instanceOf><tm:topicRef href="#associationtype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- the card min facet is used on many constraint types -->
+ <tm:topic id="card-min">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/card-min"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- the card max facet is used on many constraint types -->
+ <tm:topic id="card-max">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/card-max"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- the reg exp facet is used on many constraint types -->
+ <tm:topic id="regexp">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/reg-exp"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- the datatype facet is used on many constraint types -->
+ <tm:topic id="datatype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/datatype"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- ===================================================================== -->
+ <!-- === topics for super-subtype-associations (ako) ===================== -->
+ <!-- ===================================================================== -->
+
+ <tm:topic id="supertype-subtype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/iso13250/model/supertype-subtype"/>
+ </tm:topic>
+
+ <tm:topic id="supertype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/iso13250/model/supertype"/>
+ </tm:topic>
+
+ <tm:topic id="subtype">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/iso13250/model/subtype"/>
+ </tm:topic>
+
+
+ <!-- ===================================================================== -->
+ <!-- === schema type and schema definitions ============================== -->
+ <!-- ===================================================================== -->
+
+ <!-- constraints can be bound to a schema -->
+ <tm:topic id="schema">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/schema"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+
+ <!-- ===================================================================== -->
+ <!-- === TMCL constraint types =========================================== -->
+ <!-- ===================================================================== -->
+
+ <!-- topictype-constraint -->
+ <tm:topic id="topictype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-type-constraint"/>
+ </tm:topic> <!-- standard constraints doesn't own a valiadtion-expression-occurrence: Prague, March 25-27, 2008, page 34-36 -->
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#topictype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- associationtype-constraint -->
+ <tm:topic id="associationtype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-type-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#associationtype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- roletype-constraint -->
+ <tm:topic id="roletype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/role-type-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#roletype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- occurrencetype-constraint -->
+ <tm:topic id="occurrencetype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-type-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#occurrencetype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- nametype-constraint -->
+ <tm:topic id="nametype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/name-type-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#nametype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- abstract-topictype-constraint -->
+ <tm:topic id="abstract-topictype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/abstract-topic-type-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#abstract-topictype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- exclusive-instance -->
+ <tm:topic id="exclusive-instance">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/exclusive-instance"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#exclusive-instance"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- ===================================================================== -->
+ <!-- === subjectidentifier/locator constraints =========================== -->
+ <!-- ===================================================================== -->
+
+ <!-- subjectlocator-constraint -->
+ <tm:topic id="subjectlocator-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/subject-locator-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#subjectlocator-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- subjectidentifier-constraint -->
+ <tm:topic id="subjectidentifier-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/subject-identifier-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#subjectidentifier-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- ===================================================================== -->
+ <!-- === names/occurrences/associations/association roles ================ -->
+ <!-- ===================================================================== -->
+
+ <!-- topicname-constraint -->
+ <tm:topic id="topicname-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-name-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#topicname-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- topicoccurrence-constraint -->
+ <tm:topic id="topicoccurrence-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/topic-occurrence-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- occurrencedatatype-constraint -->
+ <tm:topic id="occurrencedatatype-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-datatype-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#occurrencedatatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- uniqueoccurrence-constraint -->
+ <tm:topic id="uniqueoccurrence-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/unique-occurrence-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#uniqueoccurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- associationrole-constraint -->
+ <tm:topic id="associationrole-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-role-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#associationrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- roleplayer-constraint -->
+ <tm:topic id="roleplayer-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/role-player-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#roleplayer-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- otherrole-constraint -->
+ <tm:topic id="otherrole-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/other-role-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#otherrole-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- ===================================================================== -->
+ <!-- === scopes ========================================================== -->
+ <!-- ===================================================================== -->
+
+ <!-- nametypescope-constraint -->
+ <tm:topic id="nametypescope-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/name-type-scope-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#nametypescope-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- occurrencetypescope-constraint -->
+ <tm:topic id="occurrencetypescope-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/occurrence-type-scope-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#occurrencetypescope-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- associationtypescope-constraint -->
+ <tm:topic id="associationtypescope-constraint">
+ <tm:subjectIdentifier href="http://psi.topicmaps.org/tmcl/association-type-scope-constraint"/>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#supertype-subtype"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#subtype"/></tm:type>
+ <tm:topicRef href="#associationtypescope-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#supertype"/></tm:type>
+ <tm:topicRef href="#constraint"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: type handling ==================================== -->
+ <!-- ===================================================================== -->
+
+ <!-- only topics that are instances of topictype are allowed as topic
+ types -->
+ <tm:topic id="ttc">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/ttc"/>
+ <tm:instanceOf><tm:topicRef href="#topictype-constraint"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- only topics that are instances of associationtype are allowed as
+ association types -->
+ <tm:topic id="atc">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/atc"/>
+ <tm:instanceOf><tm:topicRef href="#associationtype-constraint"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- only topics that are instances of roletype are allowed as
+ association role types -->
+ <tm:topic id="rtc">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/rtc"/>
+ <tm:instanceOf><tm:topicRef href="#roletype-constraint"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- only topics that are instances of occurrencetype are allowed as
+ occurrence types -->
+ <tm:topic id="otc">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/otc"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype-constraint"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- only topics that are instances of nametype are allowed as
+ name types -->
+ <tm:topic id="ntc">
+ <tm:subjectIdentifier href="http://some.where/constraint-psis/ntc"/>
+ <tm:instanceOf><tm:topicRef href="#nametype-constraint"/></tm:instanceOf>
+ </tm:topic>
+
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: base types ======================================= -->
+ <!-- ===================================================================== -->
+
+ <!-- service -->
+ <tm:topic id="service">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/service"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="service-name">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/service-name"/>
+ <tm:instanceOf><tm:topicRef href="#nametype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="description">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/description"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="service-type">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/service-type"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="service-environment">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/service-environment"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="service-key">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/service-key"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- url -->
+ <tm:topic id="url">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/url"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="url-content">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/url-content"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- parameter -->
+ <tm:topic id="parameter">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/parameter"/>
+ <tm:instanceOf><tm:topicRef href="#topictype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="parameter-name">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/parameter-name"/>
+ <tm:instanceOf><tm:topicRef href="#nametype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- description is already defined for the topic-type "service" -->
+
+ <tm:topic id="default-value">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/default-value"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="necessary">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/necessary"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencetype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- association service - url -->
+ <tm:topic id="has-url">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/has-url"/>
+ <tm:instanceOf><tm:topicRef href="#associationtype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="service-role">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/service-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:topic id="url-role">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/url-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- association url - parameter -->
+ <tm:topic id="has-parameter">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/has-parameter"/>
+ <tm:instanceOf><tm:topicRef href="#associationtype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- url-role is already defined for has-url associations -->
+ <tm:topic id="parameter-role">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/parameter-role"/>
+ <tm:instanceOf><tm:topicRef href="#roletype"/></tm:instanceOf>
+ </tm:topic>
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: exclusive type constraint ======================== -->
+ <!-- ===================================================================== -->
+ <!-- same instances of the type service, url and parameter are not allowed -->
+ <tm:topic id="exc">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/exc"/>
+ <tm:instanceOf><tm:topicRef href="#exclusive-instance"/></tm:instanceOf>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#exc"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#exc"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#url"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#exc"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#description"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: subjectIdentifier constraints ==================== -->
+ <!-- ===================================================================== -->
+ <!-- topictype "service":
+ *psis: 1:1:"^http://textgrid.org/isidorus/.+/.+$"
+ topictype "url":
+ *psis: 1:1:"^http://textgrid.org/isidorus/url/.+$"
+ topictype "parameter"
+ *psis: 1:1:"^http://textgrid.org/isidorus/parameter/.+$" -->
+
+ <!-- subjectidentifier of service -->
+ <tm:topic id="sic-service">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/sic-service"/>
+ <tm:instanceOf><tm:topicRef href="#subjectidentifier-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^http://textgrid.org/serviceregistry/.+/.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#sic-service"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- subjectidentifier of url -->
+ <tm:topic id="sic-url">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/sic-url"/>
+ <tm:instanceOf><tm:topicRef href="#subjectidentifier-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^http://textgrid.org/serviceregistry/url/.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#sic-url"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#url"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- subjectidentifier of parameter -->
+ <tm:topic id="sic-parameter">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/sic-parameter"/>
+ <tm:instanceOf><tm:topicRef href="#subjectidentifier-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^http://textgrid.org/serviceregistry/parameter/.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#sic-parameter"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: subjectLocator constraints ======================= -->
+ <!-- ===================================================================== -->
+ <!-- topictype "service":
+ *locators: 0
+ topictype "url":
+ *locators: 0
+ topictype "parameter"
+ *locators: 0 -->
+
+ <tm:topic id="slc-service-url-parameter">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/slc-service-url-parameter"/>
+ <tm:instanceOf><tm:topicRef href="#subjectlocator-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.*$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#slc-service-url-parameter"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#slc-service-url-parameter"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#url"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#slc-service-url-parameter"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: name constraints ================================= -->
+ <!-- ===================================================================== -->
+ <!-- topictype "service":
+ *names: service-name:1:1:"^.+$"
+ topictype "param":
+ *names: param-name:1:1:"^.+$" -->
+
+ <!-- service-name -->
+ <tm:topic id="service-name-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/service-name-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topicname-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#service-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#service-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#nametype-role"/></tm:type>
+ <tm:topicRef href="#service-name"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- parameter-name -->
+ <tm:topic id="parameter-name-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/parameter-name-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topicname-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#parameter-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#parameter-name-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#nametype-role"/></tm:type>
+ <tm:topicRef href="#parameter-name"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: occurence constraints ============================ -->
+ <!-- ===================================================================== -->
+ <!-- topictype "service":
+ *occurrences: service-key:1:1:"^.+$":xml:string
+ *occurrences: description:0:1:".*":xml:string
+ *occurrences: service-type:0:1:".*":xml:string
+ *occurrences: service-environment:1:1:"^.+$":xml:string
+ topictype "url":
+ *occurrences: url-content:1:1:"^.+$"
+ topictype "param":
+ *occurrences: description:0:1:".*"
+ *occurrences: default-value:0:1:".*"
+ *occurrences: necessary:0:1"(true|TRUE|false|FALSE)":xml:boolean -->
+
+ <!-- service-key occurrence -->
+ <tm:topic id="service-key-occurrence-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/service-key-occurrence-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topicoccurrence-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#service-key-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#service-key"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#service-key-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <!-- description occurrence -->
+ <tm:topic id="description-occurrence-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/description-occurrence-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topicoccurrence-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.*</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#description-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#description"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#description-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#description-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- string datatype -->
+ <tm:topic id="string-datatype-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/string-datatype-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencedatatype-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#datatype"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">http://www.w3.org/2001/XMLSchema#string</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#description"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#service-type"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#service-environment"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#default-value"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#string-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#service-key"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- anyUri datatype -->
+ <tm:topic id="anyUri-datatype-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/anyUri-datatype-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#occurrencedatatype-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#datatype"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">http://www.w3.org/2001/XMLSchema#anyUri</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#anyUri-datatype-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#url-content"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- service-type occurrence -->
+ <tm:topic id="service-type-occurrence-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/service-type-occurrence-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topicoccurrence-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.*$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#service-type-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#service-type"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#service-type-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#url"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- service-environment occurrence -->
+ <tm:topic id="service-environment-occurrence-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/service-environment-occurrence-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topicoccurrence-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#service-environment-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#service-environment"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#service-environment-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- url-content occurrence -->
+ <tm:topic id="url-content-occurrence-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/url-content-occurrence-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topicoccurrence-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^.+$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#url-content-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#url-content"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#url-content-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#url"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- default-value occurrence -->
+ <tm:topic id="default-value-occurrence-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/default-value-occurrence-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#topicoccurrence-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#regexp"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">.*</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#default-value-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#occurrencetype-role"/></tm:type>
+ <tm:topicRef href="#default-value"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#default-value-occurrence-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:topic id="paraeter-necessary-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/paraeter-necessary-constraint"/>
+ <tm:instanceOf>
+ <tm:topicRef href="#topicoccurrence-constraint"/>
+ </tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">0</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#regexp"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">^(true)|(TRUE)|(false)|(FALSE)$</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#paraeter-necessary-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#topictype-role"/>
+ </tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type>
+ <tm:topicRef href="#applies-to"/>
+ </tm:type>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#constraint-role"/>
+ </tm:type>
+ <tm:topicRef href="#paraeter-necessary-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type>
+ <tm:topicRef href="#occurrencetype-role"/>
+ </tm:type>
+ <tm:topicRef href="#necessary"/>
+ </tm:role>
+ </tm:association>
+
+<!-- Don't know what the following lines do -->
+
+<tm:topic id="boolean-datatype-constraint">
+<tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/boolean-datatype-constraint"/>
+<tm:instanceOf>
+<tm:topicRef href="#occurrencedatatype-constraint"/>
+</tm:instanceOf>
+<tm:occurrence>
+<tm:type>
+<tm:topicRef href="#datatype"/>
+</tm:type>
+<tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">http://www.w3.org/2001/XMLSchema#boolean</tm:resourceData>
+</tm:occurrence>
+</tm:topic>
+<tm:association>
+<tm:type>
+<tm:topicRef href="#applies-to"/>
+</tm:type>
+<tm:role>
+<tm:type>
+<tm:topicRef href="#constraint-role"/>
+</tm:type>
+<tm:topicRef href="#boolean-datatype-constraint"/>
+</tm:role>
+<tm:role>
+<tm:type>
+<tm:topicRef href="#occurrencetype-role"/>
+</tm:type>
+<tm:topicRef href="#necessary"/>
+</tm:role>
+</tm:association>
+
+
+ <!-- ===================================================================== -->
+ <!-- === own datamodel: association (-role) constraints ================== -->
+ <!-- ===================================================================== -->
+ <!-- association "has-url":
+ *roles: service-role:service:1:1
+ *roles: url-role:url:1:1
+ association "has-param"
+ *roles: url-role:url:1:1
+ *roles: parameter-role:parameter:1:1 -->
+
+ <!-- the service-role has to appear exactly once in an association of type
+ has-url -->
+ <tm:topic id="service-role-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/service-role-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#associationrole-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#service-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#has-url"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#service-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#service-role"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- the service-role owns a player of the type servie -->
+ <tm:topic id="service-role-player-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/service-role-player-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#roleplayer-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#service-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#service-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#has-url"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#service-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#service-role"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- otherrole-constraint:
+ If there is a role of the type service-role with a player of the type
+ service there must be another role of the type url-role with a player
+ of the type url. -->
+ <tm:topic id="has-url-otherrole-constraint-for-service">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/has-url-otherrole-constraint-for-service"/>
+ <tm:instanceOf><tm:topicRef href="#otherrole-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#has-url-otherrole-constraint-for-service"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#has-url"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#has-url-otherrole-constraint-for-service"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#service-role"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#has-url-otherrole-constraint-for-service"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#service"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#has-url-otherrole-constraint-for-service"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#otherroletype-role"/></tm:type>
+ <tm:topicRef href="#url-role"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#has-url-otherrole-constraint-for-service"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#othertopictype-role"/></tm:type>
+ <tm:topicRef href="#url"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- the url-role has to appear exactly once in an association of type
+ has-parameter -->
+ <tm:topic id="url-role-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/url-role-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#associationrole-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#url-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#has-parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#url-role-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#url-role"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- the service-role owns a player of the type servie -->
+ <tm:topic id="url-role-player-constraint">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/url-role-player-constraint"/>
+ <tm:instanceOf><tm:topicRef href="#roleplayer-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-min"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#card-max"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#url-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#url"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#url-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#has-parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#url-role-player-constraint"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#url-role"/>
+ </tm:role>
+ </tm:association>
+
+
+ <!-- otherrole-constraint:
+ If there is a role of the type url-role with a player of the type
+ url there must be another role of the type parameter-role with a player
+ of the type parameter. -->
+ <tm:topic id="has-parameter-otherrole-constraint-for-url">
+ <tm:subjectIdentifier href="http://textgrid.org/isidorus/tmcl/has-parameter-otherrole-constraint-for-url"/>
+ <tm:instanceOf><tm:topicRef href="#otherrole-constraint"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-min"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type>
+ <tm:topicRef href="#card-max"/>
+ </tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#unsignedInt">1</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#has-parameter-otherrole-constraint-for-url"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#associationtype-role"/></tm:type>
+ <tm:topicRef href="#has-parameter"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#has-parameter-otherrole-constraint-for-url"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#roletype-role"/></tm:type>
+ <tm:topicRef href="#url-role"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#has-parameter-otherrole-constraint-for-url"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#topictype-role"/></tm:type>
+ <tm:topicRef href="#url"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#has-parameter-otherrole-constraint-for-url"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#otherroletype-role"/></tm:type>
+ <tm:topicRef href="#parameter-role"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#applies-to"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#constraint-role"/></tm:type>
+ <tm:topicRef href="#has-parameter-otherrole-constraint-for-url"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#othertopictype-role"/></tm:type>
+ <tm:topicRef href="#parameter"/>
+ </tm:role>
+ </tm:association>
+
+<!--=========================================================-->
+<!--Confserver Services-->
+<!--=========================================================-->
+
+<!--=========================================================-->
+<!--Production-->
+<!--schema-->
+ <tm:topic id="service-schema">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/production/schema"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>schema-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">production</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">schema</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="url-schema">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/production/schema"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">www.textgrid.info/schemas/textgrid-metadata_2008-07-24.xsd</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#service-schema"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#url-schema"/>
+ </tm:role>
+ </tm:association>
+
+<!--ns-->
+ <tm:topic id="service-ns">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/production/ns"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>ns-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">production</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">ns</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="url-ns">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/production/ns"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://textgrid.info/namespaces/metadata/core/2008-07-24</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#service-ns"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#url-ns"/>
+ </tm:role>
+ </tm:association>
+
+<!--workflow-->
+ <tm:topic id="service-workflow">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/production/workflow"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>workflow-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">production</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">workflow</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="url-workflow">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/production/workflow"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://ingrid.sub.uni-goettingen.de/gwes/services/GWES</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#service-workflow"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#url-workflow"/>
+ </tm:role>
+ </tm:association>
+
+<!--authz-->
+ <tm:topic id="service-authz">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/production/authz"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>authz-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">production</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">authz</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="url-authz">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/production/authz"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">https://textgridlab.org/WebAuthN/WebAuthN.php</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="param-authZinstance">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/parameter/production/authZinstance"/>
+ <tm:instanceOf><tm:topicRef href="#parameter"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#parameter-name"/></tm:type>
+ <tm:value>authZinstance</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#default-value"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">textgridlab.org</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#necessary"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#boolean">true</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#service-authz"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#url-authz"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-parameter"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#url-authz"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#parameter-role"/></tm:type>
+ <tm:topicRef href="#param-authZinstance"/>
+ </tm:role>
+ </tm:association>
+
+<!--tgauth-->
+ <tm:topic id="service-tgauth">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/production/tgauth"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>tgauth-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">production</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">tgauth</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="url-tgauth">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/production/tgauth"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">https://textgridlab.org/tgauth/rbacSoap/tgextra.php</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#service-tgauth"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#url-tgauth"/>
+ </tm:role>
+ </tm:association>
+
+<!--tgsearch-->
+ <tm:topic id="service-tgsearch">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/production/tgsearch"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>tgsearch-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">production</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">tgsearch</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="url-tgsearch">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/production/tgsearch"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">https://textgridlab.org/axis2/services/Metadata</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#service-tgsearch"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#url-tgsearch"/>
+ </tm:role>
+ </tm:association>
+
+<!--tgcrud-->
+ <tm:topic id="service-tgcrud">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/production/tgcrud"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>tgcrud-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">production</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">tgcrud</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="url-tgcrud">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/production/tgcrud"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">https://textgridlab.org/axis2/services/TGCrudService</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#service-tgcrud"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#url-tgcrud"/>
+ </tm:role>
+ </tm:association>
+
+<!--logservice-->
+ <tm:topic id="service-logservice">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/production/logservice"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>logservice-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">production</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">logservice</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="url-logservice">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/production/logservice"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">https://textgridlab.org/axis2/services/textlog</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#service-logservice"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#url-logservice"/>
+ </tm:role>
+ </tm:association>
+
+<!--exist-->
+ <tm:topic id="service-exist">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/production/exist"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>exist-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">production</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">exist</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="url-exist">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/production/exist"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">https://textgridlab.org/exist/services/Query</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#service-exist"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#url-exist"/>
+ </tm:role>
+ </tm:association>
+
+<!--rdf-repository-->
+ <tm:topic id="service-rdf-repository">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/production/rdf-repository"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>rdf-repository-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">production</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">rdf-repository</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="url-rdf-repository">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/production/rdf-repository"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">https://textgridlab.org/openrdf-sesame/repositories/textgrid</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#service-rdf-repository"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#url-rdf-repository"/>
+ </tm:role>
+ </tm:association>
+
+<!--last-api-change-->
+ <tm:topic id="service-last-api-change">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/production/last-api-change"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>last-api-change-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">production</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">last-api-change</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="url-last-api-change">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/production/last-api-change"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">2009-01-21</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#service-last-api-change"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#url-last-api-change"/>
+ </tm:role>
+ </tm:association>
+
+<!--webpublish-->
+ <tm:topic id="service-webpublish">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/production/webpublish"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>webpublish-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">production</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">webpublish</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="url-webpublish">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/production/webpublish"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://textgrid-ws2.gwdg.de/teiPublisher/2/publish</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#service-webpublish"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#url-webpublish"/>
+ </tm:role>
+ </tm:association>
+
+<!--=========================================================-->
+<!--Testing-->
+<!--schema-->
+ <tm:topic id="testing-service-schema">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/testing/schema"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>schema-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">testing</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">schema</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="testing-url-schema">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/testing/schema"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">www.textgrid.info/schemas/textgrid-metadata_2008-07-24.xsd</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#testing-service-schema"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#testing-url-schema"/>
+ </tm:role>
+ </tm:association>
+
+<!--ns-->
+ <tm:topic id="testing-service-ns">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/testing/ns"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>ns-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">testing</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">ns</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="testing-url-ns">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/testing/ns"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://textgrid.info/namespaces/metadata/core/2008-07-24</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#testing-service-ns"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#testing-url-ns"/>
+ </tm:role>
+ </tm:association>
+
+<!--workflow-->
+ <tm:topic id="testing-service-workflow">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/testing/workflow"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>workflow-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">testing</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">workflow</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="testing-url-workflow">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/testing/workflow"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://ingrid.sub.uni-goettingen.de:8083/gwes/services/GWES</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#testing-service-workflow"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#testing-url-workflow"/>
+ </tm:role>
+ </tm:association>
+
+<!--authz-->
+ <tm:topic id="testing-service-authz">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/testing/authz"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>authz-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">testing</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">authz</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="testing-url-authz">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/testing/authz"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">https://textgridlab.org/WebAuthN/WebAuthN.php</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="testing-param-authZinstance">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/parameter/testing/authZinstance"/>
+ <tm:instanceOf><tm:topicRef href="#parameter"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#parameter-name"/></tm:type>
+ <tm:value>authZinstance</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#default-value"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">ingrid-8081</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#necessary"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#boolean">true</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#testing-service-authz"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#testing-url-authz"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-parameter"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#testing-url-authz"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#parameter-role"/></tm:type>
+ <tm:topicRef href="#testing-param-authZinstance"/>
+ </tm:role>
+ </tm:association>
+
+<!--tgauth-->
+ <tm:topic id="testing-service-tgauth">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/testing/tgauth"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>tgauth-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">testing</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">tgauth</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="testing-url-tgauth">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/testing/tgauth"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://ingrid.sub.uni-goettingen.de/rbac-8081/tgextra.php</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#testing-service-tgauth"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#testing-url-tgauth"/>
+ </tm:role>
+ </tm:association>
+
+<!--tgsearch-->
+ <tm:topic id="testing-service-tgsearch">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/testing/tgsearch"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>tgsearch-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">testing</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">tgsearch</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="testing-url-tgsearch">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/testing/tgsearch"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://ingrid.sub.uni-goettingen.de:8081/axis2/services/Metadata</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#testing-service-tgsearch"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#testing-url-tgsearch"/>
+ </tm:role>
+ </tm:association>
+
+<!--tgcrud-->
+ <tm:topic id="testing-service-tgcrud">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/testing/tgcrud"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>tgcrud-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">testing</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">tgcrud</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="testing-url-tgcrud">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/testing/tgcrud"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://ingrid.sub.uni-goettingen.de:8081/axis2/services/TGCrudService</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#testing-service-tgcrud"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#testing-url-tgcrud"/>
+ </tm:role>
+ </tm:association>
+
+<!--logservice-->
+ <tm:topic id="testing-service-logservice">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/testing/logservice"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>logservice-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">testing</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">logservice</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="testing-url-logservice">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/testing/logservice"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://ingrid.sub.uni-goettingen.de:8081/axis2/services/textlog</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#testing-service-logservice"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#testing-url-logservice"/>
+ </tm:role>
+ </tm:association>
+
+<!--exist-->
+ <tm:topic id="testing-service-exist">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/testing/exist"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>exist-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">testing</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">exist</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="testing-url-exist">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/testing/exist"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://ingrid.sub.uni-goettingen.de:8081/exist/services/Query</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#testing-service-exist"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#testing-url-exist"/>
+ </tm:role>
+ </tm:association>
+
+<!--rdf-repository-->
+ <tm:topic id="testing-service-rdf-repository">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/testing/rdf-repository"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>rdf-repository-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">testing</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">rdf-repository</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="testing-url-rdf-repository">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/testing/rdf-repository"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://ingrid.sub.uni-goettingen.de:8082/openrdf-sesame/repositories/textgr…</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#testing-service-rdf-repository"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#testing-url-rdf-repository"/>
+ </tm:role>
+ </tm:association>
+
+<!--last-api-change-->
+ <tm:topic id="testing-service-last-api-change">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/testing/last-api-change"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>last-api-change-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">testing</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">last-api-change</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="testing-url-last-api-change">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/testing/last-api-change"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">2009-01-21</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#testing-service-last-api-change"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#testing-url-last-api-change"/>
+ </tm:role>
+ </tm:association>
+
+<!--webpublish-->
+ <tm:topic id="testing-service-webpublish">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/testing/webpublish"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>webpublish-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">testing</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">webpublish</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="testing-url-webpublish">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/testing/webpublish"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://textgrid-ws2.gwdg.de/teiPublisher/0/publish</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#testing-service-webpublish"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#testing-url-webpublish"/>
+ </tm:role>
+ </tm:association>
+
+<!--=========================================================-->
+<!--Development-->
+<!--schema-->
+ <tm:topic id="dev-service-schema">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/development/schema"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>schema-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">development</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">schema</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="dev-url-schema">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/development/schema"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">www.textgrid.info/schemas/textgrid-metadata_2008-07-24.xsd</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#dev-service-schema"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#dev-url-schema"/>
+ </tm:role>
+ </tm:association>
+
+<!--ns-->
+ <tm:topic id="dev-service-ns">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/development/ns"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>ns-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">development</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">ns</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="dev-url-ns">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/development/ns"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://textgrid.info/namespaces/metadata/core/2008-07-24</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#dev-service-ns"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#dev-url-ns"/>
+ </tm:role>
+ </tm:association>
+
+<!--workflow-->
+ <tm:topic id="dev-service-workflow">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/development/workflow"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>workflow-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">development</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">workflow</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="dev-url-workflow">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/development/workflow"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://ingrid.sub.uni-goettingen.de:8083/gwes/services/GWES</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#dev-service-workflow"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#dev-url-workflow"/>
+ </tm:role>
+ </tm:association>
+
+<!--authz-->
+ <tm:topic id="dev-service-authz">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/development/authz"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>authz-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">development</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">authz</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="dev-url-authz">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/development/authz"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">https://textgridlab.org/Portal/WebAuthN.php</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="dev-param-authZinstance">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/parameter/development/authZinstance"/>
+ <tm:instanceOf><tm:topicRef href="#parameter"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#parameter-name"/></tm:type>
+ <tm:value>authZinstance</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#default-value"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">ingrid-8082</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#necessary"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#boolean">true</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#dev-service-authz"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#dev-url-authz"/>
+ </tm:role>
+ </tm:association>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-parameter"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#dev-url-authz"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#parameter-role"/></tm:type>
+ <tm:topicRef href="#dev-param-authZinstance"/>
+ </tm:role>
+ </tm:association>
+
+<!--tgauth-->
+ <tm:topic id="dev-service-tgauth">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/development/tgauth"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>tgauth-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">development</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">tgauth</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="dev-url-tgauth">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/development/tgauth"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://ingrid.sub.uni-goettingen.de/rbac-8082/tgextra.php</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#dev-service-tgauth"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#dev-url-tgauth"/>
+ </tm:role>
+ </tm:association>
+
+<!--tgsearch-->
+ <tm:topic id="dev-service-tgsearch">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/development/tgsearch"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>tgsearch-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">development</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">tgsearch</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="dev-url-tgsearch">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/development/tgsearch"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://ingrid.sub.uni-goettingen.de:8082/axis2/services/Metadata</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#dev-service-tgsearch"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#dev-url-tgsearch"/>
+ </tm:role>
+ </tm:association>
+
+<!--tgcrud-->
+ <tm:topic id="dev-service-tgcrud">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/development/tgcrud"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>tgcrud-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">development</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">tgcrud</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="dev-url-tgcrud">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/development/tgcrud"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://ingrid.sub.uni-goettingen.de:8082/axis2/services/TGCrudService</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#dev-service-tgcrud"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#dev-url-tgcrud"/>
+ </tm:role>
+ </tm:association>
+
+<!--logservice-->
+ <tm:topic id="dev-service-logservice">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/development/logservice"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>logservice-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">development</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">logservice</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="dev-url-logservice">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/development/logservice"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://ingrid.sub.uni-goettingen.de:8082/axis2/services/textlog</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#dev-service-logservice"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#dev-url-logservice"/>
+ </tm:role>
+ </tm:association>
+
+<!--exist-->
+ <tm:topic id="dev-service-exist">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/development/exist"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>exist-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">development</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">exist</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="dev-url-exist">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/development/exist"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://ingrid.sub.uni-goettingen.de:8082/exist/services/Query</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#dev-service-exist"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#dev-url-exist"/>
+ </tm:role>
+ </tm:association>
+
+<!--rdf-repository-->
+ <tm:topic id="dev-service-rdf-repository">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/development/rdf-repository"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>rdf-repository-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">development</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">rdf-repository</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="dev-url-rdf-repository">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/development/rdf-repository"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://ingrid.sub.uni-goettingen.de:8082/openrdf-sesame/repositories/textgr…</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#dev-service-rdf-repository"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#dev-url-rdf-repository"/>
+ </tm:role>
+ </tm:association>
+
+<!--last-api-change-->
+ <tm:topic id="dev-service-last-api-change">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/development/last-api-change"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>last-api-change-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">development</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">last-api-change</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="dev-url-last-api-change">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/development/last-api-change"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">2009-01-21</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#dev-service-last-api-change"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#dev-url-last-api-change"/>
+ </tm:role>
+ </tm:association>
+
+<!--webpublish-->
+ <tm:topic id="dev-service-webpublish">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/development/webpublish"/>
+ <tm:instanceOf><tm:topicRef href="#service"/></tm:instanceOf>
+ <tm:name>
+ <tm:type><tm:topicRef href="#service-name"/></tm:type>
+ <tm:value>webpublish-name</tm:value>
+ </tm:name>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-environment"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">development</tm:resourceData>
+ </tm:occurrence>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#service-key"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#string">webpublish</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:topic id="dev-url-webpublish">
+ <tm:subjectIdentifier href="http://textgrid.org/serviceregistry/url/development/webpublish"/>
+ <tm:instanceOf><tm:topicRef href="#url"/></tm:instanceOf>
+ <tm:occurrence>
+ <tm:type><tm:topicRef href="#url-content"/></tm:type>
+ <tm:resourceData datatype="http://www.w3.org/2001/XMLSchema#anyUri">http://textgrid-ws2.gwdg.de/teiPublisher/1/publish</tm:resourceData>
+ </tm:occurrence>
+ </tm:topic>
+
+ <tm:association>
+ <tm:type><tm:topicRef href="#has-url"/></tm:type>
+ <tm:role>
+ <tm:type><tm:topicRef href="#service-role"/></tm:type>
+ <tm:topicRef href="#dev-service-webpublish"/>
+ </tm:role>
+ <tm:role>
+ <tm:type><tm:topicRef href="#url-role"/></tm:type>
+ <tm:topicRef href="#dev-url-webpublish"/>
+ </tm:role>
+ </tm:association>
+
+</tm:topicMap>
+
1
0

11 Nov '10
Author: lgiessmann
Date: Thu Nov 11 03:47:23 2010
New Revision: 337
Log:
fixed ticket #90 => added unit-tests for the trivial-query part of the datamodel; added some functionality and fixed some bugs in the trivial-query part.
Modified:
trunk/src/base-tools/base-tools.lisp
trunk/src/isidorus.asd
trunk/src/model/datamodel.lisp
trunk/src/model/trivial-queries.lisp
trunk/src/unit_tests/fixtures.lisp
trunk/src/unit_tests/poems.xtm
trunk/src/unit_tests/trivial_queries_test.lisp
trunk/src/unit_tests/unittests-constants.lisp
Modified: trunk/src/base-tools/base-tools.lisp
==============================================================================
--- trunk/src/base-tools/base-tools.lisp (original)
+++ trunk/src/base-tools/base-tools.lisp Thu Nov 11 03:47:23 2010
@@ -11,7 +11,9 @@
(:use :cl)
(:nicknames :tools)
(:export :push-string
- :when-do))
+ :when-do
+ :remove-null
+ :full-path))
(in-package :base-tools)
@@ -31,3 +33,23 @@
,do-with-result
nil)))
+
+(defun remove-null (lst)
+ "Removes all null values from the passed list."
+ (remove-if #'null lst))
+
+
+(defun full-path (pathname)
+ "Returns a string that represents the full path of the passed
+ CL:Pathname construct."
+ (declare (CL:Pathname pathname))
+ (let ((segments
+ (remove-if #'null
+ (map 'list #'(lambda(item)
+ (when (stringp item)
+ (concatenate 'string "/" item)))
+ (pathname-directory pathname))))
+ (full-path-string ""))
+ (dolist (segment segments)
+ (push-string segment full-path-string))
+ (concatenate 'string full-path-string "/" (pathname-name pathname))))
\ No newline at end of file
Modified: trunk/src/isidorus.asd
==============================================================================
--- trunk/src/isidorus.asd (original)
+++ trunk/src/isidorus.asd Thu Nov 11 03:47:23 2010
@@ -39,7 +39,7 @@
:depends-on ("datamodel" "trivial-queries"))
(:file "model_tools"
:depends-on ("exceptions")))
- :depends-on ("constants"))
+ :depends-on ("constants" "base-tools"))
(:module "TM-SPARQL"
:components ((:file "sparql"
:depends-on ("sparql_tokenizer"))
@@ -177,7 +177,9 @@
"model"
"xml"
"json"
- "threading"))
+ "threading"
+ "base-tools"
+ "TM-SPARQL"))
(:module "json"
:components ((:file "json_exporter"
:depends-on ("json_tmcl_constants"))
Modified: trunk/src/model/datamodel.lisp
==============================================================================
--- trunk/src/model/datamodel.lisp (original)
+++ trunk/src/model/datamodel.lisp Thu Nov 11 03:47:23 2010
@@ -170,11 +170,13 @@
:direct-instance-of
:invoke-on
:names-by-type
- :occurrencs-by-type
+ :occurrences-by-type
:characteristics-by-type
:occurrences-by-value
:names-by-value
- :characteristics-by-value))
+ :characteristics-by-value
+ :isa
+ :aka))
(in-package :datamodel)
Modified: trunk/src/model/trivial-queries.lisp
==============================================================================
--- trunk/src/model/trivial-queries.lisp (original)
+++ trunk/src/model/trivial-queries.lisp Thu Nov 11 03:47:23 2010
@@ -21,12 +21,12 @@
(declare (integer revision)
(type (or Null TopicC) role-type))
(if role-type
- (remove-if #'null
- (map 'list #'(lambda(role)
- (when (eql (instance-of role :revision revision)
- role-type)
- role))
- (player-in-roles construct :revision revision)))
+ (remove-null
+ (map 'list #'(lambda(role)
+ (when (eql (instance-of role :revision revision)
+ role-type)
+ role))
+ (player-in-roles construct :revision revision)))
(player-in-roles construct :revision revision)))
@@ -35,28 +35,35 @@
(declare (integer revision)
(type (or Null TopicC) role-type))
(if role-type
- (remove-if #'null
- (map 'list #'(lambda(role)
- (when (eql (instance-of role :revision revision)
- role-type)
- role))
- (roles construct :revision revision)))
+ (remove-null
+ (map 'list #'(lambda(role)
+ (when (eql (instance-of role :revision revision)
+ role-type)
+ role))
+ (roles construct :revision revision)))
(roles construct :revision revision)))
-(defgeneric roles-by-player (construct role-player &key revision)
+(defgeneric roles-by-player (construct role-player
+ &key role-player-is-type revision)
(:documentation "Returns all roles that contains the corresponding player.
If the player is set to nil all roles are returned.")
- (:method ((construct AssociationC) role-player &key (revision *TM-REVISION*))
+ (:method ((construct AssociationC) role-player
+ &key role-player-is-type (revision *TM-REVISION*))
(declare (integer revision)
- (type (or Null TopicC) role-player))
+ (type (or Null TopicC) role-player)
+ (boolean role-player-is-type))
(if role-player
- (remove-if #'null
- (map 'list #'(lambda(role)
- (when (eql (player role :revision revision)
- role-player)
- role))
- (roles construct :revision revision)))
+ (remove-null
+ (map 'list #'(lambda(role)
+ (if role-player-is-type
+ (when (isa (player role :revision revision)
+ role-player)
+ role)
+ (when (eql (player role :revision revision)
+ role-player)
+ role)))
+ (roles construct :revision revision)))
(roles construct :revision revision))))
@@ -77,38 +84,44 @@
(defun filter-associations-by-role (associations role-type role-player
- &key (revision *TM-REVISION*))
+ &key role-player-is-type (revision *TM-REVISION*))
"Returns associations that have a role corresponding to the passed
values. If any of the passed role-values is set to nil, it won't be used
for the evaluation of the result."
(declare (List associations)
- (type (or Null TopicC) role-type role-player))
- (remove-if #'null
- (intersection
- (map 'list #'(lambda(assoc)
- (when (roles-by-type assoc role-type
- :revision revision)
- assoc))
- associations)
- (map 'list #'(lambda(assoc)
- (when (roles-by-player assoc role-player
- :revision revision)
- assoc))
- associations))))
+ (type (or Null TopicC) role-type role-player)
+ (boolean role-player-is-type))
+ (remove-null
+ (intersection
+ (map 'list #'(lambda(assoc)
+ (when (roles-by-type assoc role-type
+ :revision revision)
+ assoc))
+ associations)
+ (map 'list #'(lambda(assoc)
+ (when (roles-by-player
+ assoc role-player
+ :role-player-is-type role-player-is-type
+ :revision revision)
+ assoc))
+ associations))))
(defgeneric associations-of (construct role-type association-type
other-role-type other-player
- &key revision)
+ &key other-role-player-is-type
+ revision)
(:documentation "Returns all associations of the passed topic (construct)
that corresponds to the given values.
If any of the passed values is set to nil, it won't be
used to evaluate the result.")
(:method ((construct TopicC) role-type association-type other-role-type
- other-player &key (revision *TM-REVISION*))
+ other-player &key other-role-player-is-type
+ (revision *TM-REVISION*))
(declare (integer revision)
(type (or Null TopicC) role-type association-type
- other-role-type other-player))
+ other-role-type other-player)
+ (boolean other-role-player-is-type))
(let ((assocs-by-role (map 'list #'(lambda(role)
(parent role :revision revision))
(roles-by-type construct role-type
@@ -116,8 +129,10 @@
(let ((assocs-by-type
(filter-associations-by-type assocs-by-role association-type
:revision revision)))
- (filter-associations-by-role assocs-by-type other-role-type
- other-player :revision revision)))))
+ (filter-associations-by-role
+ assocs-by-type other-role-type other-player
+ :role-player-is-type other-role-player-is-type
+ :revision revision)))))
(defgeneric instance-of-associations (construct &key revision)
@@ -172,14 +187,18 @@
(:method ((construct TopicC) &key (revision *TM-REVISION*))
(declare (integer revision))
(let ((assocs (supertype-associations construct :revision revision)))
- (remove-if #'null
- (map 'list #'(lambda(assoc)
- (find-if-not
- #'(lambda(role)
- (eql (player role :revision revision)
- construct))
- (roles assoc :revision revision)))
- assocs)))))
+ (let ((other-roles
+ (remove-null
+ (map 'list
+ #'(lambda(assoc)
+ (find-if-not #'(lambda(role)
+ (eql (player role :revision revision)
+ construct))
+ (roles assoc :revision revision)))
+ assocs))))
+ (remove-null (map 'list #'(lambda(role)
+ (player role :revision revision))
+ other-roles))))))
(defgeneric supertypes (construct &key revision valid-supertypes)
@@ -196,7 +215,8 @@
direct-super-type :revision revision
:valid-supertypes current-valid-super-types))))
(remove-duplicates
- (remove-if #'null recursive-super-types)))))))
+ (remove-null (union recursive-super-types
+ current-valid-super-types))))))))
(defgeneric direct-instance-of (construct &key revision)
@@ -204,25 +224,27 @@
(:method ((construct TopicC) &key (revision *TM-REVISION*))
(declare (integer revision))
(let ((assocs (instance-of-associations construct :revision revision)))
- (remove-if #'null
- (map 'list #'(lambda(assoc)
- (find-if-not
- #'(lambda(role)
- (eql (player role :revision revision)
- construct))
- (roles assoc :revision revision)))
- assocs)))))
+ (let ((other-roles
+ (remove-null
+ (map 'list #'(lambda(assoc)
+ (find-if-not #'(lambda(role)
+ (eql (player role :revision revision)
+ construct))
+ (roles assoc :revision revision)))
+ assocs))))
+ (remove-null (map 'list #'(lambda(role)
+ (player role :revision revision))
+ other-roles))))))
(defmethod instance-of (construct &key (revision *TM-REVISION*))
"Returns all type topics of the passed construct and their super-types."
(declare (integer revision))
- (let ((all-super-types (supertypes construct :revision revision)))
- (let ((all-types
- (loop for topic in (append (list construct) all-super-types)
- append (direct-instance-of topic :revision revision))))
- (remove-duplicates
- (remove-if #'null all-types)))))
+ (let ((direct-types (direct-instance-of construct :revision revision)))
+ (let ((supertypes-of-types
+ (loop for type in direct-types
+ append (supertypes type :revision revision))))
+ (union direct-types supertypes-of-types))))
(defgeneric invoke-on (construct operation)
@@ -231,50 +253,37 @@
If cast-operation is set to a function the characteristic's
value is first casted by the cast-operation to another type
and afterwords processed by main-opertion.")
- (:method ((construct TopicC) (operation Function))
+ (:method ((construct CharacteristicC) (operation Function))
(funcall operation (charvalue construct))))
-(defgeneric names-by-type (construct type-identifier &key revision)
+(defgeneric names-by-type (construct nametype &key revision)
(:documentation "Returns all names that are of the corresponding type.")
- (:method ((construct TopicC) (type-identifier IdentifierC)
- &key (revision *TM-REVISION*))
- (declare (integer revision))
- (let ((type-topic (identified-construct type-identifier :revision revision)))
- (unless (typep type-topic 'TopicC)
- (error (make-bad-type-condition (format nil "from name-by-type(): expected a topic as instance-of but found ~a" (type-of type-topic)) 'TopicC type-topic)))
- (let ((results
- (map 'list #'(lambda(name)
- (when (instance-of name :revision revision)
- name))
- (names construct :revision revision))))
- (remove-if #'null results)))))
+ (:method ((construct TopicC) nametype &key (revision *TM-REVISION*))
+ (declare (integer revision)
+ (type (or Null TopicC) nametype))
+ (remove-if-not #'(lambda(name)
+ (eql nametype (instance-of name :revision revision)))
+ (names construct :revision revision))))
-(defgeneric occurrences-by-type (construct type-identifier &key revision)
+(defgeneric occurrences-by-type (construct occurrencetype &key revision)
(:documentation "Returns all names that are of the corresponding type.")
- (:method ((construct TopicC) (type-identifier IdentifierC)
+ (:method ((construct TopicC) (occurrencetype TopicC)
&key (revision *TM-REVISION*))
(declare (integer revision))
- (let ((type-topic (identified-construct type-identifier :revision revision)))
- (unless (typep type-topic 'TopicC)
- (error (make-bad-type-condition (format nil "from occurrence-by-type(): expected a topic as instance-of but found ~a" (type-of type-topic)) 'TopicC type-topic)))
- (let ((results
- (map 'list #'(lambda(occ)
- (when (instance-of occ :revision revision)
- occ))
- (occurrences construct :revision revision))))
- (remove-if #'null results)))))
+ (remove-if-not #'(lambda(occ)
+ (eql occurrencetype (instance-of occ :revision revision)))
+ (occurrences construct :revision revision))))
-(defgeneric characteristic-by-type (construct type-identifier &key revision)
+(defgeneric characteristics-by-type (construct chartype &key revision)
(:documentation "Returns all characteristics that are of the
corresponding type.")
- (:method ((construct TopicC) (type-identifier IdentifierC)
- &key (revision *TM-REVISION*))
+ (:method ((construct TopicC) (chartype TopicC) &key (revision *TM-REVISION*))
(declare (integer revision))
- (union (names-by-type construct type-identifier :revision revision)
- (occurrences-by-type construct type-identifier :revision revision))))
+ (union (names-by-type construct chartype :revision revision)
+ (occurrences-by-type construct chartype :revision revision))))
(defgeneric occurrences-by-value (construct filter &key revision)
@@ -287,7 +296,7 @@
(when (invoke-on occ filter)
occ))
(occurrences construct :revision revision))))
- (remove-if #'null results))))
+ (remove-null results))))
(defgeneric names-by-value (construct filter &key revision)
@@ -300,13 +309,33 @@
(when (invoke-on name filter)
name))
(names construct :revision revision))))
- (remove-if #'null results))))
+ (remove-null results))))
-(defgeneric characteristic-by-value (construct filter &key revision)
+(defgeneric characteristics-by-value (construct filter &key revision)
(:documentation "Returns a list of all characteristics of the passed
topic, that return a true value when calling filter.")
(:method ((construct TopicC) (filter Function) &key (revision *TM-REVISION*))
(declare (integer revision))
(union (names-by-value construct filter :revision revision)
- (occurrences-by-value construct filter :revision revision))))
\ No newline at end of file
+ (occurrences-by-value construct filter :revision revision))))
+
+
+(defgeneric isa (construct type &key revision)
+ (:documentation "Returns all types if the passed construct
+ is of the specified type.")
+ (:method ((construct TopicC) (type TopicC) &key (revision *TM-REVISION*))
+ (declare (integer revision))
+ (let ((all-types (instance-of construct :revision revision)))
+ (when (find type all-types)
+ all-types))))
+
+
+(defgeneric aka (construct supertype &key revision)
+ (:documentation "Returns all types if the passed construct
+ is of the specified type.")
+ (:method ((construct TopicC) (supertype TopicC) &key (revision *TM-REVISION*))
+ (declare (integer revision))
+ (let ((all-supertypes (supertypes construct :revision revision)))
+ (when (find supertype all-supertypes)
+ all-supertypes))))
\ No newline at end of file
Modified: trunk/src/unit_tests/fixtures.lisp
==============================================================================
--- trunk/src/unit_tests/fixtures.lisp (original)
+++ trunk/src/unit_tests/fixtures.lisp Thu Nov 11 03:47:23 2010
@@ -13,6 +13,7 @@
:xml-importer
:datamodel
:it.bese.FiveAM
+ :base-tools
:unittests-constants)
(:import-from :constants
*xtm2.0-ns*)
@@ -38,7 +39,8 @@
:*XTM-MERGE2-TM*
:rdf-init-db
:rdf-test-db
- :with-empty-db))
+ :with-empty-db
+ :with-tm-filled-db))
(in-package :fixtures)
@@ -218,4 +220,14 @@
(clean-out-db dir)
(elephant:open-store (xml-importer:get-store-spec dir))
(&body)
- (tear-down-test-db))
\ No newline at end of file
+ (tear-down-test-db))
+
+
+(def-fixture with-tm-filled-db (dir xtm-path)
+ (clean-out-db dir)
+ (let ((tm-id "http://www.isidor.us/unittests/testtm")
+ (xtm-id (full-path xtm-path)))
+ (xml-importer:setup-repository xtm-path dir :tm-id tm-id :xtm-id xtm-id)
+ (elephant:open-store (xml-importer:get-store-spec dir))
+ (&body)
+ (tear-down-test-db)))
\ No newline at end of file
Modified: trunk/src/unit_tests/poems.xtm
==============================================================================
--- trunk/src/unit_tests/poems.xtm (original)
+++ trunk/src/unit_tests/poems.xtm Thu Nov 11 03:47:23 2010
@@ -2629,7 +2629,7 @@
</tm:association>
<tm:association>
- <tm:itemIdentity href="wrrtten-by-erlkoenig-goethe"/>
+ <tm:itemIdentity href="written-by-erlkoenig-goethe"/>
<tm:type><tm:topicRef href="#written-by"/></tm:type>
<tm:role>
<tm:type><tm:topicRef href="#writer"/></tm:type>
Modified: trunk/src/unit_tests/trivial_queries_test.lisp
==============================================================================
--- trunk/src/unit_tests/trivial_queries_test.lisp (original)
+++ trunk/src/unit_tests/trivial_queries_test.lisp Thu Nov 11 03:47:23 2010
@@ -10,19 +10,481 @@
(defpackage :trivial-queries-test
(:use :cl
:it.bese.FiveAM
- :datamodel)
+ :datamodel
+ :unittests-constants
+ :fixtures
+ :constants)
(:export :run-trivial-queries-tests
- :trivial-queries-tests))
+ :trivial-queries-tests
+ :test-aka
+ :test-isa
+ :test-x-by-value
+ :test-x-by-type
+ :test-invoke-on
+ :test-instance-of
+ :test-supertypes
+ :test-direct-instance-of
+ :test-direct-supertypes
+ :test-supertype-associations
+ :test-instance-of-associations
+ :test-associations-of
+ :test-roles-by-type
+ :test-roles-by-player
+ :test-filter-associations-by-type
+ :test-filter-associations-by-role))
(in-package :trivial-queries-test)
-(def-suite trivial-queries-test
+(def-suite trivial-queries-tests
:description "tests various key functions of the trivial-query-test of
the datamodel module")
-(in-suite trivial-queries-test)
+(in-suite trivial-queries-tests)
+
+(test test-aka
+ "Tests the function aka."
+ (with-fixture with-tm-filled-db ("data_base" *poems.xtm*)
+ (with-revision 0
+ (let ((region (get-item-by-id "region"))
+ (city (get-item-by-id "city"))
+ (poem (get-item-by-id "poem"))
+ (supertype (get-item-by-psi *supertype-psi*))
+ (subtype (get-item-by-psi *subtype-psi*))
+ (supertype-subtype (get-item-by-psi *supertype-subtype-psi*))
+ (rev (get-revision)))
+ (is-true region)
+ (is-true city)
+ (is-true poem)
+ (is-true supertype)
+ (is-true subtype)
+ (is-true supertype-subtype)
+ (is-true (aka city region))
+ (is-false (aka city city))
+ (make-construct 'AssociationC
+ :start-revision rev
+ :instance-of supertype-subtype
+ :roles (list (list :start-revision rev
+ :player region
+ :instance-of subtype)
+ (list :start-revision rev
+ :player poem
+ :instance-of supertype)))
+ (is-true (aka city region))
+ (is-true (aka city poem))
+ (is-true (aka region poem))))))
+
+
+(test test-isa
+ "Tests the function isa."
+ (with-fixture with-tm-filled-db ("data_base" *poems.xtm*)
+ (with-revision 0
+ (let ((region (get-item-by-id "region"))
+ (metropolis (get-item-by-id "metropolis"))
+ (poem (get-item-by-id "poem"))
+ (frankfurt (get-item-by-id "frankfurt_am_main")))
+ (is-true region)
+ (is-true frankfurt)
+ (is-true metropolis)
+ (is-true poem)
+ (is-true (isa frankfurt metropolis))
+ (is-true (isa frankfurt region))))))
+
+
+(test test-x-by-value
+ "Tests the functions names-by-value, occurrences-by-value
+ and characteristics-by-value."
+ (with-fixture with-tm-filled-db ("data_base" *poems.xtm*)
+ (with-revision 0
+ (let ((goethe (get-item-by-id "goethe"))
+ (poem (get-item-by-id "poem"))
+ (fn "Johann Wolfgang")
+ (ln "von Goethe")
+ (ai "http://de.wikipedia.org/wiki/Johann_Wolfgang_von_Goethe")
+ (as "any string"))
+ (let ((fun-fn (lambda(value)
+ (string= value fn)))
+ (fun-ln (lambda(value)
+ (string= value ln)))
+ (fun-ai (lambda(value)
+ (string= value ai)))
+ (fun-as (lambda(value)
+ (string= value as))))
+ (is-true goethe)
+ (is-true poem)
+ (is-false (names-by-value goethe fun-as))
+ (is-false (occurrences-by-value goethe fun-as))
+ (is-false (characteristics-by-value goethe fun-as))
+ (is (= (length (names-by-value goethe fun-fn)) 1))
+ (is (= (length (names-by-value goethe fun-ln)) 1))
+ (is (= (length (occurrences-by-value goethe fun-ai)) 1))
+ (is (string= (charvalue (first (names-by-value goethe fun-fn)))
+ fn))
+ (is (string= (charvalue (first (names-by-value goethe fun-ln)))
+ ln))
+ (is (string= (charvalue (first (occurrences-by-value goethe fun-ai)))
+ ai))
+ (is (= (length (characteristics-by-value goethe fun-fn)) 1))
+ (is (string=
+ (charvalue (first (characteristics-by-value goethe fun-fn)))
+ fn)))))))
+
+
+(test test-x-by-type
+ "Tests the functions names-by-type, occurrences-by-type
+ and characteristics-by-type."
+ (with-fixture with-tm-filled-db ("data_base" *poems.xtm*)
+ (with-revision 0
+ (let ((goethe (get-item-by-id "goethe"))
+ (first-name (get-item-by-id "first-name"))
+ (last-name (get-item-by-id "last-name"))
+ (author-info (get-item-by-id "author-info"))
+ (poem (get-item-by-id "poem")))
+ (is-true goethe)
+ (is-true first-name)
+ (is-true last-name)
+ (is-true author-info)
+ (is-true poem)
+ (is-false (names-by-type goethe poem))
+ (is-false (occurrences-by-type goethe poem))
+ (is-false (characteristics-by-type goethe poem))
+ (is (= (length (names-by-type goethe first-name)) 1))
+ (is (= (length (names-by-type goethe last-name)) 1))
+ (is (= (length (occurrences-by-type goethe author-info)) 1))
+ (is (string= (charvalue (first (names-by-type goethe first-name)))
+ "Johann Wolfgang"))
+ (is (string= (charvalue (first (names-by-type goethe last-name)))
+ "von Goethe"))
+ (is (string=
+ (charvalue (first (occurrences-by-type goethe author-info)))
+ "http://de.wikipedia.org/wiki/Johann_Wolfgang_von_Goethe"))
+ (is (= (length (characteristics-by-type goethe first-name)) 1))
+ (is (string=
+ (charvalue (first (characteristics-by-type goethe first-name)))
+ "Johann Wolfgang"))))))
+
+
+(test test-invoke-on
+ "Tests the function invoke-on."
+ (with-fixture with-tm-filled-db ("data_base" *poems.xtm*)
+ (with-revision 0
+ (let ((frankfurt (get-item-by-id "frankfurt_am_main")))
+ (is-true frankfurt)
+ (is (= (length (occurrences frankfurt)) 1))
+ (is (= (invoke-on (first (occurrences frankfurt))
+ #'(lambda(value)
+ (+ 1 (parse-integer value))))
+ (+ 1 659021)))))))
+
+
+
+(test test-instance-of
+ "Tests the function instance-of."
+ (with-fixture with-tm-filled-db ("data_base" *poems.xtm*)
+ (with-revision 0
+ (let ((region (get-item-by-id "region"))
+ (metropolis (get-item-by-id "metropolis"))
+ (poem (get-item-by-id "poem"))
+ (frankfurt (get-item-by-id "frankfurt_am_main")))
+ (is-true region)
+ (is-true frankfurt)
+ (is-true metropolis)
+ (is-true poem)
+ (is (= (length (instance-of frankfurt)) 2))
+ (is-false (set-exclusive-or (instance-of frankfurt)
+ (list metropolis region)))))))
+
+
+(test test-supertypes
+ "Tests the function supertypes."
+ (with-fixture with-tm-filled-db ("data_base" *poems.xtm*)
+ (with-revision 0
+ (let ((region (get-item-by-id "region"))
+ (city (get-item-by-id "city"))
+ (poem (get-item-by-id "poem"))
+ (supertype (get-item-by-psi *supertype-psi*))
+ (subtype (get-item-by-psi *subtype-psi*))
+ (supertype-subtype (get-item-by-psi *supertype-subtype-psi*))
+ (rev (get-revision)))
+ (is-true region)
+ (is-true city)
+ (is-true poem)
+ (is-true supertype)
+ (is-true subtype)
+ (is-true supertype-subtype)
+ (is (= (length (supertypes city)) 1))
+ (is (eql (first (supertypes city)) region))
+ (is-false (supertypes region))
+ (make-construct 'AssociationC
+ :start-revision rev
+ :instance-of supertype-subtype
+ :roles (list (list :start-revision rev
+ :player region
+ :instance-of subtype)
+ (list :start-revision rev
+ :player poem
+ :instance-of supertype)))
+ (is (= (length (supertypes city)) 2))))))
+
+
+(test test-direct-instance-of
+ "Tests the function direct-instance-of."
+ (with-fixture with-tm-filled-db ("data_base" *poems.xtm*)
+ (with-revision 0
+ (let ((region (get-item-by-id "region"))
+ (frankfurt (get-item-by-id "frankfurt_am_main"))
+ (metropolis (get-item-by-id "metropolis")))
+ (is-true region)
+ (is-true metropolis)
+ (is-true frankfurt)
+ (is (= (length (direct-instance-of frankfurt)) 1))
+ (is (eql (first (direct-instance-of frankfurt)) metropolis))
+ (is-false (direct-instance-of metropolis))))))
+
+
+(test test-direct-supertypes
+ "Tests the function direct-supertypes."
+ (with-fixture with-tm-filled-db ("data_base" *poems.xtm*)
+ (with-revision 0
+ (let ((region (get-item-by-id "region"))
+ (city (get-item-by-id "city"))
+ (poem (get-item-by-id "poem"))
+ (supertype (get-item-by-psi *supertype-psi*))
+ (subtype (get-item-by-psi *subtype-psi*))
+ (supertype-subtype (get-item-by-psi *supertype-subtype-psi*))
+ (rev (get-revision)))
+ (is-true region)
+ (is-true city)
+ (is-true poem)
+ (is-true supertype)
+ (is-true subtype)
+ (is-true supertype-subtype)
+ (is (= (length (direct-supertypes city)) 1))
+ (is (eql (first (direct-supertypes city)) region))
+ (is-false (direct-supertypes region))
+ (make-construct 'AssociationC
+ :start-revision rev
+ :instance-of supertype-subtype
+ :roles (list (list :start-revision rev
+ :player region
+ :instance-of subtype)
+ (list :start-revision rev
+ :player poem
+ :instance-of supertype)))
+ (is (= (length (direct-supertypes city)) 1))))))
+
+
+(test test-supertype-associations
+ "Tests the function supertype-associations."
+ (with-fixture with-tm-filled-db ("data_base" *poems.xtm*)
+ (with-revision 0
+ (let ((region (get-item-by-id "region"))
+ (city (get-item-by-id "city"))
+ (metropolis (get-item-by-id "metropolis"))
+ (assocs (get-all-associations))
+ (supertype (get-item-by-psi *supertype-psi*))
+ (subtype (get-item-by-psi *subtype-psi*))
+ (supertype-subtype (get-item-by-psi *supertype-subtype-psi*)))
+ (is-true region)
+ (is-true city)
+ (is-true metropolis)
+ (is-true supertype)
+ (is-true subtype)
+ (is-true supertype-subtype)
+ (let ((assoc-city
+ (find-if
+ #'(lambda(assoc)
+ (and (eql (instance-of assoc) supertype-subtype)
+ (find-if #'(lambda(role)
+ (and (eql (player role) city)
+ (eql (instance-of role) subtype)))
+ (roles assoc))
+ (find-if #'(lambda(role)
+ (and (eql (player role) region)
+ (eql (instance-of role) supertype)))
+ (roles assoc))))
+ assocs))
+ (assoc-metropolis
+ (find-if
+ #'(lambda(assoc)
+ (and (eql (instance-of assoc) supertype-subtype)
+ (find-if #'(lambda(role)
+ (and (eql (player role) metropolis)
+ (eql (instance-of role) subtype)))
+ (roles assoc))
+ (find-if #'(lambda(role)
+ (and (eql (player role) region)
+ (eql (instance-of role) supertype)))
+ (roles assoc))))
+ assocs)))
+ (is-true assoc-city)
+ (is-true assoc-metropolis)
+ (is (= (length (supertype-associations city)) 1))
+ (is (= (length (supertype-associations metropolis)) 1))
+ (is (eql (first (supertype-associations city)) assoc-city))
+ (is (eql (first (supertype-associations metropolis)) assoc-metropolis))
+ (is-false (supertype-associations region)))))))
+
+
+(test test-instance-of-associations
+ "Tests the function instance-of-associations."
+ (with-fixture with-tm-filled-db ("data_base" *poems.xtm*)
+ (with-revision 0
+ (let ((goethe (get-item-by-id "goethe"))
+ (instance (get-item-by-psi *instance-psi*))
+ (type (get-item-by-psi *type-psi*))
+ (type-instance (get-item-by-psi *type-instance-psi*))
+ (author (get-item-by-id "author")))
+ (is-true goethe)
+ (is-true instance)
+ (is-true type)
+ (is-true type-instance)
+ (is-true author)
+ (is (= (length (instance-of-associations goethe)) 1))
+ (is (eql type-instance
+ (instance-of (first (instance-of-associations goethe)))))
+ (is-true (filter-associations-by-role (instance-of-associations goethe)
+ instance goethe))
+ (is-true (filter-associations-by-role (instance-of-associations goethe)
+ type author))
+ (is-true (filter-associations-by-type (instance-of-associations goethe)
+ type-instance))))))
+
+
+(test test-associations-of
+ "Tests the function associations-of."
+ (with-fixture with-tm-filled-db ("data_base" *poems.xtm*)
+ (with-revision 0
+ (let ((goethe (get-item-by-id "goethe"))
+ (writer (get-item-by-id "writer"))
+ (written-by (get-item-by-id "written-by"))
+ (written (get-item-by-id "written"))
+ (erlkoenig (get-item-by-id "erlkoenig"))
+ (instance (get-item-by-psi *instance-psi*))
+ (poem (get-item-by-id "poem")))
+ (is-true goethe)
+ (is-true writer)
+ (is-true written-by)
+ (is-true written)
+ (is-true erlkoenig)
+ (is-true instance)
+ (is-true poem)
+ (is (= (length (associations-of goethe nil nil nil nil)) 4))
+ (is (= (length (associations-of goethe writer nil nil nil)) 3))
+ (is (= (length (associations-of goethe writer written-by nil nil)) 2))
+ (is (= (length (associations-of goethe writer written-by written nil)) 2))
+ (is (= (length (associations-of goethe writer written-by written erlkoenig)) 1))
+ (is-false (associations-of goethe writer written-by written instance))
+ (is-false (associations-of goethe writer written-by instance erlkoenig))
+ (is (= (length (associations-of goethe instance nil nil nil)) 1))
+ (is-false (associations-of goethe writer written-by written erlkoenig
+ :other-role-player-is-type t))
+ (is (= (length (associations-of goethe writer written-by written poem
+ :other-role-player-is-type t)) 2))))))
+
+
+(test test-roles-by-type
+ "Tests the function roles-by-type bound to TopicC and AssociationC."
+ (with-fixture with-tm-filled-db ("data_base" *poems.xtm*)
+ (with-revision 0
+ (let ((goethe (get-item-by-id "goethe"))
+ (writer (get-item-by-id "writer"))
+ (written (get-item-by-id "written"))
+ (instance (get-item-by-psi *instance-psi*))
+ (assoc (get-item-by-item-identifier "written-by-erlkoenig-goethe")))
+ (is-true goethe)
+ (is-true writer)
+ (is-true written)
+ (is-true instance)
+ (is-true assoc)
+ (is (= (length (roles-by-type goethe writer)) 3))
+ (is (= (length (roles-by-type goethe nil)) 4))
+ (is (= (length (roles-by-type goethe instance)) 1))
+ (is-false (roles-by-type goethe written))
+ (is (= (length (roles-by-type assoc writer)) 1))
+ (is (eql writer (instance-of (first (roles-by-type assoc writer)))))
+ (is (= (length (roles-by-type assoc nil)) 2))))))
+
+
+(test test-roles-by-player
+ "Tests the function roles-by-player."
+ (with-fixture with-tm-filled-db ("data_base" *poems.xtm*)
+ (with-revision 0
+ (let ((goethe (get-item-by-id "goethe"))
+ (writer (get-item-by-id "writer"))
+ (written (get-item-by-id "written"))
+ (instance (get-item-by-psi *instance-psi*))
+ (assoc (get-item-by-item-identifier "written-by-erlkoenig-goethe"))
+ (author (get-item-by-id "author")))
+ (is-true goethe)
+ (is-true author)
+ (is-true writer)
+ (is-true written)
+ (is-true instance)
+ (is-true assoc)
+ (is (= (length (roles-by-player assoc goethe)) 1))
+ (is (eql goethe (player (first (roles-by-player assoc goethe)))))
+ (is (= (length (roles-by-player assoc written)) 0))
+ (is (= (length (roles-by-player assoc nil)) 2))
+ (is (= (length (roles-by-player assoc author :role-player-is-type t))
+ 1))
+ (is-false (roles-by-player assoc goethe :role-player-is-type t))
+ (is (eql goethe (player (first (roles-by-player
+ assoc author
+ :role-player-is-type t)))))))))
+
+
+(test test-filter-associations-by-type
+ "Tests the function roles-by-player."
+ (with-fixture with-tm-filled-db ("data_base" *poems.xtm*)
+ (with-revision 0
+ (let ((written-by (get-item-by-id "written-by"))
+ (born-in (get-item-by-id "born-in"))
+ (assocs (get-all-associations)))
+ (is-true written-by)
+ (is-true assocs)
+ (is-true born-in)
+ (is (= (length (filter-associations-by-type assocs written-by)) 4))
+ (is (> (length (filter-associations-by-type assocs nil)) (+ 4 2)))
+ (is (= (length (filter-associations-by-type assocs born-in)) 2))))))
+
+
+(test test-filter-associations-by-role
+ "Tests the function roles-by-player."
+ (with-fixture with-tm-filled-db ("data_base" *poems.xtm*)
+ (with-revision 0
+ (let ((written-by (get-item-by-id "written-by"))
+ (born-in (get-item-by-id "born-in"))
+ (written (get-item-by-id "written"))
+ (writer (get-item-by-id "writer"))
+ (place (get-item-by-id "place"))
+ (goethe (get-item-by-id "goethe"))
+ (frankfurt (get-item-by-id "frankfurt_am_main"))
+ (assocs (get-all-associations))
+ (author (get-item-by-id "author")))
+ (is-true written-by)
+ (is-true assocs)
+ (is-true born-in)
+ (is-true author)
+ (is-true written)
+ (is-true writer)
+ (is-true place)
+ (is-true frankfurt)
+ (is (= (length (filter-associations-by-role assocs place frankfurt)) 1))
+ (is (= (length (filter-associations-by-role assocs written nil)) 4))
+ (is (= (length (filter-associations-by-role assocs written goethe)) 2))
+ (is (= (length (filter-associations-by-role assocs writer nil)) 6))
+ (is (= (length (filter-associations-by-role assocs nil goethe)) 4))
+ (is (> (length (filter-associations-by-role assocs nil nil)) (+ 4 3)))
+ (is-false (filter-associations-by-role assocs writer goethe
+ :role-player-is-type t))
+ (is (= (length (filter-associations-by-role assocs writer author
+ :role-player-is-type t))
+ 6))))))
+
+
+
(defun run-trivial-queries-tests ()
Modified: trunk/src/unit_tests/unittests-constants.lisp
==============================================================================
--- trunk/src/unit_tests/unittests-constants.lisp (original)
+++ trunk/src/unit_tests/unittests-constants.lisp Thu Nov 11 03:47:23 2010
@@ -29,6 +29,7 @@
:*t100.xtm*
:*atom_test.xtm*
:*atom-conf.lisp*
+ :*poems.xtm*
:*poems_light.rdf*
:*poems_light.xtm*
:*poems_light.xtm.txt*
@@ -100,6 +101,10 @@
(asdf:component-pathname
(asdf:find-component *unit-tests-component* "atom-conf")))
+(defparameter *poems.xtm*
+ (asdf:component-pathname
+ (asdf:find-component *unit-tests-component* "poems.xtm")))
+
(defparameter *poems_light.rdf*
(asdf:component-pathname
(asdf:find-component *unit-tests-component* "poems_light.rdf")))
1
0