RdfTransformer.kt 21 KB
Newer Older
Jonas Waeber's avatar
Jonas Waeber committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * Drupal Sync Service
 * Copyright (C) 2020 Memoriav
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

Jonas Waeber's avatar
Jonas Waeber committed
19
20
package org.memobase

Jonas Waeber's avatar
Jonas Waeber committed
21
import ch.memobase.rdf.DC
22
23
24
25
26
27
28
import ch.memobase.rdf.MB
import ch.memobase.rdf.NS
import ch.memobase.rdf.RDA
import ch.memobase.rdf.RDF
import ch.memobase.rdf.RICO
import ch.memobase.rdf.SCHEMA
import ch.memobase.rdf.WD
Jonas Waeber's avatar
Jonas Waeber committed
29
import ch.memobase.rdf.XSD
30
import java.util.Properties
31
32
33
import org.apache.jena.rdf.model.Literal
import org.apache.jena.rdf.model.Model
import org.apache.jena.rdf.model.ModelFactory
Jonas Waeber's avatar
Jonas Waeber committed
34
import org.apache.jena.rdf.model.Property
35
36
import org.apache.jena.rdf.model.Resource
import org.apache.jena.rdf.model.ResourceFactory
Jonas Waeber's avatar
Jonas Waeber committed
37
import org.apache.logging.log4j.LogManager
Jonas Waeber's avatar
Jonas Waeber committed
38
39
import org.memobase.model.Address
import org.memobase.model.Institution
Jonas Waeber's avatar
Jonas Waeber committed
40
import org.memobase.model.Link
Jonas Waeber's avatar
Jonas Waeber committed
41
import org.memobase.model.RecordSet
42
import org.memobase.model.RichText
Jonas Waeber's avatar
Jonas Waeber committed
43

44
class RdfTransformer(properties: Properties) {
45
    private val log = LogManager.getLogger(this::class.java)
Jonas Waeber's avatar
Jonas Waeber committed
46

47
48
49
    private val cantons = Util.readLabelFile(properties.getProperty(Util.pathCantons))
    private val municipalities = Util.readLabelFile(properties.getProperty(Util.pathMunicipalities))
    private val languages = Util.readLabelFile(properties.getProperty(Util.pathLanguages))
Jonas Waeber's avatar
Jonas Waeber committed
50
51
52
53
54

