RdfTransformer.kt 23 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)
Jonas Waeber's avatar
Jonas Waeber committed
63
64
65
66
            resource.addProperty(
                RICO.identifiedBy,
                addIdentifier(model, Types.Identifier.oldMemobase, input.field_old_memobase_id)
            )
Jonas Waeber's avatar
Jonas Waeber committed
67

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

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

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

Jonas Waeber's avatar
Jonas Waeber committed
120
    fun createRecordSet(input: RecordSet): Pair<String, Model> {
121
122
123
        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
124
        // Publikations Status
125
126
        resource.addLiteral(MB.isPublished, input.status)

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

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

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

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

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

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

255
        // Currently each project link is added as a separate entity.
Jonas Waeber's avatar
Jonas Waeber committed
256
257
        // 5.1 Projekt (Titel)
        // 5.2 Projekt (Link)
258
259
260
261
262
263
264
265
266
267
        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
268
269
        // 5.3 Verwandte Bestände (Titel)
        // 5.4 Verwandte Bestände (Link)
270
        input.field_related_record_sets_de.forEach { link ->
Jonas Waeber's avatar
Jonas Waeber committed
271
272
273
274
275
276
277
278
            if (link.title == Util.internalRelatedRecordSet) {
                resource.addProperty(
                    RICO.isRecordResourceAssociatedWithRecordResource,
                    model.createResource(NS.mbrs + link.uri)
                )
            } else {
                addRelatedRecordSet(resource, model, link, "de")
            }
279
280
        }
        input.field_related_record_sets_fr.forEach { link ->
Jonas Waeber's avatar
Jonas Waeber committed
281
282
283
284
285
286
287
288
            if (link.title == Util.internalRelatedRecordSet) {
                resource.addProperty(
                    RICO.isRecordResourceAssociatedWithRecordResource,
                    model.createResource(NS.mbrs + link.uri)
                )
            } else {
                addRelatedRecordSet(resource, model, link, "fr")
            }
289
290
        }
        input.field_related_record_sets_it.forEach { link ->
Jonas Waeber's avatar
Jonas Waeber committed
291
292
293
294
295
296
297
298
            if (link.title == Util.internalRelatedRecordSet) {
                resource.addProperty(
                    RICO.isRecordResourceAssociatedWithRecordResource,
                    model.createResource(NS.mbrs + link.uri)
                )
            } else {
                addRelatedRecordSet(resource, model, link, "it")
            }
299
300
        }
        // Currently each publication link is added as a separate entity.
Jonas Waeber's avatar
Jonas Waeber committed
301
302
        // 5.5 Publikationen (Titel)
        // 5.6 Publikationen (Link)
303
        input.field_publications_de.forEach { link ->
304
            addRelatedRecord(resource, model, link, "de", RICO.isSubjectOf, Types.Record.publication)
305
306
        }
        input.field_publications_fr.forEach { link ->
307
            addRelatedRecord(resource, model, link, "fr", RICO.isSubjectOf, Types.Record.publication)
308
309
        }
        input.field_publications_it.forEach { link ->
310
            addRelatedRecord(resource, model, link, "it", RICO.isSubjectOf, Types.Record.publication)
311
312
        }
        // Currently each record link is added as a separate entity.
Jonas Waeber's avatar
Jonas Waeber committed
313
314
        // 5.7 Dokumente (Titel)
        // 5.8 Dokumente (Link)
315
        input.field_documents_de.forEach { link ->
Jonas Waeber's avatar
Jonas Waeber committed
316
317
318
319
320
321
322
323
            addRelatedRecord(
                resource,
                model,
                link,
                "de",
                RICO.isRecordResourceAssociatedWithRecordResource,
                Types.Record.related
            )
324
        }
325
        input.field_documents_fr.forEach { link ->
Jonas Waeber's avatar
Jonas Waeber committed
326
327
328
329
330
331
332
333
            addRelatedRecord(
                resource,
                model,
                link,
                "fr",
                RICO.isRecordResourceAssociatedWithRecordResource,
                Types.Record.related
            )
334
        }
335
        input.field_documents_it.forEach { link ->
Jonas Waeber's avatar
Jonas Waeber committed
336
337
338
339
340
341
342
343
            addRelatedRecord(
                resource,
                model,
                link,
                "it",
                RICO.isRecordResourceAssociatedWithRecordResource,
                Types.Record.related
            )
344
        }
Jonas Waeber's avatar
Jonas Waeber committed
345
346
347
        // 6.1 Datenübernahme
        addRichTextLiteralIfNotNull(
            resource,
348
            listOf(input.field_data_transfer_de, input.field_data_transfer_fr, input.field_data_transfer_it),
Jonas Waeber's avatar
Jonas Waeber committed
349
350
351
352
353
354
355
356
357
358
359
360
361
362
            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
363
        resource.addProperty(RICO.identifiedBy, addIdentifier(model, Types.Identifier.main, input.field_memobase_id))
Jonas Waeber's avatar
Jonas Waeber committed
364

Jonas Waeber's avatar
Jonas Waeber committed
365
        // 8.1 Unterstützt durch Memoriav
366
        resource.addProperty(RDA.hasSponsoringAgentOfResource, model.createResource(MB.memoriavInstitutionURI))
Jonas Waeber's avatar
Jonas Waeber committed
367
368
369
370
371
372
        // 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)
Jonas Waeber's avatar
Jonas Waeber committed
373
374
375
376
            resource.addProperty(
                RICO.identifiedBy,
                addIdentifier(model, Types.Identifier.oldMemobase, input.field_old_memobase_id)
            )
377
        log.info("Transformed record set ${resource.uri}.")
378
379
380
381
382
383
384
385
386
387
388
389
390
391
        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)
392
        language.addProperty(RICO.type, literal(Types.Language.metadata))
393
394
395
396
397
398
399
400
401
402
403
404
405
        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
406
407
408
    private fun addTitle(resource: Resource, model: Model, type: String, titles: List<String?>) {
        if (titles.all { it == null })
            return
409
410
        val language = model.createResource()
        language.addProperty(RDF.type, RICO.Title)
Jonas Waeber's avatar
Jonas Waeber committed
411
412
413
414
415
416
        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
417
418
    }

419
420
421
    private fun addMemoriavProject(resource: Resource, model: Model, link: Link, language: String) {
        val node = model.createResource()
        node.addProperty(RDF.type, RICO.CorporateBody)
422
        node.addProperty(RICO.type, Types.CorporateBody.memoriavProject)
423
424
425
426
427
428
429
        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)
    }
