source: branches/new-datamodel/src/xml/xtm/importer.lisp

Last change on this file was 306, checked in by lgiessmann, 14 years ago

new-datamodel: fixed bugs in get-latest-topic-by-psi, find-all-associations-for-topic, find-associations-for-topic, changed-p, with-tm; adapted the json-unit-tests to the new datamodel

  • Property svn:eol-style set to native
File size: 6.9 KB
Line 
1;;+-----------------------------------------------------------------------------
2;;+  Isidorus
3;;+  (c) 2008-2009 Marc Kuester, Christoph Ludwig, Lukas Giessmann
4;;+
5;;+  Isidorus is freely distributable under the LGPL license.
6;;+  You can find a detailed description in trunk/docs/LGPL-LICENSE.txt.
7;;+-----------------------------------------------------------------------------
8
9
10;; TODOs (in descending priority):
11;; * resolve non-local topicRefs
12;; * either check the input document for XTM2.0 conformance in advance or
13;;   raise some kind of error (--> condition) if something goes wrong.
14;; * handle reifier attributes
15;; * handle variants
16;;
17
18(defpackage :xml-importer
19  (:use :cl :cxml :elephant :datamodel :isidorus-threading)
20  (:import-from :constants
21                *type-instance-psi*
22                *type-psi*
23                *instance-psi*
24                *XTM2.0-NS*
25                *XTM1.0-NS*
26                *XTM1.0-XLINK*
27                *XML-STRING*
28                *XML-URI*)
29  (:import-from :xml-constants
30                *core_psis.xtm*)
31  (:import-from :xml-tools
32                get-attribute
33                 xpath-fn-string
34                 xpath-child-elems-by-qname
35                 xpath-single-child-elem-by-qname
36                 xpath-select-location-path
37                 xpath-select-single-location-path)
38  (:import-from :exceptions
39                missing-reference-error
40                duplicate-identifier-error)
41  (:export :create-instanceof-association
42           :from-association-elem
43           :from-name-elem
44           :from-occurrence-elem
45           :from-role-elem
46           :from-scope-elem
47           :from-topic-elem-to-stub
48           :from-type-elem
49           :get-store-spec
50           :get-topicref-uri
51           :import-only-topics
52           :import-xtm
53           :importer 
54           :init-isidorus
55           :merge-topic-elem 
56           :setup-repository
57           :get-topicid-by-psi
58           :get-topic-id-xtm1.0
59           :from-resourceRef-elem-xtm1.0
60           :from-baseName-elem-xtm1.0
61           :from-variant-elem-xtm1.0
62           :from-topicRef-elem-xtm1.0
63           :from-resourceX-elem-xtm1.0
64           :from-variant-elem-xtm1.0
65           :from-parameters-elem-xtm1.0
66           :get-xlink-attribute
67           :get-instanceOf-refs-xtm1.0
68           :from-roleSpec-elem-xtm1.0
69           :from-scope-elem-xtm1.0
70           :from-occurrence-elem-xtm1.0
71           :from-subjectIdentity-elem-xtm1.0
72           :from-member-elem-xtm1.0
73           :from-topic-elem-to-stub-xtm1.0
74           :merge-topic-elem-xtm1.0
75           :from-association-elem-xtm1.0
76           :importer-xtm1.0
77           :with-tm))
78
79(in-package :xml-importer)
80
81;(declaim (optimize (debug 3)))
82
83(defun get-store-spec (pathname)
84  "return the store spec for elephant and ensure that the path name is absolute"
85  (list :BDB (truename pathname)))
86
87
88(defun get-topicref-uri (topicref-elem)
89  "Extract the uri from a topicref"
90  ;TODO: at present, this resolves only local topicRefs by cutting off
91  ;the first character ('#')
92  (declare (dom:element topicref-elem))
93  (let 
94      ((topicref (get-attribute topicref-elem "href")))
95    (unless (char= (elt topicref 0) #\#)
96      (error "cannot handle topicrefs that don't start with #"))
97    (subseq topicref 1)))
98
99(defun get-topicid-by-psi (uri &key (xtm-id d:*current-xtm*) (revision *TM-REVISION*))
100  (when uri
101    (loop for item in 
102         (topic-identifiers
103          (identified-construct (elephant:get-instance-by-value 'PersistentIdC 'uri uri)) :revision revision)
104       when (string= xtm-id (xtm-id item))
105       return (uri item))))
106
107
108(defmacro with-tm ((revision xtm-id tm-id) &body body)
109  "creates a topic map object called tm and puts it into the local scope"
110  `(let ((ii (make-construct 'ItemIdentifierC 
111                             :uri ,tm-id
112                             :start-revision ,revision)))
113     (let ((tm 
114            (make-construct 'TopicMapC 
115                            :start-revision ,revision
116                            :xtm-id ,xtm-id
117                            :item-identifiers (list ii))))
118       (declare (ItemIdentifierC ii))
119       (declare (TopicMapC tm))
120       ,@body)))
121
122
123(defun init-isidorus (&optional (revision (get-revision)))
124  "Initiatlize the database with the stubs of the core topics + PSIs
125defined in the XTM 1.0 spec. This includes a topic that represents the
126core TM"
127  (with-writer-lock
128    (with-tm (revision "core.xtm" "http://www.topicmaps.org/xtm/1.0/core.xtm")
129      (let
130          ((core-dom 
131            (cxml:parse-file *core_psis.xtm* (cxml-dom:make-dom-builder))))
132        (loop for top-elem across 
133             (xpath-child-elems-by-qname (dom:document-element core-dom)
134                                         *xtm2.0-ns* "topic")
135           do
136             (let
137                 ((top
138                   (from-topic-elem-to-stub top-elem revision :xtm-id "core.xtm")))
139               (add-to-tm tm top)))))))
140
141;TODO: replace the two importers with this macro
142(defmacro importer-mac
143    (get-topic-elems get-association-elems 
144     from-topic-elem-to-stub merge-topic-elem from-association-elem)
145  `(lambda (xtm-dom &key (xtm-id d:*current-xtm*) (revision (get-revision)))
146    (declare (dom:element xtm-dom))
147    (declare (integer revision))        ;all topics that are imported in one go share the same revision
148   
149    (let
150        ((topic-vector (,get-topic-elems xtm-dom))
151         (assoc-vector (,get-association-elems xtm-dom)))
152      (loop for top-elem across topic-vector do
153           (,from-topic-elem-to-stub top-elem revision :xtm-id xtm-id))
154      (loop for top-elem across topic-vector do
155           (format t "t")
156           (,merge-topic-elem top-elem revision :xtm-id xtm-id))
157      (loop for assoc-elem across assoc-vector do
158           (,from-association-elem assoc-elem revision :xtm-id xtm-id)))))
159 
160
161(defun create-instanceof-association (topicid-of-supertype player2-obj start-revision 
162                                      &key 
163                                      tm
164                                      (xtm-id *current-xtm*))
165  "handle the instanceOf element. The instanceOf element is different
166  from all the others in that it is not modelled one to one, but
167  following the suggestion of the XTM 2.0 spec (4.9) and the
168  TMDM (7.2) as an association"
169 ;instanceOf = element instanceOf { topicRef+ }
170  (declare (string topicid-of-supertype))
171  (declare (TopicC player2-obj))
172  (declare (TopicMapC tm))
173  (let
174      ((associationtype 
175        (get-item-by-psi *type-instance-psi* :revision start-revision))
176       (roletype1
177        (get-item-by-psi *type-psi* :revision start-revision))
178       (roletype2
179        (get-item-by-psi *instance-psi* :revision start-revision))
180       (player1
181        (get-item-by-id topicid-of-supertype 
182                        :xtm-id xtm-id 
183                        :revision start-revision)))
184    (unless (and associationtype roletype1 roletype2)
185      (error "Error in the creation of an instanceof association: core topics are missing"))
186    (unless player1 
187      (error
188       (make-condition 'missing-reference-error
189                       :message "could not find type topic (first player)"
190                       :reference topicid-of-supertype)))
191    (add-to-tm 
192     tm
193     (make-construct 
194      'AssociationC
195      :item-identifiers nil
196      :themes nil
197      :start-revision start-revision
198      :instance-of associationtype
199      :roles (list (list :start-revision start-revision
200                         :instance-of roletype1
201                         :player player1)
202                   (list :start-revision start-revision
203                         :instance-of roletype2
204                         :player player2-obj))))))
Note: See TracBrowser for help on using the repository browser.