    fun createInstitution(input: Institution): Pair<String, Model> {
        val model = ModelFactory.createDefaultModel()

        val resource = model.createResource(NS.mbcb + input.field_memobase_id)
55
56
        resource.addProperty(RDF.type, RICO.CorporateBody)
        resource.addProperty(RICO.type, "memobaseInstitution")
Jonas Waeber's avatar
Jonas Waeber committed
57
        resource.addLiteral(MB.isPublished, input.status)
Jonas Waeber's avatar
Jonas Waeber committed
58

59
60
61
        resource.addProperty(RICO.identifiedBy, addIdentifier(model, "main", input.field_memobase_id))
        if (input.field_old_memobase_id != null)
            resource.addProperty(RICO.identifiedBy, addIdentifier(model, "oldMemobase", input.field_old_memobase_id))
Jonas Waeber's avatar
Jonas Waeber committed
62

Jonas Waeber's avatar
Jonas Waeber committed
63
64
65
66
        input.recordset_ids.forEach {
            resource.addProperty(RICO.isHolderOf, NS.mbrs + it)
        }

67
        resource.addProperty(RICO.name, langLiteral(input.title_de, "de"))
Jonas Waeber's avatar
Jonas Waeber committed
68
69
        resource.addProperty(RICO.name, langLiteral(input.title_fr, "fr"))
        resource.addProperty(RICO.name, langLiteral(input.title_it, "it"))
Jonas Waeber's avatar
Jonas Waeber committed
70
71
72
        /* Description */
        addRichTextLiteralIfNotNull(
            resource,
73
            listOf(input.field_text_de, input.field_text_fr, input.field_text_it),
Jonas Waeber's avatar
Jonas Waeber committed
74
75
            RICO.descriptiveNote
        )
Jonas Waeber's avatar
Jonas Waeber committed
76

Jonas Waeber's avatar
Jonas Waeber committed
77
        input.field_address.forEach { address ->
78
            val location = generateLocationResource(model, address)
Jonas Waeber's avatar
Jonas Waeber committed
79
            resource.addProperty(RICO.hasLocation, location)
Jonas Waeber's avatar
Jonas Waeber committed
80
        }
Jonas Waeber's avatar
Jonas Waeber committed
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
        input.field_isil.let {
            if (it != null)
                resource.addProperty(WD.isil, literal(it))
        }
        input.field_email.let {
            if (it != null) {
                resource.addProperty(WD.emailAddress, literal(it))
            }
        }
        input.field_website.let {
            if (it != null)
                resource.addProperty(WD.website, literal(it.uri))
        }
        input.field_link_archive_catalog.let {
            if (it != null)
                resource.addProperty(WD.onlineArchive, literal(it.uri))
        }
Jonas Waeber's avatar
Jonas Waeber committed
98
99
100
        input.field_institution_types.forEach {
            resource.addProperty(WD.typeOfInstitution, model.createResource(NS.wd + it.substringAfterLast("/")))
        }
101
102
        if (input.computed_teaser_image_url != null)
            resource.addLiteral(WD.image, input.computed_teaser_image_url)
Jonas Waeber's avatar
Jonas Waeber committed
103
        return Pair(resource.uri, model)
Jonas Waeber's avatar
Jonas Waeber committed
104
105
    }

Jonas Waeber's avatar
Jonas Waeber committed
106
    fun createRecordSet(input: RecordSet): Pair<String, Model> {
107
108
109
        val model = ModelFactory.createDefaultModel()
        val resource = model.createResource(NS.mbrs + input.field_memobase_id)
        resource.addProperty(RDF.type, RICO.RecordSet)
Jonas Waeber's avatar
Jonas Waeber committed
110
        // Publikations Status
111
112
        resource.addLiteral(MB.isPublished, input.status)

Jonas Waeber's avatar
Jonas Waeber committed
113
        // Beschreibung
114
        /* Not used in the metadata model.
Jonas Waeber's avatar
Jonas Waeber committed
115
116
        addRichTextLiteralIfNotNull(
            resource,
117
            listOf(input.field_text_de, input.field_text_fr, input.field_text_it),
Jonas Waeber's avatar
Jonas Waeber committed
118
119
            RICO.descriptiveNote
        )
120
        */
121

Jonas Waeber's avatar
Jonas Waeber committed
122
        // 0.1 Titel (Memobase)
123
        addTitle(resource, model, "main", listOf(input.title_de, input.title_fr, input.title_it))
Jonas Waeber's avatar
Jonas Waeber committed
124
        // + convenience label on the resource directly.
125
        resource.addProperty(RICO.title, langLiteral(input.title_de, "de"))
126
127
        resource.addProperty(RICO.title, langLiteral(input.title_fr, "fr"))
        resource.addProperty(RICO.title, langLiteral(input.title_it, "it"))
128

Jonas Waeber's avatar
Jonas Waeber committed
129
        // 0.2.1 Thumbnail Image
130
131
132
        if (input.computed_teaser_image_url != null)
            resource.addProperty(WD.image, literal(input.computed_teaser_image_url))

Jonas Waeber's avatar
Jonas Waeber committed
133
134
135
        // 1.1 Inhalt
        addRichTextLiteralIfNotNull(
            resource,
136
            listOf(input.field_content_de, input.field_content_fr, input.field_content_it),
Jonas Waeber's avatar
Jonas Waeber committed
137
138
139
140
141
            RICO.scopeAndContent
        )

        // 1.2 Entstehungszeitraum
        // is expected to always be a normalized value YYYY/YYYY.
Jonas Waeber's avatar
Jonas Waeber committed
142
143
144
145
146
147
148
149
        input.field_time_period.let {
            if (it != null) {
                val date = model.createResource()
                date.addProperty(RDF.type, RICO.DateRange)
                date.addProperty(RICO.normalizedDateValue, it)
                resource.addProperty(RICO.isAssociatedWithDate, date)
            }
        }
Jonas Waeber's avatar
Jonas Waeber committed
150
151
152
153
154
155
156
157
        // 1.3 Sprache
        addLiteralIfNotNull(
            resource,
            listOf(input.field_language_de, input.field_language_fr, input.field_language_it),
            RDA.hasLanguageOfResource
        )

        // 1.4 Zugang Memobase
158
        addRichTextLiteralIfNotNull(
Jonas Waeber's avatar
Jonas Waeber committed
159
            resource,
160
            listOf(input.field_access_memobase_de, input.field_access_memobase_fr, input.field_access_memobase_it),
Jonas Waeber's avatar
Jonas Waeber committed
161
            RDA.hasRestrictionOnAccess
Jonas Waeber's avatar
Jonas Waeber committed
162
163
164
165
        )
        // 2.1 Kontext
        addRichTextLiteralIfNotNull(
            resource,
166
            listOf(input.field_context_de, input.field_context_fr, input.field_context_it),
Jonas Waeber's avatar
Jonas Waeber committed
167
168
169
170
171
172
173
174
            RICO.history
        )
        // 3.1 Titel
        // Originaltitle des Bestandes
        addTitle(
            resource,
            model,
            "original",
175
            listOf(input.field_original_title_de, input.field_original_title_fr, input.field_original_title_it)
Jonas Waeber's avatar
Jonas Waeber committed
176
177
178
179
        )
        // 3.2 Umfang -> recordResourceExtent
        addRichTextLiteralIfNotNull(
            resource,
180
            listOf(input.field_scope_de, input.field_scope_fr, input.field_scope_it),
Jonas Waeber's avatar
Jonas Waeber committed
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
            RICO.recordResourceExtent
        )
        // 3.3 Auswahl / Vollständigkeit
        addRichTextLiteralIfNotNull(
            resource,
            listOf(input.field_selection_de, input.field_selection_fr, input.field_selection_it),
            RICO.integrity
        )
        // 3.4 Informationen zur Erschliessung
        addRichTextLiteralIfNotNull(
            resource,
            listOf(
                input.field_info_on_development_de,
                input.field_info_on_development_fr,
                input.field_info_on_development_it
            ),
            DC.conformsTo
        )
        // 3.5 Sprache Metadaten Records
        input.field_metadata_language_codes.forEach {
            resource.addProperty(RICO.hasLanguage, addLanguage(model, it))
        }
        // 3.6 Rechte
        addRichTextLiteralIfNotNull(
            resource,
            listOf(
                input.field_rights_de,
                input.field_rights_fr,
                input.field_rights_it
            ),
            RICO.conditionsOfUse
        )
        // 3.7 Original ID
        input.field_original_id.let {
            if (it != null) {
Jonas Waeber's avatar
Jonas Waeber committed
216
                resource.addProperty(RICO.identifiedBy, addIdentifier(model, "original", it))
Jonas Waeber's avatar
Jonas Waeber committed
217
218
219
220
221
            }
        }
        // 3.8 Original Signatur
        input.field_original_shelf_mark.let {
            if (it != null) {
Jonas Waeber's avatar
Jonas Waeber committed
222
                resource.addProperty(RICO.identifiedBy, addIdentifier(model, "callNumber", it))
Jonas Waeber's avatar
Jonas Waeber committed
223
224
            }
        }
Jonas Waeber's avatar
Jonas Waeber committed
225
226
        // 3.9 Original Beschreibung (Text)
        // 3.9.1 Original Beschreibung (Link)
Jonas Waeber's avatar
Jonas Waeber committed
227
228
229
230
        addOriginalRecordSetLink(
            model,
            resource,
            listOf(
231
                input.field_original_description_de,
Jonas Waeber's avatar
Jonas Waeber committed
232
233
234
235
236
237
                input.field_original_description_fr,
                input.field_original_description_it
            )
        )

        // 4.1 Zugang
238
        addRichTextLiteralIfNotNull(
Jonas Waeber's avatar
Jonas Waeber committed
239
            resource,
240
            listOf(input.field_access_de, input.field_access_fr, input.field_access_it),
Jonas Waeber's avatar
Jonas Waeber committed
241
242
243
244
245
246
247
248
249
            RICO.conditionsOfAccess
        )
        // 4.2 Zuständige Institution (Original)
        addRelatedInstitution(model, resource, "original", input.field_resp_institution_original)
        // 4.3 Zuständige Institution (Master)
        addRelatedInstitution(model, resource, "master", input.field_resp_institution_master)
        // 4.4 Zuständige Institution (Access)
        addRelatedInstitution(model, resource, "access", input.field_resp_institution_access)

250
        // Currently each project link is added as a separate entity.
Jonas Waeber's avatar
Jonas Waeber committed
251
252
        // 5.1 Projekt (Titel)
        // 5.2 Projekt (Link)
253
254
255
256
257
258
259
260
261
262
        input.field_project_de.forEach { link ->
            addMemoriavProject(resource, model, link, "de")
        }
        input.field_project_fr.forEach { link ->
            addMemoriavProject(resource, model, link, "fr")
        }
        input.field_project_it.forEach { link ->
            addMemoriavProject(resource, model, link, "it")
        }
        // Currently each record set link is added as a separate entity.
Jonas Waeber's avatar
Jonas Waeber committed
263
264
        // 5.3 Verwandte Bestände (Titel)
        // 5.4 Verwandte Bestände (Link)
265
266
267
268
269
270
271
272
273
274
        input.field_related_record_sets_de.forEach { link ->
            addRelatedRecordSet(resource, model, link, "de")
        }
        input.field_related_record_sets_fr.forEach { link ->
            addRelatedRecordSet(resource, model, link, "fr")
        }
        input.field_related_record_sets_it.forEach { link ->
            addRelatedRecordSet(resource, model, link, "it")
        }
        // Currently each publication link is added as a separate entity.
Jonas Waeber's avatar
Jonas Waeber committed
275
276
        // 5.5 Publikationen (Titel)
        // 5.6 Publikationen (Link)
277
278
279
280
281
282
283
284
285
286
        input.field_publications_de.forEach { link ->
            addRelatedRecord(resource, model, link, "de", RICO.isSubjectOf)
        }
        input.field_publications_fr.forEach { link ->
            addRelatedRecord(resource, model, link, "fr", RICO.isSubjectOf)
        }
        input.field_publications_it.forEach { link ->
            addRelatedRecord(resource, model, link, "it", RICO.isSubjectOf)
        }
        // Currently each record link is added as a separate entity.
Jonas Waeber's avatar
Jonas Waeber committed
287
288
        // 5.7 Dokumente (Titel)
        // 5.8 Dokumente (Link)
289
        input.field_documents_de.forEach { link ->
290
291
            addRelatedRecord(resource, model, link, "de", RICO.isRecordResourceAssociatedWithRecordResource)
        }
292
        input.field_documents_fr.forEach { link ->
293
294
            addRelatedRecord(resource, model, link, "fr", RICO.isRecordResourceAssociatedWithRecordResource)
        }
295
        input.field_documents_it.forEach { link ->
296
297
            addRelatedRecord(resource, model, link, "it", RICO.isRecordResourceAssociatedWithRecordResource)
        }
Jonas Waeber's avatar
Jonas Waeber committed
298
299
300
        // 6.1 Datenübernahme
        addRichTextLiteralIfNotNull(
            resource,
301
            listOf(input.field_data_transfer_de, input.field_data_transfer_fr, input.field_data_transfer_it),
Jonas Waeber's avatar
Jonas Waeber committed
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
            RICO.descriptiveNote
        )
        // 6.2 Datum der Übernahme in Memobase
        input.field_transfer_date.let {
            if (it != null) {
                val date = it.split("T")[0]
                val literal = model.createTypedLiteral(date, XSD.date)
                resource.addLiteral(RICO.publicationDate, literal)
            }
        }
        // 6.3 Datum letzte Aktualisierung in Memobase
        val literal = model.createTypedLiteral(Util.now, XSD.dateTime)
        resource.addLiteral(RICO.modificationDate, literal)
        // 6.4 Memobase ID
        resource.addProperty(RICO.identifiedBy, addIdentifier(model, "main", input.field_memobase_id))
Jonas Waeber's avatar
Jonas Waeber committed
317

Jonas Waeber's avatar
Jonas Waeber committed
318
319
320
321
322
323
324
325
326
        // 8.1 Unterstützt durch Memoriav
        resource.addProperty(RDA.hasSponsoringAgentOfResource, model.createResource(Util.memoriavUri))
        // 8.2 Institution
        input.field_institution.forEach {
            resource.addProperty(RICO.heldBy, NS.mbcb + it)
        }
        // 9.3 Alte Memobase ID
        if (input.field_old_memobase_id != null)
            resource.addProperty(RICO.identifiedBy, addIdentifier(model, "oldMemobase", input.field_old_memobase_id))
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
        return Pair(resource.uri, model)
    }

