source: trunk/src/json/isidorus-json/json_importer.lisp

Last change on this file was 720, checked in by lgiessmann, 13 years ago

trunk: rest-interface: fixed a potential bug => if a foreign association is contained in a fragment, i.e. an association that is not bound to the actual main topic of the passed fragment, the corresponding fragments of all players of the foreign associations are updated

File size: 24.5 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
10(defpackage :json-importer
11  (:use :cl :json :datamodel :xtm-importer :constants)
12  (:export :import-from-isidorus-json
13           :*json-xtm*))
14
15(in-package :json-importer)
16
17;; the json schema for our datamodel is in "docs/xtm_json.txt"
18
19
20(defvar *json-xtm* "json-xtm"); Represents the currently active TM of the JSON-Importer
21
22
23(defun import-from-isidorus-json(json-string &key (xtm-id *json-xtm*))
24  "creates all objects (topics, topic stubs, associations)
25   of the passed json-decoded-list (=fragment)"
26  (declare (type (or string null) json-string xtm-id))
27  (when json-string
28    (let ((fragment-values
29           (get-fragment-values-from-json-list
30            (json:decode-json-from-string json-string))))
31      (let ((topic-values (getf fragment-values :topic))
32            (topicStubs-values (getf fragment-values :topicStubs))
33            (associations-values (getf fragment-values :associations))
34            (rev (get-revision)) ; creates a new revision, equal for all elements of the passed fragment
35            (tm-ids (getf fragment-values :tm-ids)))
36        (unless tm-ids
37          (error "From import-from-isidorus-json(): tm-ids must be set"))
38        (let ((psi-of-topic
39               (let ((psi-uris (getf topic-values :subjectIdentifiers)))
40                 (when psi-uris
41                   (first psi-uris))))
42              (committed-associations nil))
43          (elephant:ensure-transaction (:txn-nosync nil) 
44            (xtm-importer:with-tm (rev xtm-id (first tm-ids))
45              (loop for topicStub-values in
46                   (append topicStubs-values (list topic-values))
47                 do (json-to-stub topicStub-values rev :tm xtm-importer::tm
48                                  :xtm-id xtm-id))
49              (json-merge-topic topic-values rev :tm xtm-importer::tm :xtm-id xtm-id)
50              (loop for association-values in associations-values
51                 do (push (json-to-association association-values rev
52                                               :tm xtm-importer::tm)
53                          committed-associations))))
54          (when psi-of-topic
55            (let* ((frag (create-latest-fragment-of-topic psi-of-topic))
56                   (foreign-assocs
57                    (nset-difference
58                     committed-associations
59                     (map 'list (lambda(role)
60                                  (parent role :revision rev))
61                          (player-in-roles (topic frag) :revision rev)))))
62              (list :fragment frag
63                    :foreign-associations foreign-assocs))))))))
64                 
65
66
67(defun json-to-association (json-decoded-list start-revision
68                            &key tm)
69  "creates an association element of the passed json-decoded-list"
70  (elephant:ensure-transaction (:txn-nosync t) 
71    (let 
72        ((item-identifiers 
73          (map 'list #'(lambda(uri)
74                         (make-identifier 'ItemIdentifierC uri start-revision))
75               (getf json-decoded-list :itemIdentities)))
76         (instance-of
77          (psis-to-topic (getf json-decoded-list :type) :revision start-revision))
78         (themes
79          (json-to-scope (getf json-decoded-list :scopes) start-revision))
80         (roles 
81          (map 'list #'(lambda(role-values)
82                         (json-to-role role-values start-revision))
83               (getf json-decoded-list :roles))))
84      (declare (list json-decoded-list))
85      (declare (integer start-revision))
86      (declare (TopicMapC tm))
87      (setf roles (xtm-importer::set-standard-role-types roles start-revision))
88      (add-to-tm tm 
89                 (make-construct 'AssociationC
90                                 :start-revision start-revision
91                                 :item-identifiers item-identifiers
92                                 :instance-of instance-of
93                                 :themes themes
94                                 :roles roles)))))
95   
96
97(defun json-to-role (json-decoded-list start-revision)
98  "creates a role element"
99  (when json-decoded-list
100  (elephant:ensure-transaction (:txn-nosync t) 
101    (let
102        ((item-identifiers
103          (map 'list #'(lambda(uri)
104                         (make-identifier 'ItemIdentifierC uri start-revision))
105               (getf json-decoded-list :itemIdentities)))
106         (instance-of
107          (psis-to-topic (getf json-decoded-list :type) :revision start-revision))
108         (player
109          (psis-to-topic (getf json-decoded-list :topicRef)
110                         :revision start-revision)))
111      (declare (list json-decoded-list))
112      (declare (integer start-revision))
113      (unless player
114        (error "Role in association with topicref ~a not complete"
115               (getf json-decoded-list :topicRef)))
116      (list :instance-of instance-of
117            :player player
118            :item-identifiers item-identifiers
119            :start-revision start-revision)))))
120
121
122(defun json-merge-topic (json-decoded-list start-revision
123                         &key tm (xtm-id *json-xtm*))
124  "merges the a topic by setting the name, occurrence and instanceOf
125   elements from the json-decoded-list"
126  (when json-decoded-list
127    (elephant:ensure-transaction (:txn-nosync t) 
128      (let ((top
129             (d:get-item-by-id
130              (getf json-decoded-list :id)
131              :revision start-revision
132              :xtm-id xtm-id)))
133        (declare (list json-decoded-list))
134        (declare (integer start-revision))
135        (declare (TopicMapC tm))
136        (unless top
137          (error "topic ~a could not be found" (getf json-decoded-list :id)))
138        (let ((instanceof-topics
139               (remove-duplicates
140                (map 'list
141                     #'(lambda(psis)
142                         (psis-to-topic psis :revision start-revision))
143                     (getf json-decoded-list :instanceOfs)))))
144
145          (loop for name-values in (getf json-decoded-list :names)
146             do (json-to-name name-values top start-revision))
147          (loop for occurrence-values in (getf json-decoded-list :occurrences)
148             do (json-to-occurrence occurrence-values top start-revision))
149          (dolist (instanceOf-top instanceof-topics)
150            (json-create-instanceOf-association instanceOf-top top start-revision
151                                                :tm tm))
152          top)))))
153
154
155(defun json-to-stub(json-decoded-list start-revision &key tm (xtm-id *json-xtm*))
156  "creates a topic stub from the passed json-decoded list"
157  (when json-decoded-list
158    (elephant:ensure-transaction (:txn-nosync t) 
159      (let ((item-identifiers
160             (map 'list #'(lambda(uri)
161                            (make-identifier 'ItemIdentifierC uri start-revision))
162                  (getf json-decoded-list :itemIdentities)))
163            (subject-identifiers
164             (map 'list #'(lambda(uri)
165                            (make-identifier 'PersistentIdC uri start-revision))
166                  (getf json-decoded-list :subjectIdentifiers)))
167            (subject-locators
168             (map 'list #'(lambda(uri)
169                            (make-identifier 'SubjectLocatorC uri start-revision))
170                  (getf json-decoded-list :subjectLocators)))
171            (topic-ids
172             (when (getf json-decoded-list :id)
173               (list
174                (make-construct 'TopicIdentificationC
175                                :uri (getf json-decoded-list :id)
176                                :xtm-id xtm-id)))))
177        ;; all topic stubs has to be added top a topicmap object in this method
178        ;; becuase the only one topic that is handled in "json-merge-topic"
179        ;; is the main topic of the fragment
180        (let ((top
181               (make-construct 'TopicC :start-revision start-revision
182                                       :item-identifiers item-identifiers
183                                       :locators subject-locators
184                                       :psis subject-identifiers
185                                       :topic-identifiers topic-ids)))
186          (add-to-tm tm top)
187          top)))))
188       
189
190(defun json-to-occurrence (json-decoded-list top start-revision)
191  "Creates an occurrence element"
192  (when json-decoded-list
193    (let
194      ((themes
195        (json-to-scope (getf json-decoded-list :scopes) start-revision))
196       (item-identifiers
197        (map 'list #'(lambda(uri)
198                       (make-identifier 'ItemIdentifierC uri start-revision))
199             (getf json-decoded-list :itemIdentities)))
200       (instance-of 
201        (psis-to-topic (getf json-decoded-list :type) :revision start-revision))
202       (occurrence-value
203        (json-to-resourceX json-decoded-list)))
204     
205      (unless occurrence-value
206        (error "OccurrenceC: one of resourceRef and resourceData must be set"))
207      (make-construct 'OccurrenceC 
208                      :start-revision start-revision
209                      :parent top
210                      :themes themes
211                      :item-identifiers item-identifiers
212                      :instance-of instance-of
213                      :charvalue (getf occurrence-value :data)
214                      :datatype (getf occurrence-value :type)))))
215
216
217(defun make-identifier (classsymbol uri start-revision)
218  "creates an instance of a PersistentIdc, SubjectlocatorC or
219   ItemIdentifierC"
220  (declare (symbol classsymbol))
221  (declare (string uri))
222  (declare (integer start-revision))
223  (make-construct classsymbol
224                  :uri uri
225                  :start-revision start-revision))
226
227
228(defun json-to-scope (json-decoded-list start-revision)
229  "Generate set of themes (= topics) from this scope element and
230   return that set. If the input is nil, the list of themes is empty"
231  (when json-decoded-list
232    (let ((tops
233           (map 'list #'(lambda(psis)
234                          (psis-to-topic psis :revision start-revision))
235                json-decoded-list)))
236      (declare (list json-decoded-list))
237      (unless (>= (length tops) 1)
238        (error "need at least one topic in a scope"))
239      tops)))
240
241
242(defun psis-to-topic(psis &key (revision *TM-REVISION*))
243  "searches for a topic of the passed psis-list describing
244   exactly one topic"
245  (declare (list psis)
246           (type (or integer null) revision))
247  (when psis
248    (let ((top
249           (let ((psi
250                  (loop for uri in psis
251                     when (elephant:get-instance-by-value
252                           'd:PersistentIdC 'd:uri uri)
253                     return (elephant:get-instance-by-value
254                             'd:PersistentIdC 'd:uri uri))))
255             (when psi
256               (d:identified-construct psi :revision revision)))))
257      (unless top
258        (error (make-condition 'missing-reference-error
259                               :message (format nil "psis-to-topic: could not resolve reference ~a" psis))))
260      top)))
261
262
263(defun json-to-name (json-decoded-list top start-revision)
264  "creates a name element (NameC) of the passed json-decoded-list"
265  (when json-decoded-list
266    (let ((item-identifiers
267           (map 'list #'(lambda(uri)
268                          (make-identifier 'ItemIdentifierC uri start-revision))
269                (getf json-decoded-list :itemIdentities)))
270          (namevalue (getf json-decoded-list :value))
271          (themes
272           (json-to-scope (getf json-decoded-list :scopes) start-revision))
273          (instance-of
274           (psis-to-topic (getf json-decoded-list :type) :revision start-revision)))
275      (unless namevalue
276        (error "A name must have exactly one namevalue"))
277      (let ((name (make-construct
278                   'NameC 
279                   :start-revision start-revision
280                   :parent top
281                   :charvalue namevalue
282                   :instance-of (if instance-of
283                                    instance-of
284                                    (get-item-by-psi *topic-name-psi*
285                                                     :revision start-revision
286                                                     :error-if-nil t))
287                   :item-identifiers item-identifiers
288                   :themes themes)))
289        (loop for variant in (getf json-decoded-list :variants)
290           do (json-to-variant variant name start-revision))
291        name))))
292
293
294(defun json-to-variant(json-decoded-list name start-revision)
295  "creates a variant element (VariantC) of the passed json-decoded-list"
296  (when json-decoded-list
297    (let ((item-identifiers
298           (map 'list #'(lambda(uri)
299                          (make-identifier 'ItemIdentifierC uri start-revision))
300                (getf json-decoded-list :itemIdentities)))
301          (themes
302           (remove-duplicates
303            (append (d:themes name :revision start-revision)
304                    (json-to-scope (getf json-decoded-list :scopes)
305                                   start-revision))))
306          (variant-value
307           (json-to-resourceX json-decoded-list)))
308      (declare (list json-decoded-list))
309      (make-construct 'VariantC
310                      :start-revision start-revision
311                      :item-identifiers item-identifiers
312                      :themes themes
313                      :charvalue (getf variant-value :data)
314                      :datatype (getf variant-value :type)
315                      :parent name))))
316
317
318(defun json-to-resourceX(json-decoded-list)
319  "creates a resourceRef or resourceData element"
320  (when json-decoded-list
321    (let ((resourceRef
322           (getf json-decoded-list :resourceRef))
323          (resourceData
324           (getf json-decoded-list :resourceData)))
325      (declare (list json-decoded-list))
326      (let ((value
327             (if resourceRef
328                 (list :data resourceRef
329                       :type "http://www.w3.org/2001/XMLSchema#anyURI")
330                 (list :data (getf resourceData :value)
331                       :type (if (getf resourceData :datatype)
332                                 (getf resourceData :datatype)
333                                 "http://www.w3.org/2001/XMLSchema#string")))))
334        (unless (getf value :data)
335          (error "json-to-resourceX: one of resourceRef or resourceData must be set"))
336        value))))
337
338
339(defun json-create-instanceOf-association (supertype player2-obj start-revision 
340                                      &key tm)
341  "handle the instanceOf element. The instanceOf element is different
342  from all the others in that it is not modelled one to one, but
343  following the suggestion of the XTM 2.0 spec (4.9) and the
344  TMDM (7.2) as an association"
345  (declare (TopicC supertype player2-obj)
346           (TopicMapC tm))
347  (let
348      ((associationtype 
349        (get-item-by-psi constants:*type-instance-psi* :revision start-revision))
350       (roletype1
351        (get-item-by-psi constants:*type-psi* :revision start-revision))
352       (roletype2
353        (get-item-by-psi constants:*instance-psi* :revision start-revision))
354       (player1 supertype))
355    (unless (and associationtype roletype1 roletype2)
356      (error "Error in the creation of an instanceof association: core topics are missing"))
357    (add-to-tm tm associationtype)
358    (add-to-tm tm roletype1)
359    (add-to-tm tm roletype2)
360    (add-to-tm 
361     tm
362     (make-construct 
363      'AssociationC
364      :item-identifiers nil
365      :themes nil
366      :start-revision start-revision
367      :instance-of associationtype
368      :roles (list (list :instance-of roletype1
369                         :player player1
370                         :start-revision start-revision)
371                   (list :instance-of roletype2
372                         :player player2-obj
373                         :start-revision start-revision))))))
374
375
376(defun get-fragment-values-from-json-list(json-decoded-list)
377  "returns all fragment values of the passed json-decoded-list
378   as a named list"
379  (when json-decoded-list
380    (let ((topic nil)
381          (topicStubs nil)
382          (associations nil)
383          (tm-ids nil))
384      (declare (list json-decoded-list))
385      (loop for j-elem in json-decoded-list
386         do (cond
387              ((string= (car j-elem) :topic)
388               (setf topic (cdr j-elem)))
389              ((string= (car j-elem) :topic-Stubs)
390               (setf topicStubs (cdr j-elem)))
391              ((string= (car j-elem) :associations)
392               (setf associations (cdr j-elem)))
393              ((string= (car j-elem) :tm-Ids)
394               (setf tm-ids (cdr j-elem)))
395              (t
396               (error "json-importer:get-fragment-values-from-json-string:
397                       bad item-specifier found in json-list"))))
398      (unless topic
399        (error "json-importer:get-fragment-values-from-json-string: the element topic must be set"))
400      (unless (= (length tm-ids) 1)
401        (error "There must be given exactly one tm-id in the tm-ids list"))
402      (let ((topic-list (get-topic-values-from-json-list topic))
403            (topicStubs-list (map 'list #'get-topicStub-values-from-json-list topicStubs))
404            (associations-list (map 'list #'get-association-values-from-json-list associations)))
405        (list :topic topic-list
406              :topicStubs topicStubs-list
407              :associations associations-list
408              :tm-ids tm-ids)))))
409
410
411(defun get-topicStub-values-from-json-list (json-decoded-list)
412  "returns all topicStub values of the passed json-decoded-list
413   as a named list"
414  (when json-decoded-list
415    (let ((id nil)
416          (itemIdentities nil)
417          (subjectLocators nil)
418          (subjectIdentifiers nil))
419      (declare (list json-decoded-list))
420      (loop for j-elem in json-decoded-list
421         do (cond
422              ((string= (car j-elem) :ID)
423               (setf id (cdr j-elem)))
424              ((string= (car j-elem) :item-Identities)
425               (setf itemIdentities (cdr j-elem)))
426              ((string= (car j-elem) :subject-Locators)
427               (setf subjectLocators (cdr j-elem)))
428              ((string= (car j-elem) :subject-Identifiers)
429               (setf subjectIdentifiers (cdr j-elem)))
430              (t
431               (error "json-importer:get-topicStub-values-from-json-string:
432                       bad item-specifier found in json-list"))))
433       (unless subjectIdentifiers
434        (error "json-importer:get-topicStub-values-from-json-string: the element subjectIdentifiers mus be set!"))
435      (unless id
436        (error "json-importer:get-topic-valuesStub-from-json-string: the element id must be set"))
437      (list :id id
438            :itemIdentities itemIdentities
439            :subjectLocators subjectLocators
440            :subjectIdentifiers subjectIdentifiers))))
441     
442
443(defun get-topic-values-from-json-list (json-decoded-list)
444  "extracts all values of the passed json-list and
445   returns them as a named list"
446  (when json-decoded-list
447    (let ((id nil)
448          (itemIdentities nil)
449          (subjectLocators nil)
450          (subjectIdentifiers nil)
451          (instanceOfs nil)
452          (names nil)
453          (occurrences nil))
454      (declare (list json-decoded-list))
455      (loop for j-elem in json-decoded-list
456         do (cond
457              ((string= (car j-elem) :ID)
458               (setf id (cdr j-elem)))
459              ((string= (car j-elem) :item-Identities) ;json-decoder transforms camelcase to '-' from
460               (setf itemIdentities (cdr j-elem)))
461              ((string= (car j-elem) :subject-Locators)
462               (setf subjectLocators (cdr j-elem)))
463              ((string= (car j-elem) :subject-Identifiers)
464               (setf subjectIdentifiers (cdr j-elem)))
465              ((string= (car j-elem) :instance-Ofs)
466               (setf instanceOfs (cdr j-elem)))
467              ((string= (car j-elem) :names)
468               (setf names (cdr j-elem)))
469              ((string= (car j-elem) :occurrences)
470               (setf occurrences (cdr j-elem)))
471              (t
472               (error "json-importer:get-topic-values-from-json-string:
473                       bad item-specifier found in json-list ~a" (car j-elem)))))
474      (unless subjectIdentifiers
475        (error "json-importer:get-topic-values-from-json-string: the element subjectIdentifiers must be set!"))
476      (unless id
477        (error "json-importer:get-topic-values-from-json-string: the element id must be set"))
478      (let ((names-list (map 'list #'get-name-values-from-json-list names))
479            (occurrences-list (map 'list #'get-occurrence-values-from-json-list occurrences)))
480        (list :id id
481              :itemIdentities itemIdentities
482              :subjectLocators subjectLocators
483              :subjectIdentifiers subjectIdentifiers
484              :instanceOfs instanceOfs
485              :names names-list
486              :occurrences occurrences-list)))))
487
488
489(defun get-name-values-from-json-list (json-decoded-list)
490  "returns all element values of a name element as
491   a named list"
492  (when json-decoded-list
493    (let ((itemIdentities nil)
494          (type nil)
495          (scopes nil)
496          (value nil)
497          (variants nil))
498      (declare (list json-decoded-list))
499      (loop for j-elem in json-decoded-list
500         do (cond
501              ((string= (car j-elem) :item-Identities)
502               (setf itemIdentities (cdr j-elem)))
503              ((string= (car j-elem) :type)
504               (setf type (cdr j-elem)))
505              ((string= (car j-elem) :scopes)
506               (setf scopes (cdr j-elem)))
507              ((string= (car j-elem) :value)
508               (setf value (cdr j-elem)))
509              ((string= (car j-elem) :variants)
510               (setf variants (cdr j-elem)))
511              (t
512               (error "json-importer:get-name-values-from-json-list:
513                       bad item-specifier found in json-list"))))
514      (unless value
515        (error "json-importer:get-name-values-from-json-list: value must be set"))
516      (let ((variants-list (map 'list #'get-variant-values-from-json-list variants)))
517        (list :itemIdentities itemIdentities
518              :type type
519              :scopes scopes
520              :value value
521              :variants variants-list)))))
522           
523
524(defun get-variant-values-from-json-list (json-decoded-list)
525  "returns all element values of a variant element as
526   a named list"
527  (when json-decoded-list
528    (let ((itemIdentities nil)
529          (scopes nil)
530          (resourceRef nil)
531          (resourceData nil))
532      (declare (list json-decoded-list))
533      (loop for j-elem in json-decoded-list
534         do (cond
535              ((string= (car j-elem) :item-Identities)
536               (setf itemIdentities (cdr j-elem)))
537              ((string= (car j-elem) :scopes)
538               (setf scopes (cdr j-elem)))
539              ((string= (car j-elem) :resource-Ref)
540               (setf resourceRef (cdr j-elem)))
541              ((string= (car j-elem) :resource-Data)
542               (setf resourceData (cdr j-elem)))
543              (t
544               (error "json-importer:get-variant-values-from-json-list:
545                       bad item-specifier found in json-list"))))
546      (when (or (and (not resourceRef)
547                     (not resourceData))
548                (and resourceRef resourceData))
549        (error "json-importer:get-variant-values-from-json-list: ONE of the elements
550                  resourceRef or resourceData must be set"))
551      (let ((resourceData-list (get-resourceData-values-from-json-list resourceData)))
552        (list :itemIdentities itemIdentities 
553              :scopes scopes
554              :resourceRef resourceRef
555              :resourceData resourceData-list)))))
556 
557
558(defun get-resourceData-values-from-json-list (json-decoded-list)
559  "returns the resourceData value and the datatype value, if there
560   is no datatype given, there will be set the standard type string"
561  (when json-decoded-list
562    (let ((value nil)
563          (datatype nil))
564      (declare (list json-decoded-list))
565      (loop for j-elem in json-decoded-list
566         do (cond
567              ((string= (car j-elem) :value)
568               (setf value (cdr j-elem)))
569              ((string= (car j-elem) :datatype)
570               (setf datatype (cdr j-elem)))
571              (t
572               (error "json-importer:get-resourceData-values-from-json-list:
573                       bad item-specifier found in json-list"))))
574      (unless value
575        (error "json-importer:get-resourceData-values-from-json-list: resourceData must have a value"))
576      (list :value value
577            :datatype (if datatype datatype "http://www.w3.org/2001/XMLSchema#string")))))
578
579
580(defun get-occurrence-values-from-json-list (json-decoded-list)
581  "returns all occurrence values of the passed json-list as
582   a named list"
583  (when json-decoded-list
584    (let ((itemIdentities nil)
585          (type nil)
586          (scopes nil)
587          (resourceRef nil)
588          (resourceData nil))
589      (declare (list json-decoded-list))
590      (loop for j-elem in json-decoded-list
591         do (cond
592              ((string= (car j-elem) :item-Identities)
593               (setf itemIdentities (cdr j-elem)))
594              ((string= (car j-elem) :type)
595               (setf type (cdr j-elem)))
596              ((string= (car j-elem) :scopes)
597               (setf scopes (cdr j-elem)))
598              ((string= (car j-elem) :resource-Ref)
599               (setf resourceRef (cdr j-elem)))
600              ((string= (car j-elem) :resource-Data)
601               (setf resourceData (cdr j-elem)))
602              (t
603               (error "json-importer:get-occurrence-values-from-json-list:
604                       bad item-specifier found in json-list"))))
605      (when (or (and (not resourceRef)
606                     (not resourceData))
607                (and resourceRef resourceData))
608        (error "json-importer:get-occurrence-values-from-json-list: ONE of the elements
609                  resourceRef or resourceData must be set"))
610      (unless type
611        (error "json-importer:get-occurrence-values-from-json-list: type must be set"))
612      (let ((resourceData-list (get-resourceData-values-from-json-list resourceData)))
613        (list :itemIdentities itemIdentities
614              :type type
615              :scopes scopes
616              :resourceRef resourceRef
617              :resourceData resourceData-list)))))
618
619
620(defun get-association-values-from-json-list (json-decoded-list)
621  "extracts all values of the passed json-list and
622   returns them as a named list"
623  (when json-decoded-list
624    (let ((itemIdentities nil)
625          (type nil)
626          (scopes nil)
627          (roles nil))
628      (declare (list json-decoded-list))
629      (loop for j-elem in json-decoded-list
630         do (cond
631              ((string= (car j-elem) :item-Identities)
632               (setf itemIdentities (cdr j-elem)))
633              ((string= (car j-elem) :type)
634               (setf type (cdr j-elem)))
635              ((string= (car j-elem) :scopes)
636               (setf scopes (cdr j-elem)))
637              ((string= (car j-elem) :roles)
638               (setf roles (cdr j-elem)))
639              (t
640               (error "json-importer:get-association-values-from-json-list:
641                       bad item-specifier found in json-list"))))
642      (unless (and type roles)
643        (error "json-importer:get-occurrence-values-from-json-list: type and role must be set"))
644      (let ((roles-list (map 'list #'get-role-values-from-json-list roles)))
645        (list :itemIdentities itemIdentities
646              :type type
647              :scopes scopes
648              :roles roles-list)))))
649 
650
651(defun get-role-values-from-json-list (json-decoded-list)
652  "extracts all values of the passed json-list and
653   returns them as a named list"
654  (when json-decoded-list
655    (let ((itemIdentities nil)
656          (type nil)
657          (topicRef nil))
658      (declare (list json-decoded-list))
659      (loop for j-elem in json-decoded-list
660         do (cond
661              ((string= (car j-elem) :item-Identities)
662               (setf itemIdentities (cdr j-elem)))
663              ((string= (car j-elem) :type)
664               (setf type (cdr j-elem)))
665              ((string= (car j-elem) :topic-Ref)
666               (setf topicRef (cdr j-elem)))
667              (t
668               (error "json-importer:get-role-values-from-json-list:
669                       bad item-specifier found in json-list"))))
670      (unless (and type topicRef)
671        (error "json-importer:get-occurrence-values-from-json-list: type and topicRef must be set"))
672      (list :itemIdentities itemIdentities
673            :type type
674            :topicRef topicRef))))
675
676
Note: See TracBrowser for help on using the repository browser.