RdfTransformer.kt 23.5 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)

127 128 129 130 131 132 133 134 135 136 137
        input.field_processed_teaser_text_de?.let { langLiteral(it.processed, "de") }?.let {
            resource.addLiteral(MB.recordSetProcessedTeaserText, it)
        }
        input.field_processed_teaser_text_fr?.let { langLiteral(it.processed, "fr") }?.let {
            resource.addLiteral(MB.recordSetProcessedTeaserText, it)
        }
        input.field_processed_teaser_text_it?.let { langLiteral(it.processed, "it") }?.let {
            resource.addLiteral(MB.recordSetProcessedTeaserText, it)
        }


Jonas Waeber's avatar
Jonas Waeber committed
138
        // 0.1 Titel (Memobase)
139
        addTitle(resource, model, Types.Title.main, listOf(input.title_de, input.title_fr, input.title_it))
Jonas Waeber's avatar
Jonas Waeber committed
140
        // + convenience label on the resource directly.
141
        resource.addProperty(RICO.title, langLiteral(input.title_de, "de"))
142 143
        resource.addProperty(RICO.title, langLiteral(input.title_fr, "fr"))
        resource.addProperty(RICO.title, langLiteral(input.title_it, "it"))
144

Jonas Waeber's avatar
Jonas Waeber committed
145
        // 0.2.1 Thumbnail Image
146 147 148
        if (input.computed_teaser_image_url != null)
            resource.addProperty(WD.image, literal(input.computed_teaser_image_url))

Jonas Waeber's avatar
Jonas Waeber committed
149 150 151
        // 1.1 Inhalt
        addRichTextLiteralIfNotNull(
            resource,
152
            listOf(input.field_content_de, input.field_content_fr, input.field_content_it),
Jonas Waeber's avatar
Jonas Waeber committed
153 154 155 156 157
            RICO.scopeAndContent
        )

        // 1.2 Entstehungszeitraum
        // is expected to always be a normalized value YYYY/YYYY.
Jonas Waeber's avatar
Jonas Waeber committed
158 159 160 161 162 163 164 165
        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
166 167 168 169 170 171 172 173
        // 1.3 Sprache
        addLiteralIfNotNull(
            resource,
            listOf(input.field_language_de, input.field_language_fr, input.field_language_it),
            RDA.hasLanguageOfResource
        )

        // 1.4 Zugang Memobase
174
        addRichTextLiteralIfNotNull(
Jonas Waeber's avatar
Jonas Waeber committed
175
            resource,
176
            listOf(input.field_access_memobase_de, input.field_access_memobase_fr, input.field_access_memobase_it),
Jonas Waeber's avatar
Jonas Waeber committed
177
            RDA.hasRestrictionOnAccess
Jonas Waeber's avatar
Jonas Waeber committed
178 179 180 181
        )
        // 2.1 Kontext
        addRichTextLiteralIfNotNull(
            resource,
182
            listOf(input.field_context_de, input.field_context_fr, input.field_context_it),
Jonas Waeber's avatar
Jonas Waeber committed
183 184 185 186 187 188 189
            RICO.history
        )
        // 3.1 Titel
        // Originaltitle des Bestandes
        addTitle(
            resource,
            model,
190
            Types.Title.original,
191
            listOf(input.field_original_title_de, input.field_original_title_fr, input.field_original_title_it)
Jonas Waeber's avatar
Jonas Waeber committed
192 193 194 195
        )
        // 3.2 Umfang -> recordResourceExtent
        addRichTextLiteralIfNotNull(
            resource,
196
            listOf(input.field_scope_de, input.field_scope_fr, input.field_scope_it),
Jonas Waeber's avatar
Jonas Waeber committed
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
            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) {
232
                resource.addProperty(RICO.identifiedBy, addIdentifier(model, Types.Identifier.original, it))
Jonas Waeber's avatar
Jonas Waeber committed
233 234 235 236 237
            }
        }
        // 3.8 Original Signatur
        input.field_original_shelf_mark.let {
            if (it != null) {
238
                resource.addProperty(RICO.identifiedBy, addIdentifier(model, Types.Identifier.callNumber, it))
Jonas Waeber's avatar
Jonas Waeber committed
239 240
            }
        }
Jonas Waeber's avatar
Jonas Waeber committed
241 242
        // 3.9 Original Beschreibung (Text)
        // 3.9.1 Original Beschreibung (Link)
Jonas Waeber's avatar
Jonas Waeber committed
243 244 245 246
        addOriginalRecordSetLink(
            model,
            resource,
            listOf(
247
                input.field_original_description_de,
Jonas Waeber's avatar
Jonas Waeber committed
248 249 250 251 252 253
                input.field_original_description_fr,
                input.field_original_description_it
            )
        )

        // 4.1 Zugang