    private fun addIdentifier(model: Model, type: String, value: String): Resource {
        val identifier = model.createResource()
        identifier.addProperty(RDF.type, RICO.Identifier)
        identifier.addProperty(RICO.type, literal(type))
        identifier.addProperty(RICO.identifier, literal(value))
        return identifier
    }

    private fun addLanguage(model: Model, value: String): Resource {
        val language = model.createResource()
        language.addProperty(RDF.type, RICO.Language)
        language.addProperty(RICO.type, literal("metadata"))
        languages[value].let {
            if (it == null) {
                language.addProperty(RICO.name, literal(value))
            } else {
                language.addProperty(RICO.name, langLiteral(it.de, "de"))
                language.addProperty(RICO.name, langLiteral(it.fr, "fr"))
                language.addProperty(RICO.name, langLiteral(it.it, "it"))
                language.addProperty(SCHEMA.sameAs, literal(it.id))
            }
        }
        return language
    }

Jonas Waeber's avatar
Jonas Waeber committed
355
356
357
    private fun addTitle(resource: Resource, model: Model, type: String, titles: List<String?>) {
        if (titles.all { it == null })
            return
358
359
        val language = model.createResource()
        language.addProperty(RDF.type, RICO.Title)
Jonas Waeber's avatar
Jonas Waeber committed
360
361
362
363
364
365
        language.addProperty(RICO.type, literal(type))
        titles.forEachIndexed { index, s ->
            if (s != null)
                language.addProperty(RICO.title, langLiteral(s, getLanguage(index)))
        }
        resource.addProperty(RICO.hasTitle, language)
Jonas Waeber's avatar
Jonas Waeber committed
366
367
    }

368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
    private fun addMemoriavProject(resource: Resource, model: Model, link: Link, language: String) {
        val node = model.createResource()
        node.addProperty(RDF.type, RICO.CorporateBody)
        node.addProperty(RICO.type, Util.memoriavProject)
        link.title.let {
            if (it != null && it.isNotEmpty())
                node.addProperty(RICO.title, langLiteral(it, language))
        }
        node.addProperty(SCHEMA.sameAs, literal(link.uri))
        resource.addProperty(RDA.hasSponsoringAgentOfResource, node)
    }
    private fun addRelatedRecordSet(resource: Resource, model: Model, link: Link, language: String) {
        val node = model.createResource()
        node.addProperty(RDF.type, RICO.RecordSet)
        link.title.let {
            if (it != null && it.isNotEmpty())
                node.addProperty(RICO.title, langLiteral(it, language))
        }
        node.addProperty(SCHEMA.sameAs, literal(link.uri))
        resource.addProperty(RICO.isRecordResourceAssociatedWithRecordResource, node)
    }
    private fun addRelatedRecord(resource: Resource, model: Model, link: Link, language: String, property: Property) {
        val node = model.createResource()
        node.addProperty(RDF.type, RICO.Record)
        link.title.let {
            if (it != null && it.isNotEmpty())
                node.addProperty(RICO.title, langLiteral(it, language))
        }
        node.addProperty(SCHEMA.sameAs, literal(link.uri))
        resource.addProperty(property, node)
    }

400
401
    private fun generateLocationResource(model: Model, address: Address): Resource {
        val location = model.createResource()
402

Jonas Waeber's avatar
Jonas Waeber committed
403
404
405
406
407
408
        val streetAddress = address.address_line1
        val secondAddressLine = address.address_line2
        val combinedStreetAddress = if (secondAddressLine.isNullOrEmpty()) {
            streetAddress
        } else {
            streetAddress + "\n" + secondAddressLine
Jonas Waeber's avatar
Jonas Waeber committed
409
        }
Jonas Waeber's avatar
Jonas Waeber committed
410
411
412
413
414
415
        val streetNumber = streetAddress.substringAfterLast(" ")
        val street = streetAddress.replace(streetNumber, "").trim()
        location.addProperty(WD.street, literal(street))
        location.addProperty(WD.streetNumber, literal(streetNumber))
        location.addProperty(WD.streetAddress, literal(combinedStreetAddress))

Jonas Waeber's avatar
Jonas Waeber committed
416

Jonas Waeber's avatar
Jonas Waeber committed
417
        val postalCode = address.postal_code.trim()
Jonas Waeber's avatar
Jonas Waeber committed
418

419
        location.addProperty(RDF.type, RICO.Place)
Jonas Waeber's avatar
Jonas Waeber committed
420
        location.addProperty(WD.postalCode, literal(postalCode))
Jonas Waeber's avatar
Jonas Waeber committed
421
422
423

        location.addProperty(WD.coordinates, literal(address.coordinates))

424
        val canton = model.createResource()
Jonas Waeber's avatar
Jonas Waeber committed
425
426
427
428
429
430
431
432
433
434
435
436
437
        canton.addProperty(RDF.type, RICO.Place)
        location.addProperty(WD.adminUnit, canton)
        cantons[address.administrative_area].let {
            // this should always be the case!
            if (it != null) {
                canton.addProperty(RICO.name, langLiteral(it.de, "de"))
                canton.addProperty(RICO.name, langLiteral(it.fr, "fr"))
                canton.addProperty(RICO.name, langLiteral(it.it, "it"))
                canton.addProperty(SCHEMA.sameAs, it.id)
            } else {
                // this shouldn't happen!
                canton.addProperty(RICO.name, literal("Unknown"))
            }
438
            canton.addProperty(RICO.type, literal("canton"))
Jonas Waeber's avatar
Jonas Waeber committed
439
440
        }

441
        val municipality = model.createResource()
Jonas Waeber's avatar
Jonas Waeber committed
442
443
444
445
446
447
448
449
450
451
        municipality.addProperty(RDF.type, RICO.Place)
        location.addProperty(WD.adminUnit, municipality)
        municipalities[postalCode].let {
            if (it != null) {
                municipality.addProperty(RICO.name, langLiteral(it.de, "de"))
                municipality.addProperty(RICO.name, langLiteral(it.fr, "fr"))
                municipality.addProperty(RICO.name, langLiteral(it.it, "it"))
                municipality.addProperty(SCHEMA.sameAs, it.id)
            } else {
                municipality.addProperty(RICO.name, literal(address.locality))
Jonas Waeber's avatar
Jonas Waeber committed
452
            }
453
            municipality.addProperty(RICO.type, "municipality")
Jonas Waeber's avatar
Jonas Waeber committed
454
455
456
        }
        // country is currently hard coded to switzerland!
        location.addProperty(WD.country, WD.switzerland)
Jonas Waeber's avatar
Jonas Waeber committed
457
458
459
        return location
    }

Jonas Waeber's avatar
Jonas Waeber committed
460
461
    private fun langLiteral(text: String, language: String): Literal =
        ResourceFactory.createLangLiteral(text.trim(), language)
462

Jonas Waeber's avatar
Jonas Waeber committed
463
    private fun literal(text: String): Literal = ResourceFactory.createPlainLiteral(text.trim())
464

Jonas Waeber's avatar
Jonas Waeber committed
465
466
467
468
    private fun addRichTextLiteralIfNotNull(resource: Resource, field: List<RichText?>, property: Property) {
        field.forEachIndexed { index, s ->
            if (s != null)
                resource.addProperty(property, langLiteral(s.value, getLanguage(index)))
469
470
        }
    }
Jonas Waeber's avatar
Jonas Waeber committed
471

Jonas Waeber's avatar
Jonas Waeber committed
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
    private fun getLanguage(index: Int): String {
        return when (index) {
            0 -> "de"
            1 -> "fr"
            2 -> "it"
            else -> "un"
        }
    }

