source: trunk/src/xml/rdf/importer.lisp

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

JTM: added the functions: make-prefix-list-from-jtm-list, import-construct-from-jtm-string, import-from-jtm, import-topic-map-from-jtm-list, and import-role-from-jtm-list

File size: 33.1 KB
Line 
1;;+-----------------------------------------------------------------------------
2;;+  Isidorus
3;;+  (c) 2008-2010 Marc Kuester, Christoph Ludwig, Lukas Georgieff
4;;+
5;;+  Isidorus is freely distributable under the LLGPL license.
6;;+  You can find a detailed description in trunk/docs/LLGPL-LICENSE.txt and
7;;+  trunk/docs/LGPL-LICENSE.txt.
8;;+-----------------------------------------------------------------------------
9(in-package :rdf-importer)
10
11(defun setup-rdf-module (rdf-xml-path repository-path 
12                         &key tm-id (document-id (get-uuid)))
13  "Sets up the data base by importing core_psis.xtm and
14   rdf_core_psis.xtm afterwards the file corresponding
15   to the give file path is imported."
16  (declare ((or pathname string) rdf-xml-path))
17  (declare ((or pathname string) repository-path))
18  (open-tm-store repository-path)
19  (xtm-importer:init-isidorus)
20  (init-rdf-module)
21  (import-from-rdf rdf-xml-path repository-path :tm-id tm-id
22                   :document-id document-id)
23  (when elephant:*store-controller*
24    (close-tm-store)))
25
26
27(defun import-from-rdf (rdf-xml-path repository-path 
28                        &key 
29                        (tm-id nil)
30                        (document-id (get-uuid))
31                        (start-revision (d:get-revision)))
32  "Imports the file correponding to the given path."
33  (setf *document-id* document-id)
34  (tm-id-p tm-id "rdf-importer")
35  (with-writer-lock
36    (open-tm-store repository-path)
37    (let ((rdf-dom
38           (dom:document-element (cxml:parse-file
39                                  (truename rdf-xml-path)
40                                  (cxml-dom:make-dom-builder)))))
41      (import-dom rdf-dom start-revision :tm-id tm-id :document-id document-id))
42    (map-to-tm tm-id start-revision :document-id document-id)
43    (format t "#Objects in the store: Topics: ~a, Associations: ~a~%"
44            (length (elephant:get-instances-by-class 'TopicC))
45            (length (elephant:get-instances-by-class 'AssociationC)))
46    (close-tm-store)
47    (setf *_n-map* nil)))
48
49
50(defun init-rdf-module (&optional (revision (get-revision)))
51  "Imports the file rdf_core_psis.xtm. core_psis.xtm has to be imported
52   before."
53  (with-writer-lock
54    (with-tm (revision "rdf.xtm" "http://isidorus/rdf2tm_mapping/rdf.xtm")
55      (let
56          ((core-dom 
57            (cxml:parse-file *rdf_core_psis.xtm* (cxml-dom:make-dom-builder))))
58        (elephant:ensure-transaction (:txn-nosync t)
59          (loop for top-elem across 
60               (xpath-child-elems-by-qname (dom:document-element core-dom)
61                                           *xtm2.0-ns* "topic")
62             do
63               (let
64                   ((top
65                     (from-topic-elem-to-stub top-elem revision
66                                              :xtm-id *rdf-core-xtm*)))
67                 (add-to-tm xtm-importer::tm top))))))))
68
69
70(defun import-dom (rdf-dom start-revision
71                   &key (tm-id nil) (document-id *document-id*))
72  "Imports the entire dom of an rdf-xml-file."
73  (setf *_n-map* nil) ;in case of an failed last call
74  (tm-id-p tm-id "import-dom")
75  (let ((xml-base (get-xml-base rdf-dom))
76        (xml-lang (get-xml-lang rdf-dom))
77        (elem-name (get-node-name rdf-dom))
78        (elem-ns (dom:namespace-uri rdf-dom)))
79    (if (and (string= elem-ns *rdf-ns*)
80             (string= elem-name "RDF"))
81        (let ((children (child-nodes-or-text rdf-dom :trim t)))
82          (when children
83            (loop for child across children
84               do (import-node child tm-id start-revision
85                               :document-id document-id
86                               :parent-xml-base xml-base
87                               :parent-xml-lang xml-lang))))
88        (import-node rdf-dom tm-id start-revision
89                     :document-id document-id
90                     :parent-xml-base xml-base
91                     :parent-xml-lang xml-lang)))
92  (setf *_n-map* nil))
93
94
95(defun import-node (elem tm-id start-revision &key (document-id *document-id*)
96                    (parent-xml-base nil) (parent-xml-lang nil))
97  "Imports an RDF node with all its properties and 'child' RDF nodes."
98  (tm-id-p tm-id "import-node")
99  (parse-node elem)
100  (let ((about (get-absolute-attribute elem tm-id parent-xml-base "about"))
101        (nodeID (get-ns-attribute elem "nodeID"))
102        (ID (get-absolute-attribute elem tm-id parent-xml-base "ID"))
103        (UUID (get-ns-attribute elem "UUID" :ns-uri *rdf2tm-ns*)))
104    (parse-properties-of-node elem (or about nodeID ID UUID))
105    (let ((literals (append (get-literals-of-node elem parent-xml-lang)
106                            (get-literals-of-node-content
107                             elem tm-id parent-xml-base parent-xml-lang)))
108          (associations (get-associations-of-node-content elem tm-id
109                                                          parent-xml-base))
110          (types (get-types-of-node elem tm-id 
111                                    :parent-xml-base parent-xml-base))
112          (super-classes
113           (get-super-classes-of-node-content elem tm-id parent-xml-base)))
114      (with-tm (start-revision document-id tm-id)
115        (let ((this
116               (make-topic-stub
117                about ID nodeID UUID start-revision xtm-importer::tm
118                :document-id document-id)))
119          (make-literals this literals tm-id start-revision
120                         :document-id document-id)
121          (make-associations this associations xtm-importer::tm
122                             start-revision :document-id document-id)
123          (make-types this types xtm-importer::tm start-revision
124                      :document-id document-id)
125          (make-super-classes this super-classes xtm-importer::tm
126                              start-revision :document-id document-id)
127          (make-recursion-from-node elem tm-id start-revision
128                                    :document-id document-id
129                                    :parent-xml-base parent-xml-base
130                                    :parent-xml-lang parent-xml-lang)
131          this)))))
132
133
134(defun import-arc (elem tm-id start-revision
135                   &key (document-id *document-id*)
136                   (parent-xml-base nil) (parent-xml-lang nil))
137  "Imports a property that is a blank_node and continues the recursion
138   on this element."
139  (declare (dom:element elem))
140  (let ((xml-lang (get-xml-lang elem :old-lang parent-xml-lang))
141        (UUID (get-ns-attribute elem "UUID" :ns-uri *rdf2tm-ns*))
142        (parseType (get-ns-attribute elem "parseType"))
143        (content (child-nodes-or-text elem :trim t)))
144    (with-tm (start-revision document-id tm-id)
145      (if (and (string= parseType "Collection")
146               (= (length content) 0))
147            (make-topic-stub *rdf-nil* nil nil nil start-revision
148                             xtm-importer::tm :document-id document-id)
149          (let ((this-topic
150                 (when (or (not parseType)
151                           (and parseType
152                                (string/= parseType "Collection")))
153                   (when UUID
154                     (parse-properties-of-node elem UUID)
155                     (let ((this
156                            (get-item-by-id UUID :xtm-id document-id
157                                            :revision start-revision)))
158                       (let ((literals
159                              (append (get-literals-of-property
160                                       elem xml-lang)
161                                      (get-literals-of-node-content
162                                       elem tm-id parent-xml-base
163                                       parent-xml-lang)))
164                             (associations
165                              (get-associations-of-node-content
166                               elem tm-id parent-xml-base))
167                             (types
168                              (remove-if
169                               #'null
170                               (append
171                                (get-types-of-node-content elem tm-id
172                                                           parent-xml-base)
173                                (when (get-ns-attribute elem "type")
174                                  (list :ID nil
175                                        :topicid (get-ns-attribute elem "type")
176                                        :psi (get-ns-attribute elem "type"))))))
177                             (super-classes
178                              (get-super-classes-of-node-content
179                               elem tm-id parent-xml-base)))
180                         (make-literals this literals tm-id start-revision
181                                        :document-id document-id)
182                         (make-associations this associations xtm-importer::tm
183                                            start-revision :document-id document-id)
184                         (make-types this types xtm-importer::tm start-revision
185                                     :document-id document-id)
186                         (make-super-classes
187                          this super-classes xtm-importer::tm
188                          start-revision :document-id document-id))
189                       this)))))
190            (make-recursion-from-arc elem tm-id start-revision
191                                     :document-id document-id
192                                     :parent-xml-base parent-xml-base
193                                     :parent-xml-lang parent-xml-lang)
194            this-topic)))))
195
196
197(defun make-collection (elem tm-id start-revision
198                        &key (document-id *document-id*)
199                        (parent-xml-base nil) (parent-xml-lang nil))
200  "Creates a collection structure of a node that contains
201   parseType='Collection."
202  (declare (dom:element elem))
203  (with-tm (start-revision document-id tm-id)
204    (let ((xml-base (get-xml-base elem :old-base parent-xml-base))
205          (xml-lang (get-xml-lang elem :old-lang parent-xml-lang))
206          (UUID (get-ns-attribute elem "UUID" :ns-uri *rdf2tm-ns*)))
207      (let ((this (make-topic-stub nil nil nil UUID start-revision
208                                   xtm-importer::tm
209                                   :document-id document-id))
210            (items (loop for item across (child-nodes-or-text elem :trim t)
211                      collect (import-node item tm-id start-revision
212                                           :document-id document-id
213                                           :parent-xml-base xml-base
214                                           :parent-xml-lang xml-lang))))
215        (let ((last-blank-node this))
216          (dotimes (index (length items))
217            (let ((is-end
218                   (if (= index (- (length items) 1))
219                       t
220                       nil)))
221              (let ((new-blank-node
222                     (make-collection-association
223                      last-blank-node (elt items index) tm-id  start-revision
224                      :is-end is-end :document-id document-id)))
225                (setf last-blank-node new-blank-node)))))))))
226
227
228(defun make-collection-association (current-blank-node first-object tm-id
229                                    start-revision &key (is-end nil)
230                                    (document-id *document-id*))
231  "Creates a 'first'-association between the current-blank-node and the
232   first-object. If is-end is set to true another association between
233   current-blank-node and the topic rdf:nil is created. Otherwise this
234   associaiton is made from the current-blank-node to a new created blank
235   node."
236  (declare (d:TopicC current-blank-node first-object))
237  (with-tm (start-revision document-id tm-id)
238    (let ((first-arc
239           (make-topic-stub *rdf-first* nil nil nil start-revision 
240                            xtm-importer::tm :document-id document-id))
241          (rest-arc
242           (make-topic-stub *rdf-rest* nil nil nil start-revision
243                            xtm-importer::tm :document-id document-id)))
244      (make-association-with-nodes current-blank-node first-object first-arc
245                                   xtm-importer::tm start-revision
246                                   :document-id document-id)
247      (if is-end
248          (let ((rdf-nil (make-topic-stub *rdf-nil* nil nil nil
249                                          start-revision xtm-importer::tm
250                                          :document-id document-id)))
251            (make-association-with-nodes
252             current-blank-node rdf-nil rest-arc xtm-importer::tm
253             start-revision :document-id document-id)
254            nil)
255          (let ((new-blank-node (make-topic-stub
256                                 nil nil nil (get-uuid) start-revision
257                                 xtm-importer::tm :document-id document-id)))
258            (make-association-with-nodes
259             current-blank-node new-blank-node rest-arc xtm-importer::tm
260             start-revision :document-id document-id)
261            new-blank-node)))))
262
263
264(defun make-literals (owner-top literals tm-id start-revision
265                      &key (document-id *document-id*))
266  "Creates Topic Maps constructs (occurrences) of the passed
267   named list literals related to the topic owner-top."
268  (declare (d:TopicC owner-top))
269  (map 'list #'(lambda(literal)
270                 (make-occurrence owner-top literal start-revision
271                                  tm-id :document-id document-id))
272       literals))
273
274
275(defun make-associations (owner-top associations tm start-revision
276                          &key (document-id *document-id*))
277  "Creates Topic Maps constructs (assocaitions) of the passed
278   named list literals related to the topic owner-top."
279  (declare (d:TopicC owner-top))
280  (map 'list #'(lambda(assoc)
281                 (make-association owner-top assoc tm
282                                   start-revision
283                                   :document-id document-id))
284       associations))
285
286
287(defun make-types (owner-top types tm start-revision
288                   &key (document-id *document-id*))
289  "Creates instance-of associations corresponding to the passed
290   topic owner-top and the passed types."
291  (declare (d:TopicC owner-top))
292  (map 'list
293       #'(lambda(type)
294           (let ((type-topic
295                  (make-topic-stub (getf type :psi)
296                                   nil
297                                   (getf type :topicid)
298                                   nil start-revision tm
299                                   :document-id document-id))
300                 (ID (getf type :ID)))
301             (make-instance-of-association owner-top type-topic
302                                           ID start-revision tm
303                                           :document-id document-id)))
304       types))
305
306
307(defun make-super-classes (owner-top super-classes tm start-revision
308                           &key (document-id *document-id*))
309  "Creates supertype-subtype associations corresponding to the passed
310   topic owner-top and the passed super classes."
311  (declare (d:TopicC owner-top))
312  (map 'list
313       #'(lambda(class)
314           (let ((class-topic
315                  (make-topic-stub (getf class :psi)
316                                   nil
317                                   (getf class :topicid)
318                                   nil start-revision tm
319                                   :document-id document-id))
320                 (ID (getf class :ID)))
321             (make-supertype-subtype-association
322              owner-top class-topic ID start-revision tm
323              :document-id document-id)))
324       super-classes))
325
326
327(defun make-supertype-subtype-association (sub-top super-top reifier-id
328                                           start-revision tm
329                                           &key (document-id *document-id*))
330  "Creates an supertype-subtype association."
331  (declare (TopicC sub-top super-top))
332  (declare (TopicMapC tm))
333  (elephant:ensure-transaction (:txn-nosync t)
334    (let ((assoc-type
335           (make-topic-stub *supertype-subtype-psi* nil nil nil
336                            start-revision tm :document-id document-id))
337          (role-type-1
338           (make-topic-stub *supertype-psi* nil nil nil
339                            start-revision tm :document-id document-id))
340          (role-type-2
341           (make-topic-stub *subtype-psi* nil nil nil
342                            start-revision tm :document-id document-id))
343          (err-pref "From make-supertype-subtype-association(): "))
344      (unless assoc-type
345        (error "~athe association type ~a is missing!"
346               err-pref *supertype-subtype-psi*))
347      (unless (or role-type-1 role-type-2)
348        (error "~aone of the role types ~a ~a is missing!"
349               err-pref *supertype-psi* *subtype-psi*))
350      (let ((a-roles (list (list :instance-of role-type-1
351                                 :player super-top
352                                 :start-revision start-revision)
353                           (list :instance-of role-type-2
354                                 :player sub-top
355                                 :start-revision start-revision))))
356        (let ((assoc
357               (add-to-tm
358                tm
359                (make-construct 'AssociationC
360                                :start-revision start-revision
361                                :instance-of assoc-type
362                                :roles a-roles))))
363          (when reifier-id
364            (make-reification reifier-id assoc start-revision tm
365                              :document-id document-id))
366          (format t "a")
367          assoc)))))
368
369
370(defun make-instance-of-association (instance-top type-top reifier-id
371                                     start-revision tm
372                                     &key (document-id *document-id*))
373  "Creates and returns an instance-of association."
374  (declare (TopicC type-top instance-top))
375  (declare (TopicMapC tm))
376  (elephant:ensure-transaction (:txn-nosync t)
377    (let ((assoc-type
378           (make-topic-stub *type-instance-psi* nil nil nil
379                            start-revision tm :document-id document-id))
380          (roletype-1
381           (make-topic-stub *type-psi* nil nil nil
382                            start-revision tm :document-id document-id))
383          (roletype-2
384           (make-topic-stub *instance-psi* nil nil nil
385                            start-revision tm :document-id document-id))
386          (err-pref "From make-instance-of-association(): "))
387      (unless assoc-type
388        (error "~athe association type ~a is missing!"
389               err-pref *type-instance-psi*))
390      (unless (or roletype-1 roletype-2)
391        (error "~aone of the role types ~a ~a is missing!"
392               err-pref *type-psi* *instance-psi*))
393      (let ((a-roles (list (list :instance-of roletype-1
394                                 :player type-top
395                                 :start-revision start-revision)
396                           (list :instance-of roletype-2
397                                 :player instance-top
398                                 :start-revision start-revision))))
399        (add-to-tm tm assoc-type)
400        (add-to-tm tm roletype-1)
401        (add-to-tm tm roletype-2)
402        (let ((assoc
403               (add-to-tm
404                tm
405                (make-construct 'AssociationC
406                                :start-revision start-revision
407                                :instance-of assoc-type
408                                :roles a-roles))))
409          (when reifier-id
410            (make-reification reifier-id assoc start-revision tm
411                              :document-id document-id))
412          (format t "a")
413          assoc)))))
414
415
416(defun make-topic-stub (about ID nodeId UUID start-revision
417                        tm &key (document-id *document-id*))
418  "Returns a topic corresponding to the passed parameters.
419   When the searched topic does not exist there will be created one.
420   If about or ID is set there will also be created a new PSI."
421  (declare (TopicMapC tm))
422  (let ((topic-id (or about ID nodeID UUID))
423        (psi-uri (or about ID))
424        (ii-uri (unless (or about ID)
425                  (concat *rdf2tm-blank-node-prefix* (or nodeID UUID)))))
426    (let ((top (get-item-by-id topic-id :xtm-id document-id
427                               :revision start-revision)))
428      (if top
429          (progn
430            (d::add-to-version-history top :start-revision start-revision)
431            top)
432          (elephant:ensure-transaction (:txn-nosync t)
433            (let ((psis (when psi-uri
434                          (list
435                           (make-construct 'PersistentIdC
436                                          :uri psi-uri
437                                          :start-revision start-revision))))
438                  (iis (when ii-uri
439                         (list
440                          (make-construct 'ItemIdentifierC
441                                         :uri ii-uri
442                                         :start-revision start-revision))))
443                  (topic-ids (when topic-id
444                               (list
445                                (make-construct 'TopicIdentificationC
446                                                :uri topic-id
447                                                :xtm-id document-id
448                                                :start-revision start-revision)))))
449              (handler-case (let ((top
450                                   (add-to-tm
451                                    tm
452                                    (make-construct 
453                                     'TopicC
454                                     :topic-identifiers topic-ids
455                                     :psis psis
456                                     :item-identifiers iis
457                                     :xtm-id document-id
458                                     :start-revision start-revision))))
459                              (format t "t")
460                              top)
461                (Condition (err)(error "Creating topic ~a failed: ~a"
462                                       topic-id err)))))))))
463
464
465(defun make-lang-topic (lang start-revision tm
466                        &key (document-id *document-id*))
467  "Returns a topic with the topicid tm-id/lang. If no such topic exist
468   there will be created one."
469  (when lang
470    (let ((psi-and-topic-id
471           (concatenate-uri *rdf2tm-scope-prefix* lang)))
472      (make-topic-stub psi-and-topic-id nil nil nil start-revision
473                       tm :document-id document-id))))
474
475
476(defun make-association (top association tm start-revision
477                         &key (document-id *document-id*))
478  "Creates an association depending on the given parameters and
479   returns the elephat-associaton object."
480  (declare (TopicC top))
481  (declare (TopicMapC tm))
482  (let ((type (getf association :type))
483        (player-id (getf association :topicid))
484        (player-psi (getf association :psi))
485        (ID (getf association :ID)))
486    (elephant:ensure-transaction (:txn-nosync t)
487      (let ((player-1 (make-topic-stub player-psi nil player-id nil
488                                       start-revision
489                                       tm :document-id document-id))
490            (role-type-1
491             (make-topic-stub *rdf2tm-object* nil nil nil
492                              start-revision tm :document-id document-id))
493            (role-type-2
494             (make-topic-stub *rdf2tm-subject* nil nil nil
495                              start-revision tm :document-id document-id))
496            (type-top (make-topic-stub type nil nil nil start-revision
497                                       tm :document-id document-id)))
498        (let ((roles (list (list :instance-of role-type-1
499                                 :player player-1
500                                 :start-revision start-revision)
501                           (list :instance-of role-type-2
502                                 :player top
503                                 :start-revision start-revision))))
504          (let ((assoc
505                 (add-to-tm tm (make-construct 'AssociationC
506                                                     :start-revision start-revision
507                                                     :instance-of type-top
508                                                     :roles roles))))
509            (when ID
510              (make-reification ID assoc start-revision tm
511                                :document-id document-id))
512            (format t "a")
513            assoc))))))
514
515
516(defun make-association-with-nodes (subject-topic object-topic
517                                    associationtype-topic tm start-revision
518                                    &key (document-id *document-id*))
519  "Creates an association with two roles that contains the given players."
520  (declare (TopicC subject-topic object-topic associationtype-topic))
521  (declare (TopicMapC tm))
522  (elephant:ensure-transaction (:txn-nosync t)
523    (let ((role-type-1
524           (make-topic-stub *rdf2tm-subject* nil nil nil start-revision
525                            tm :document-id document-id))
526          (role-type-2
527           (make-topic-stub *rdf2tm-object* nil nil nil start-revision
528                            tm :document-id document-id)))
529      (let ((roles (list (list :instance-of role-type-1
530                               :player subject-topic
531                               :start-revision start-revision)
532                         (list :instance-of role-type-2
533                               :player object-topic
534                               :start-revision start-revision))))
535        (let ((assoc
536               (add-to-tm 
537                tm (make-construct 'AssociationC
538                                   :start-revision start-revision
539                                   :instance-of associationtype-topic
540                                   :roles roles))))
541          (format t "a")
542          assoc)))))
543
544
545
546(defun make-reification(reifier-id reifiable-construct start-revision tm &key
547                        (document-id *document-id*))
548  (declare (string reifier-id))
549  (declare (ReifiableConstructC reifiable-construct))
550  (declare (TopicMapC tm))
551  (let ((reifier-topic (make-topic-stub reifier-id nil nil nil start-revision tm
552                                        :document-id document-id)))
553    (add-reifier reifiable-construct reifier-topic :revision start-revision)))
554
555
556(defun make-occurrence (top literal start-revision tm-id 
557                        &key (document-id *document-id*))
558  "Creates an accorrence from the literal list and returns
559   the created elephant-occurrence-object."
560  (declare (TopicC top))
561  (tm-id-p tm-id "make-occurrence")
562  (with-tm (start-revision document-id tm-id)
563    (let ((type (getf literal :type))
564          (value (getf literal :value))
565          (lang (getf literal :lang))
566          (datatype (getf literal :datatype))
567          (ID (getf literal :ID)))
568      (elephant:ensure-transaction (:txn-nosync t)
569        (let ((type-top (make-topic-stub type nil nil nil start-revision
570                                         xtm-importer::tm
571                                         :document-id document-id))
572              (lang-top (make-lang-topic lang start-revision
573                                         xtm-importer::tm
574                                         :document-id document-id)))
575          (let ((occurrence
576                 (make-construct 'OccurrenceC 
577                                 :start-revision start-revision
578                                 :parent top
579                                 :themes (when lang-top
580                                           (list lang-top))
581                                 :instance-of type-top
582                                 :charvalue value
583                                 :datatype datatype)))
584            (when ID
585              (make-reification ID occurrence start-revision xtm-importer::tm
586                                :document-id document-id))
587            occurrence))))))
588           
589
590(defun get-literals-of-node-content (node tm-id parent-xml-base parent-xml-lang)
591  "Returns a list of literals that is produced of a node's content."
592  (declare (dom:element node))
593  (tm-id-p tm-id "get-literals-of-noode-content")
594  (let ((properties (child-nodes-or-text node :trim t))
595        (xml-base (get-xml-base node :old-base parent-xml-base))
596        (xml-lang (get-xml-lang node :old-lang parent-xml-lang)))
597    (let ((literals
598           (when properties
599             (loop for property across properties
600                when (let ((datatype (get-ns-attribute property "datatype"))
601                           (parseType (get-ns-attribute property "parseType"))
602                           (nodeID (get-ns-attribute property "nodeID"))
603                           (resource (get-ns-attribute property "resource"))
604                           (UUID (get-ns-attribute property "UUID"
605                                                   :ns-uri *rdf2tm-ns*))
606                           (type (get-ns-attribute property "type"))
607                           (prop-literals (get-literals-of-property
608                                           property nil))
609                           (prop-content (child-nodes-or-text property)))
610                       (and (or datatype
611                                (and parseType
612                                     (string= parseType "Literal"))
613                                (and (not (or nodeID resource UUID parseType))
614                                     (or (not prop-content)
615                                         (stringp prop-content))))
616                            (not (or prop-literals type))
617                            (string/= parseType "Collection")
618                            (string/= parseType "Resource")))
619                collect (let ((content (child-nodes-or-text property))
620                              (ID (get-absolute-attribute property tm-id
621                                                          xml-base "ID"))
622                              (child-xml-lang
623                               (get-xml-lang property :old-lang xml-lang)))
624                          (let ((full-name (get-type-of-node-name property))
625                                (datatype (get-datatype property tm-id xml-base))
626                                (text
627                                 (cond
628                                   ((= (length content) 0)
629                                    "")
630                                   ((not (stringp content)) ;must be an element
631                                    (let ((text-val ""))
632                                      (when (dom:child-nodes property)
633                                        (loop for content-node across
634                                             (dom:child-nodes property)
635                                           do (push-string
636                                               (node-to-string content-node)
637                                               text-val)))
638                                      text-val))
639                                   (t content))))
640                            (list :type full-name
641                                  :value text
642                                  :ID ID
643                                  :lang child-xml-lang
644                                  :datatype datatype)))))))
645      literals)))
646
647
648(defun get-types-of-node-content (node tm-id parent-xml-base)
649  "Returns a list of type-uris that corresponds to the node's content
650   or attributes."
651  (tm-id-p tm-id "get-types-of-node-content")
652  (let ((xml-base (get-xml-base node :old-base parent-xml-base)))
653    (let ((attr-type
654           (if (get-ns-attribute node "type")
655               (list
656                (list :topicid (absolutize-value (get-ns-attribute node "type")
657                                                 xml-base tm-id)
658                      :psi (absolutize-value (get-ns-attribute node "type")
659                                             xml-base tm-id)
660                      :ID nil))
661               nil))
662          (content-types
663           (when (child-nodes-or-text node :trim t)
664             (loop for child across (child-nodes-or-text node :trim t)
665                when (and (string= (dom:namespace-uri child) *rdf-ns*)
666                          (string= (get-node-name child) "type"))
667                collect (let ((nodeID (get-ns-attribute child "nodeID"))
668                              (resource (get-absolute-attribute
669                                         child tm-id xml-base "resource"))
670                              (UUID (get-ns-attribute child "UUID"
671                                                      :ns-uri *rdf2tm-ns*))
672                              (ID (get-absolute-attribute child tm-id
673                                                          xml-base "ID")))
674                          (if (or nodeID resource UUID)
675                              (list :topicid (or nodeID resource UUID)
676                                    :psi resource
677                                    :ID ID)
678                              (let ((child-xml-base
679                                     (get-xml-base child :old-base xml-base)))
680                                (let ((refs
681                                       (get-node-refs
682                                        (child-nodes-or-text child :trim t)
683                                        tm-id child-xml-base)))
684                                  (list :topicid (getf (first refs) :topicid)
685                                        :psi (getf (first refs) :psi)
686                                        :ID ID)))))))))
687      (remove-if #'null (append attr-type content-types)))))
688
689
690(defun get-literals-of-property (property parent-xml-lang)
691  "Returns a list of attributes that are treated as literal nodes."
692  (let ((xml-lang (get-xml-lang property :old-lang parent-xml-lang))
693        (attributes nil))
694    (dom:map-node-map
695     #'(lambda(attr)
696         (let ((attr-ns (dom:namespace-uri attr))
697               (attr-name (get-node-name attr)))
698           (let ((l-type (get-type-of-node-name attr))
699                 (l-value (if (get-ns-attribute property attr-name
700                                                :ns-uri attr-ns)
701                              (get-ns-attribute property attr-name
702                                                :ns-uri attr-ns)
703                              "")))
704             (cond
705               ((string= attr-ns *rdf-ns*)
706                (unless (or (string= attr-name "ID")
707                            (string= attr-name "resource")
708                            (string= attr-name "nodeID")
709                            (string= attr-name "type")
710                            (string= attr-name "parseType")
711                            (string= attr-name "datatype"))
712                  (push (list :type l-type
713                              :value l-value
714                              :ID  nil
715                              :lang xml-lang
716                              :datatype *xml-string*)
717                        attributes)))
718               ((or (string= attr-ns *xml-ns*)
719                    (string= attr-ns *xmlns-ns*))
720                nil);;do nothing, all xml-attributes are no literals
721               (t
722                (unless (and (string= attr-ns *rdf2tm-ns*)
723                             (string= attr-name "UUID"))
724                  (push (list :type l-type
725                              :value l-value
726                              :ID nil
727                              :lang xml-lang
728                              :datatype *xml-string*)
729                        attributes)))))))
730     (dom:attributes property))
731    attributes))
732
733
734(defun get-literals-of-node (node parent-xml-lang)
735  "Returns alist of attributes that are treated as literal nodes."
736  (let ((xml-lang (get-xml-lang node :old-lang parent-xml-lang))
737        (attributes nil))
738    (dom:map-node-map
739     #'(lambda(attr)
740         (let ((attr-ns (dom:namespace-uri attr))
741               (attr-name (get-node-name attr)))
742           (let ((l-type (get-type-of-node-name attr))
743                 (l-value (if (get-ns-attribute node attr-name :ns-uri attr-ns)
744                              (get-ns-attribute node attr-name :ns-uri attr-ns)
745                              "")))
746             (cond
747               ((string= attr-ns *rdf-ns*)
748                (unless (or (string= attr-name "ID")
749                            (string= attr-name "about")
750                            (string= attr-name "nodeID")
751                            (string= attr-name "type"))
752                  (push (list :type l-type
753                              :value l-value
754                              :ID nil
755                              :lang xml-lang
756                              :datatype *xml-string*)
757                        attributes)))
758               ((or (string= attr-ns *xml-ns*)
759                    (string= attr-ns *xmlns-ns*))
760                nil);;do nothing, all xml-attributes are no literals
761               (t
762                (unless (and (string= attr-ns *rdf2tm-ns*)
763                             (string= attr-name "UUID"))
764                  (push (list :type l-type
765                              :value l-value
766                              :ID nil
767                              :lang xml-lang
768                              :datatype *xml-string*)
769                        attributes)))))))
770     (dom:attributes node))
771    attributes))
772
773
774(defun get-super-classes-of-node-content (node tm-id parent-xml-base)
775  "Returns a list of super-classes and IDs."
776  (declare (dom:element node))
777  (tm-id-p tm-id "get-super-classes-of-node-content")
778  (let ((content (child-nodes-or-text node :trim t))
779        (xml-base (get-xml-base node :old-base parent-xml-base)))
780    (when content
781      (loop for property across content
782         when (let ((prop-name (get-node-name property))
783                    (prop-ns (dom:namespace-uri property)))
784                (and (string= prop-name "subClassOf")
785                     (string= prop-ns *rdfs-ns*)))
786         collect (let ((prop-xml-base (get-xml-base property
787                                                    :old-base xml-base)))
788                   (let ((ID (get-absolute-attribute property tm-id
789                                                     xml-base "ID"))
790                         (nodeID (get-ns-attribute property "nodeID"))
791                         (resource
792                          (get-absolute-attribute property tm-id
793                                                  xml-base "resource"))
794                         (UUID (get-ns-attribute property "UUID"
795                                                 :ns-uri *rdf2tm-ns*)))
796                     (if (or nodeID resource UUID)
797                         (list :topicid (or nodeID resource UUID)
798                               :psi resource
799                               :ID ID)
800                         (let ((refs (get-node-refs
801                                      (child-nodes-or-text property :trim t)
802                                      tm-id prop-xml-base)))
803                           (list :topicid (getf (first refs) :topicid)
804                                 :psi (getf (first refs) :psi)
805                                 :ID ID)))))))))
806
807
808(defun get-associations-of-node-content (node tm-id parent-xml-base)
809  "Returns a list of associations with a type, value and ID member."
810  (declare (dom:element node))
811  (let ((properties (child-nodes-or-text node :trim t))
812        (xml-base (get-xml-base node :old-base parent-xml-base)))
813    (loop for property across properties
814       when (let ((prop-name (get-node-name property))
815                  (prop-ns (dom:namespace-uri property))
816                  (prop-content (child-nodes-or-text property))
817                  (resource (get-absolute-attribute property tm-id
818                                                    xml-base "resource"))
819                  (nodeID (get-ns-attribute property "nodeID"))
820                  (type (get-ns-attribute property "type"))
821                  (parseType (get-ns-attribute property "parseType"))
822                  (UUID (get-ns-attribute property "UUID"
823                                          :ns-uri *rdf2tm-ns*)))
824              (and (or resource nodeID type UUID
825                       (and parseType
826                            (or (string= parseType "Collection")
827                                (string= parseType "Resource")))
828                       (and (> (length prop-content) 0)
829                            (not (stringp prop-content)))
830                       (> (length (get-literals-of-property property nil)) 0))
831                   (not (and (string= prop-name "type")
832                             (string= prop-ns *rdf-ns*)))
833                   (not (and (string= prop-name "subClassOf")
834                             (string= prop-ns *rdfs-ns*)))))
835       collect (let ((prop-xml-base (get-xml-base property
836                                                  :old-base xml-base))
837                     (content (child-nodes-or-text property :trim t))
838                     (parseType (get-ns-attribute property "parseType")))
839                 (let ((resource
840                        (if (and (string= parseType "Collection")
841                                 (= (length content) 0))
842                            *rdf-nil*
843                            (get-absolute-attribute property tm-id
844                                                    xml-base "resource")))
845                       (nodeID (get-ns-attribute property "nodeID"))
846                       (UUID (get-ns-attribute property "UUID"
847                                               :ns-uri *rdf2tm-ns*))
848                       (ID (get-absolute-attribute property tm-id
849                                                   xml-base "ID"))
850                       (full-name (get-type-of-node-name property)))
851                   (if (or nodeID resource UUID)
852                       (list :type full-name
853                             :topicid (or resource nodeID UUID)
854                             :psi resource
855                             :ID ID)
856                       (let ((refs (get-node-refs
857                                    (child-nodes-or-text property :trim t)
858                                    tm-id prop-xml-base)))
859                         (list :type full-name
860                               :topicid (getf (first refs) :topicid)
861                               :psi (getf (first refs) :psi)
862                               :ID ID))))))))
863
864
865(defun make-recursion-from-node (node tm-id start-revision
866                                 &key (document-id *document-id*)
867                                 (parent-xml-base nil) (parent-xml-lang nil))
868  "Calls the next function that handles all DOM child elements
869   of the passed element as arcs."
870  (declare (dom:element node))
871  (let ((content (child-nodes-or-text node :trim t))
872        (err-pref "From make-recursion-from-node(): ")
873        (xml-base (get-xml-base node :old-base parent-xml-base))
874        (xml-lang (get-xml-lang node :old-lang parent-xml-lang)))
875    (when (stringp content)
876      (error "~aliteral content not allowed here: ~a"
877             err-pref content))
878    (loop for arc across content
879       collect (import-arc arc tm-id start-revision :document-id document-id
880                           :parent-xml-base xml-base
881                           :parent-xml-lang xml-lang))))
882
883
884(defun make-recursion-from-arc (arc tm-id start-revision
885                                &key (document-id *document-id*)
886                                (parent-xml-base nil) (parent-xml-lang nil))
887  "Calls the next function that handles the arcs content nodes/arcs."
888  (declare (dom:element arc))
889  (let ((xml-base (get-xml-base arc :old-base parent-xml-base))
890        (xml-lang (get-xml-lang arc :old-lang parent-xml-lang))
891        (content (child-nodes-or-text arc))
892        (parseType (get-ns-attribute arc "parseType")))
893    (let ((datatype (get-absolute-attribute arc tm-id
894                                            parent-xml-base "datatype"))
895          (type (get-absolute-attribute arc tm-id parent-xml-base "type"))
896          (resource (get-absolute-attribute arc tm-id
897                                            parent-xml-base "resource"))
898          (nodeID (get-ns-attribute arc "nodeID"))
899          (literals (get-literals-of-property arc parent-xml-lang)))
900      (if (and parseType
901               (string= parseType "Collection"))
902          (make-collection arc tm-id start-revision
903                           :document-id document-id
904                           :parent-xml-base parent-xml-base
905                           :parent-xml-lang parent-xml-lang)
906          (if (or datatype resource nodeID
907                  (and parseType
908                       (string= parseType "Literal"))
909                  (and content
910                       (stringp content)))
911              nil;; do nothing current elem is a literal node that has been
912                 ;; already imported as an occurrence
913              (if (or type literals
914                      (and parseType
915                           (string= parseType "Resource")))
916                  (loop for item across content
917                     collect (import-arc item tm-id start-revision
918                                         :document-id document-id
919                                         :parent-xml-base xml-base
920                                         :parent-xml-lang xml-lang))
921                  (loop for item across content
922                     collect (import-node item tm-id start-revision
923                                          :document-id document-id
924                                          :parent-xml-base xml-base
925                                          :parent-xml-lang xml-lang))))))))
Note: See TracBrowser for help on using the repository browser.