RdfTransformer.kt 21.6 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
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
27
import ch.memobase.rdf.RICO.Types
28
29
import ch.memobase.rdf.SCHEMA
import ch.memobase.rdf.WD
Jonas Waeber's avatar
Jonas Waeber committed
30
import ch.memobase.rdf.XSD
31
import java.util.Properties
32
33
34
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
35
import org.apache.jena.rdf.model.Property
36
37
import org.apache.jena.rdf.model.Resource
import org.apache.jena.rdf.model.ResourceFactory
Jonas Waeber's avatar
Jonas Waeber committed
38
import org.apache.logging.log4j.LogManager
Jonas Waeber's avatar
Jonas Waeber committed
39
40
import org.memobase.model.Address
import org.memobase.model.Institution
Jonas Waeber's avatar
Jonas Waeber committed
41
import org.memobase.model.Link
Jonas Waeber's avatar
Jonas Waeber committed
42
import org.memobase.model.RecordSet
43
import org.memobase.model.RichText
Jonas Waeber's avatar
Jonas Waeber committed
44

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

48
49
50
    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
51
52
53
54
55

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

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

60
61
        resource.addProperty(RICO.identifiedBy, addIdentifier(model, Types.Identifier.main, input.field_memobase_id))

62
        if (input.field_old_memobase_id != null)
63
            resource.addProperty(RICO.identifiedBy, addIdentifier(model, Types.Identifier.oldMemobase, input.field_old_memobase_id))
Jonas Waeber's avatar
Jonas Waeber committed
64

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

69
        resource.addProperty(RICO.name, langLiteral(input.title_de, "de"))
Jonas Waeber's avatar
Jonas Waeber committed
70
71
        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
72
73
74
        /* Description */
        addRichTextLiteralIfNotNull(
            resource,
75
            listOf(input.field_text_de, input.field_text_fr, input.field_text_it),
Jonas Waeber's avatar
Jonas Waeber committed
76
77
            RICO.descriptiveNote
        )
Jonas Waeber's avatar
Jonas Waeber committed
78

Jonas Waeber's avatar
Jonas Waeber committed
79
        input.field_address.forEach { address ->
80
            val location = generateLocationResource(model, address)
Jonas Waeber's avatar
Jonas Waeber committed
81
            resource.addProperty(RICO.hasLocation, location)
Jonas Waeber's avatar
Jonas Waeber committed
82
        }
Jonas Waeber's avatar
Jonas Waeber committed
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
        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
100
101
102
        input.field_institution_types.forEach {
            resource.addProperty(WD.typeOfInstitution, model.createResource(NS.wd + it.substringAfterLast("/")))
        }
103
104
        if (input.computed_teaser_image_url != null)
            resource.addLiteral(WD.image, input.computed_teaser_image_url)
105
        log.info("Transformed institution ${resource.uri}.")
Jonas Waeber's avatar
Jonas Waeber committed
106
        return Pair(resource.uri, model)
Jonas Waeber's avatar
Jonas Waeber committed
107
108
    }

Jonas Waeber's avatar
Jonas Waeber committed
109
    fun createRecordSet(input: RecordSet): Pair<String, Model> {
110
111
112
        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
113
        // Publikations Status
114
115
        resource.addLiteral(MB.isPublished, input.status)

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

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

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

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

        // 1.2 Entstehungszeitraum
        // is expected to always be a normalized value YYYY/YYYY.
Jonas Waeber's avatar
Jonas Waeber committed
145
146
147
148
149
150
151
152
        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
153
154
155
156
157
158
159
160
        // 1.3 Sprache
        addLiteralIfNotNull(
            resource,
            listOf(input.field_language_de, input.field_language_fr, input.field_language_it),
            RDA.hasLanguageOfResource
        )

        // 1.4 Zugang Memobase
161
        addRichTextLiteralIfNotNull(
Jonas Waeber's avatar
Jonas Waeber committed
162
            resource,
163
            listOf(input.field_access_memobase_de, input.field_access_memobase_fr, input.field_access_memobase_it),
Jonas Waeber's avatar
Jonas Waeber committed
164
            RDA.hasRestrictionOnAccess
Jonas Waeber's avatar
Jonas Waeber committed
165
166
167
168
        )
        // 2.1 Kontext
        addRichTextLiteralIfNotNull(
            resource,
169
            listOf(input.field_context_de, input.field_context_fr, input.field_context_it),
Jonas Waeber's avatar
Jonas Waeber committed
170
171
172
173
174
175
176
            RICO.history
        )
        // 3.1 Titel
        // Originaltitle des Bestandes
        addTitle(
            resource,
            model,
177
            Types.Title.original,
178
            listOf(input.field_original_title_de, input.field_original_title_fr, input.field_original_title_it)
Jonas Waeber's avatar
Jonas Waeber committed
179
180
181
182
        )
        // 3.2 Umfang -> recordResourceExtent
        addRichTextLiteralIfNotNull(
            resource,
183
            listOf(input.field_scope_de, input.field_scope_fr, input.field_scope_it),
Jonas Waeber's avatar
Jonas Waeber committed
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
216
217
218
            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) {
219
                resource.addProperty(RICO.identifiedBy, addIdentifier(model, Types.Identifier.original, it))
Jonas Waeber's avatar
Jonas Waeber committed
220
221
222
223
224
            }
        }
        // 3.8 Original Signatur
        input.field_original_shelf_mark.let {
            if (it != null) {
225
                resource.addProperty(RICO.identifiedBy, addIdentifier(model, Types.Identifier.callNumber, it))
Jonas Waeber's avatar
Jonas Waeber committed
226
227
            }
        }