    private fun addLiteralIfNotNull(resource: Resource, fields: List<String?>, property: Property) {
        fields.forEachIndexed { index, s ->
            if (s != null)
                resource.addProperty(property, langLiteral(s, getLanguage(index)))
        }
    }

    private fun addOriginalRecordSetLink(model: Model, resource: Resource, links: List<Link?>) {
        if (links.all { it == null })
            return
        val recordSet = model.createResource()
        recordSet.addProperty(RDF.type, RICO.RecordSet)
        links.forEachIndexed { index, link ->
            if (link != null) {
                recordSet.addLiteral(SCHEMA.sameAs, langLiteral(link.uri, getLanguage(index)))
                link.title.let { title ->
                    if (title != null) {
                        recordSet.addLiteral(RICO.title, langLiteral(title, getLanguage(index)))
                    }
                }
            }
        }
        resource.addProperty(RICO.hasSource, recordSet)
    }

    private fun addRelatedInstitution(model: Model, resource: Resource, type: String, item: List<String>) {
        item.forEach {
            val node = model.createResource()
            node.addProperty(RDF.type, RICO.RecordResourceHoldingRelation)
            node.addProperty(RICO.type, type)
            node.addProperty(RICO.recordResourceHoldingRelationHasTarget, resource)
            node.addProperty(RICO.recordResourceHoldingRelationHasSource, NS.mbrs + it)
            resource.addProperty(RICO.recordResourceOrInstantiationIsTargetOfRecordResourceHoldingRelation, node)
Jonas Waeber's avatar
Jonas Waeber committed
514
515
        }
    }
Jonas Waeber's avatar
Jonas Waeber committed
516
}