Jonas Waeber's avatar
Jonas Waeber committed
430

431
432
433
434
435
436
437
    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))
        }
438
        node.addProperty(RICO.type, literal(Types.RecordSet.related))
439
440
441
        node.addProperty(SCHEMA.sameAs, literal(link.uri))
        resource.addProperty(RICO.isRecordResourceAssociatedWithRecordResource, node)
    }
Jonas Waeber's avatar
Jonas Waeber committed
442
443
444
445
446
447
448
449
450

    private fun addRelatedRecord(
        resource: Resource,
        model: Model,
        link: Link,
        language: String,
        property: Property,
        type: String
    ) {
451
452
453
454
455
456
        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))
        }
457
        node.addProperty(RICO.type, literal(type))
458
459
460
461
        node.addProperty(SCHEMA.sameAs, literal(link.uri))
        resource.addProperty(property, node)
    }

462
463
    private fun generateLocationResource(model: Model, address: Address): Resource {
        val location = model.createResource()
464

Jonas Waeber's avatar
Jonas Waeber committed
465
466
467
468
469
470
        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
471
        }
Jonas Waeber's avatar
Jonas Waeber committed
472
473
474
475
476
477
        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
478

Jonas Waeber's avatar
Jonas Waeber committed
479
        val postalCode = address.postal_code.trim()
Jonas Waeber's avatar
Jonas Waeber committed
480

481
        location.addProperty(RDF.type, RICO.Place)
Jonas Waeber's avatar
Jonas Waeber committed
482
        location.addProperty(WD.postalCode, literal(postalCode))
Jonas Waeber's avatar
Jonas Waeber committed
483
484
485

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

486
        val canton = model.createResource()
Jonas Waeber's avatar
Jonas Waeber committed
487
488
489
490
491
492
493
494
495
496
497
498
499
        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"))
            }
500
            canton.addProperty(RICO.type, literal("canton"))
Jonas Waeber's avatar
Jonas Waeber committed
501
502
        }

503
        val municipality = model.createResource()
Jonas Waeber's avatar
Jonas Waeber committed
504
505
506
507
508
509
510
511
512
513
        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
514
            }
515
            municipality.addProperty(RICO.type, "municipality")
Jonas Waeber's avatar
Jonas Waeber committed
516
517
518
        }
        // country is currently hard coded to switzerland!
        location.addProperty(WD.country, WD.switzerland)
Jonas Waeber's avatar
Jonas Waeber committed
519
520
521
        return location
    }

Jonas Waeber's avatar
Jonas Waeber committed
522
523
    private fun langLiteral(text: String, language: String): Literal =
        ResourceFactory.createLangLiteral(text.trim(), language)
524

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

Jonas Waeber's avatar
Jonas Waeber committed
527
528
529
530
    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)))
531
532
        }
    }
Jonas Waeber's avatar
Jonas Waeber committed
533

Jonas Waeber's avatar
Jonas Waeber committed
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
    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)
574
            node.addProperty(RICO.recordResourceHoldingRelationHasSource, NS.mbcb + it)
Jonas Waeber's avatar
Jonas Waeber committed
575
            resource.addProperty(RICO.recordResourceOrInstantiationIsTargetOfRecordResourceHoldingRelation, node)
Jonas Waeber's avatar
Jonas Waeber committed
576
577
        }
    }
Jonas Waeber's avatar
Jonas Waeber committed
578
}