Jonas Waeber's avatar
Jonas Waeber committed
228
229
        // 3.9 Original Beschreibung (Text)
        // 3.9.1 Original Beschreibung (Link)
Jonas Waeber's avatar
Jonas Waeber committed
230
231
232
233
        addOriginalRecordSetLink(
            model,
            resource,
            listOf(
234
                input.field_original_description_de,
Jonas Waeber's avatar
Jonas Waeber committed
235
236
237
238
239
240
                input.field_original_description_fr,
                input.field_original_description_it
            )
        )

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

253
        // Currently each project link is added as a separate entity.
Jonas Waeber's avatar
Jonas Waeber committed
254
255
        // 5.1 Projekt (Titel)
        // 5.2 Projekt (Link)
256
257
258
259
260
261
262
263
264
265
        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
266
267
        // 5.3 Verwandte Bestände (Titel)
        // 5.4 Verwandte Bestände (Link)
268
269
270
271
272
273
274
275
276
277
        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
278
279
        // 5.5 Publikationen (Titel)
        // 5.6 Publikationen (Link)
280
        input.field_publications_de.forEach { link ->
281
            addRelatedRecord(resource, model, link, "de", RICO.isSubjectOf, Types.Record.publication)
282
283
        }
        input.field_publications_fr.forEach { link ->
284
            addRelatedRecord(resource, model, link, "fr", RICO.isSubjectOf, Types.Record.publication)
285
286
        }
        input.field_publications_it.forEach { link ->
287
            addRelatedRecord(resource, model, link, "it", RICO.isSubjectOf, Types.Record.publication)
288
289
        }
        // Currently each record link is added as a separate entity.
Jonas Waeber's avatar
Jonas Waeber committed
290
291
        // 5.7 Dokumente (Titel)
        // 5.8 Dokumente (Link)
292
        input.field_documents_de.forEach { link ->
293
            addRelatedRecord(resource, model, link, "de", RICO.isRecordResourceAssociatedWithRecordResource, Types.Record.related)
294
        }
295
        input.field_documents_fr.forEach { link ->
296
            addRelatedRecord(resource, model, link, "fr", RICO.isRecordResourceAssociatedWithRecordResource, Types.Record.related)
297
        }
298
        input.field_documents_it.forEach { link ->
299
            addRelatedRecord(resource, model, link, "it", RICO.isRecordResourceAssociatedWithRecordResource, Types.Record.related)
300
        }