254
        addRichTextLiteralIfNotNull(
Jonas Waeber's avatar
Jonas Waeber committed
255
            resource,
256
            listOf(input.field_access_de, input.field_access_fr, input.field_access_it),
Jonas Waeber's avatar
Jonas Waeber committed
257 258 259
            RICO.conditionsOfAccess
        )
        // 4.2 Zuständige Institution (Original)
260
        addRelatedInstitution(model, resource, Types.CorporateBody.original, input.field_resp_institution_original)
Jonas Waeber's avatar
Jonas Waeber committed
261
        // 4.3 Zuständige Institution (Master)
262
        addRelatedInstitution(model, resource, Types.CorporateBody.master, input.field_resp_institution_master)
Jonas Waeber's avatar
Jonas Waeber committed
263
        // 4.4 Zuständige Institution (Access)
264
        addRelatedInstitution(model, resource, Types.CorporateBody.access, input.field_resp_institution_access)
Jonas Waeber's avatar
Jonas Waeber committed
265

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

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

430 431 432
    private fun addMemoriavProject(resource: Resource, model: Model, link: Link, language: String) {
        val node = model.createResource()
        node.addProperty(RDF.type, RICO.CorporateBody)
433
        node.addProperty(RICO.type, Types.CorporateBody.memoriavProject)
434 435 436 437 438 439 440
        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
441

442 443 444 445 446 447 448
    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))
        }
449
        node.addProperty(RICO.type, literal(Types.RecordSet.related))
450 451 452
        node.addProperty(SCHEMA.sameAs, literal(link.uri))
        resource.addProperty(RICO.isRecordResourceAssociatedWithRecordResource, node)
    }
Jonas Waeber's avatar
Jonas Waeber committed
453 454 455 456 457 458 459 460 461

    private fun addRelatedRecord(
        resource: Resource,
        model: Model,
        link: Link,
        language: String,
        property: Property,
        type: String
    ) {
462 463 464 465 466 467
        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))
        }
468
        node.addProperty(RICO.type, literal(type))
469 470 471 472
        node.addProperty(SCHEMA.sameAs, literal(link.uri))
        resource.addProperty(property, node)
    }

473 474
    private fun generateLocationResource(model: Model, address: Address): Resource {
        val location = model.createResource()
475

Jonas Waeber's avatar
Jonas Waeber committed
476 477 478 479 480 481
        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
482
        }
Jonas Waeber's avatar
Jonas Waeber committed
483 484 485 486 487 488
        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
489

Jonas Waeber's avatar
Jonas Waeber committed
490
        val postalCode = address.postal_code.trim()
Jonas Waeber's avatar
Jonas Waeber committed
491

492
        location.addProperty(RDF.type, RICO.Place)
Jonas Waeber's avatar
Jonas Waeber committed
493
        location.addProperty(WD.postalCode, literal(postalCode))
Jonas Waeber's avatar
Jonas Waeber committed
494 495 496

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

497
        val canton = model.createResource()
Jonas Waeber's avatar
Jonas Waeber committed
498 499 500 501 502 503 504 505 506 507 508 509 510
        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"))
            }
511
            canton.addProperty(RICO.type, literal("canton"))
Jonas Waeber's avatar
Jonas Waeber committed
512 513
        }

514
        val municipality = model.createResource()
Jonas Waeber's avatar
Jonas Waeber committed
515 516 517 518 519 520 521 522 523 524
        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
525
            }
526
            municipality.addProperty(RICO.type, "municipality")
Jonas Waeber's avatar
Jonas Waeber committed
527 528 529
        }
        // country is currently hard coded to switzerland!
        location.addProperty(WD.country, WD.switzerland)
Jonas Waeber's avatar
Jonas Waeber committed
530 531 532
        return location
    }

Jonas Waeber's avatar
Jonas Waeber committed
533 534
    private fun langLiteral(text: String, language: String): Literal =
        ResourceFactory.createLangLiteral(text.trim(), language)
535

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

Jonas Waeber's avatar
Jonas Waeber committed
538 539 540 541
    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)))
542 543
        }
    }
Jonas Waeber's avatar
Jonas Waeber committed
544

Jonas Waeber's avatar
Jonas Waeber committed
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 574 575 576 577 578 579 580 581 582 583 584
    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)
585
            node.addProperty(RICO.recordResourceHoldingRelationHasSource, NS.mbcb + it)
Jonas Waeber's avatar
Jonas Waeber committed
586
            resource.addProperty(RICO.recordResourceOrInstantiationIsTargetOfRecordResourceHoldingRelation, node)
Jonas Waeber's avatar
Jonas Waeber committed
587 588
        }
    }
Jonas Waeber's avatar
Jonas Waeber committed
589
}