Jonas Waeber's avatar
Jonas Waeber committed
301
302
303
        // 6.1 Datenübernahme
        addRichTextLiteralIfNotNull(
            resource,
304
            listOf(input.field_data_transfer_de, input.field_data_transfer_fr, input.field_data_transfer_it),
Jonas Waeber's avatar
Jonas Waeber committed
305
306
307
308
309
310
311
312
313
314
315
316
317
318
            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
319
        resource.addProperty(RICO.identifiedBy, addIdentifier(model, Types.Identifier.main, input.field_memobase_id))
Jonas Waeber's avatar
Jonas Waeber committed
320

Jonas Waeber's avatar
Jonas Waeber committed
321
        // 8.1 Unterstützt durch Memoriav
322
        resource.addProperty(RDA.hasSponsoringAgentOfResource, model.createResource(MB.memoriavInstitutionURI))
Jonas Waeber's avatar
Jonas Waeber committed
323
324
325
326
327
328
        // 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)
329
330
            resource.addProperty(RICO.identifiedBy, addIdentifier(model, Types.Identifier.oldMemobase, input.field_old_memobase_id))
        log.info("Transformed record set ${resource.uri}.")
331
332
333
334
335
336
337
338
339
340
341
342
343
344
        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)
345
        language.addProperty(RICO.type, literal(Types.Language.metadata))
346
347
348
349
350
351
352
353
354
355
356
357
358
        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
359
360
361
    private fun addTitle(resource: Resource, model: Model, type: String, titles: List<String?>) {
        if (titles.all { it == null })
            return
362
363
        val language = model.createResource()
        language.addProperty(RDF.type, RICO.Title)
Jonas Waeber's avatar
Jonas Waeber committed
364
365
366
367
368
369
        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
370
371
    }

372
373
374
    private fun addMemoriavProject(resource: Resource, model: Model, link: Link, language: String) {
        val node = model.createResource()
        node.addProperty(RDF.type, RICO.CorporateBody)
375
        node.addProperty(RICO.type, Types.CorporateBody.memoriavProject)
376
377
378
379
380
381
382
383
384
385
386
387
388
389
        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))
        }
390
        node.addProperty(RICO.type, literal(Types.RecordSet.related))
391
392
393
        node.addProperty(SCHEMA.sameAs, literal(link.uri))
        resource.addProperty(RICO.isRecordResourceAssociatedWithRecordResource, node)
    }
394
    private fun addRelatedRecord(resource: Resource, model: Model, link: Link, language: String, property: Property, type: String) {
395
396
397
398
399
400
        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))
        }
401
        node.addProperty(RICO.type, literal(type))
402
403
404
405
        node.addProperty(SCHEMA.sameAs, literal(link.uri))
        resource.addProperty(property, node)
    }

406
407
    private fun generateLocationResource(model: Model, address: Address): Resource {
        val location = model.createResource()
408

Jonas Waeber's avatar
Jonas Waeber committed
409
410
411
412
413
414
        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
415
        }
Jonas Waeber's avatar
Jonas Waeber committed
416
417
418
419
420
421
        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
422

Jonas Waeber's avatar
Jonas Waeber committed
423
        val postalCode = address.postal_code.trim()
Jonas Waeber's avatar
Jonas Waeber committed
424

425
        location.addProperty(RDF.type, RICO.Place)
Jonas Waeber's avatar
Jonas Waeber committed
426
        location.addProperty(WD.postalCode, literal(postalCode))
Jonas Waeber's avatar
Jonas Waeber committed
427
428
429

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

430
        val canton = model.createResource()
Jonas Waeber's avatar
Jonas Waeber committed
431
432
433
434
435
436
437
438
439
440
441
442
443
        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"))
            }
444
            canton.addProperty(RICO.type, literal("canton"))
Jonas Waeber's avatar
Jonas Waeber committed
445
446
        }

447
        val municipality = model.createResource()
Jonas Waeber's avatar
Jonas Waeber committed
448
449
450
451
452
453
454
455
456
457
        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
458
            }
459
            municipality.addProperty(RICO.type, "municipality")
Jonas Waeber's avatar
Jonas Waeber committed
460
461
462
        }
        // country is currently hard coded to switzerland!
        location.addProperty(WD.country, WD.switzerland)
Jonas Waeber's avatar
Jonas Waeber committed
463
464
465
        return location
    }

Jonas Waeber's avatar
Jonas Waeber committed
466
467
    private fun langLiteral(text: String, language: String): Literal =
        ResourceFactory.createLangLiteral(text.trim(), language)
468

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

Jonas Waeber's avatar
Jonas Waeber committed
471
472
473
474
    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)))
475
476
        }
    }
Jonas Waeber's avatar
Jonas Waeber committed
477

Jonas Waeber's avatar
Jonas Waeber committed
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
514
515
516
517
518
519
    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
520
521
        }
    }
Jonas Waeber's avatar
Jonas Waeber committed
522
}