Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)

- Border configuration options to tables
- Option to add list of rows to table and list of cells to table row in their respective builders
- Support for document object pdf tagging/accessibility metadata

### Changed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ class Stats {
this.id = obj.id
this.collectContent(obj.content)
this.collectDisplayRule(obj.displayRuleRef)

if (obj.pdfMetadata != null) {
obj.pdfMetadata.collectRefs().each { this.usedVariables.add(it.id) }
}

return this
}

Expand Down Expand Up @@ -235,6 +240,7 @@ class Stats {
def dependency = migration.documentObjectRepository.find(ref.id)
if (dependency.internal) {
this.usedInternalObjects.add(ref.id)
this.collectDisplayRule(dependency.displayRuleRef)
this.collectContent(dependency.content)
} else {
if (this.usageMap[ref.id] == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package com.quadient.migration.example.example
import com.quadient.migration.api.Migration
import com.quadient.migration.api.dto.migrationmodel.DisplayRuleRef
import com.quadient.migration.api.dto.migrationmodel.ParagraphStyleRef
import com.quadient.migration.api.dto.migrationmodel.VariableRef
import com.quadient.migration.api.dto.migrationmodel.builder.AttachmentBuilder
import com.quadient.migration.api.dto.migrationmodel.builder.DisplayRuleBuilder
import com.quadient.migration.api.dto.migrationmodel.builder.DocumentObjectBuilder
Expand Down Expand Up @@ -473,6 +474,13 @@ def page = new DocumentObjectBuilder("page1", DocumentObjectType.Page)
def template = new DocumentObjectBuilder("template", DocumentObjectType.Template)
.documentObjectRef(page.id)
.subject("Document example template")
.pdfMetadata {
it.author(new VariableRef(nameVariable.id))
it.title("Migration Model Example Template")
it.producer("Quadient")
it.keywords("Migration, Model, Example, Test, Import")
it.subject { it.string("Lorem ipsum dolor sit amet from: ").variableRef(cityVariable.id) }
}
.variableStructureRef(variableStructure.id)
.build()

Expand Down
27 changes: 17 additions & 10 deletions migration-examples/src/test/groovy/AreasExportTest.groovy
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import com.quadient.migration.api.Migration
import com.quadient.migration.api.dto.migrationmodel.*
import com.quadient.migration.api.dto.migrationmodel.builder.DocumentObjectBuilder
import com.quadient.migration.api.dto.migrationmodel.builder.documentcontent.AreaBuilder
import com.quadient.migration.api.repository.DocumentObjectRepository
import com.quadient.migration.example.common.mapping.AreasExport
import com.quadient.migration.shared.DocumentObjectType
import com.quadient.migration.shared.Position
import com.quadient.migration.shared.Size
import com.quadient.migration.shared.SkipOptions
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
Expand Down Expand Up @@ -33,10 +34,12 @@ class AreasExportTest {
Path mappingFile = Paths.get(dir.path, "testProject.csv")
when(migration.mappingRepository.getAreaMapping(any())).thenReturn(new MappingItem.Area(null, [:], [:]))
when((migration.documentObjectRepository as DocumentObjectRepository).list(any())).thenReturn([
new DocumentObject("empty tmpl", null, [], new CustomFieldMap([:]), DocumentObjectType.Template, [], false, null, null, null, null, null, null, null, [:], emptySkipOptions(), null),
new DocumentObject("unreferenced page", null, [], new CustomFieldMap([:]), DocumentObjectType.Page, [createArea("test flow", true)], false, null, null, null, null, null, null, null, [:], emptySkipOptions(), null),
new DocumentObject("full tmpl", null, [], new CustomFieldMap([:]), DocumentObjectType.Template, [new DocumentObjectRef("full page")], false, null, null, null, null, null, null, null, [:], emptySkipOptions(), null),
new DocumentObject("full page", null, [], new CustomFieldMap([:]), DocumentObjectType.Page, [createArea("test flow2"), createArea("test flow3", true), createArea(null), createArea("test flow5")], false, null, null, null, null, null, null, null, [:], emptySkipOptions(), null),
new DocumentObjectBuilder("empty tmpl", DocumentObjectType.Template).build(),
new DocumentObjectBuilder("unreferenced page", DocumentObjectType.Page).content([createArea("test flow", true)]).build(),
new DocumentObjectBuilder("full tmpl", DocumentObjectType.Template).documentObjectRef("full page").build(),
new DocumentObjectBuilder("full page", DocumentObjectType.Page)
.content([createArea("test flow2"), createArea("test flow3", true), createArea(null), createArea("test flow5")])
.build(),
])

AreasExport.run(migration, mappingFile)
Expand All @@ -53,10 +56,14 @@ class AreasExportTest {
}

static Area createArea(String flowName, Boolean flowToNextPage = false) {
return new Area([], new Position(Size.ofMillimeters(0), Size.ofMillimeters(0), Size.ofMillimeters(0), Size.ofMillimeters(0)), flowName, flowToNextPage)
}
def areaBuilder = new AreaBuilder()
.position(new Position(Size.ofMillimeters(0), Size.ofMillimeters(0), Size.ofMillimeters(0), Size.ofMillimeters(0)))
.flowToNextPage(flowToNextPage)

if (flowName != null) {
areaBuilder.interactiveFlowName(flowName)
}

static SkipOptions emptySkipOptions() {
return new SkipOptions(false, null, null)
return areaBuilder.build()
}
}
}
18 changes: 13 additions & 5 deletions migration-examples/src/test/groovy/AreasImportTest.groovy
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import com.quadient.migration.api.Migration
import com.quadient.migration.api.dto.migrationmodel.*
import com.quadient.migration.api.dto.migrationmodel.builder.DocumentObjectBuilder
import com.quadient.migration.api.dto.migrationmodel.builder.documentcontent.AreaBuilder
import com.quadient.migration.example.common.mapping.AreasImport
import com.quadient.migration.shared.DocumentObjectType
import com.quadient.migration.shared.Position
import com.quadient.migration.shared.Size
import com.quadient.migration.shared.SkipOptions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir
Expand Down Expand Up @@ -63,14 +64,21 @@ class AreasImportTest {
}

static Area createArea(String flowName, boolean flowToNextPage) {
return new Area([], new Position(Size.ofMillimeters(0), Size.ofMillimeters(0), Size.ofMillimeters(0), Size.ofMillimeters(0)), flowName, flowToNextPage)
def areaBuilder = new AreaBuilder()
.position(new Position(Size.ofMillimeters(0), Size.ofMillimeters(0), Size.ofMillimeters(0), Size.ofMillimeters(0)))
.flowToNextPage(flowToNextPage)

if (flowName != null) {
areaBuilder.interactiveFlowName(flowName)
}

return areaBuilder.build()
}

void givenPageExists(String pageId, List<String> flowNames, List<Boolean> flowToNextPageValues = null) {
def values = flowToNextPageValues ?: flowNames.collect { false }
def content = [flowNames, values].transpose()
.collect { String flowName, Boolean flowToNextPage -> createArea(flowName, flowToNextPage) }
when(migration.documentObjectRepository.find(pageId))
.thenReturn(new DocumentObject(pageId, null, [], new CustomFieldMap([:]), DocumentObjectType.Page, content, false, null, null, null, null, null, null, null, [:], new SkipOptions(false, null, null), null))
when(migration.documentObjectRepository.find(pageId)).thenReturn(new DocumentObjectBuilder(pageId, DocumentObjectType.Page).content(content).build())
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import com.quadient.migration.api.dto.migrationmodel.CustomFieldMap
import com.quadient.migration.api.dto.migrationmodel.DocumentObject
import com.quadient.migration.api.dto.migrationmodel.VariableStructureRef
import com.quadient.migration.api.dto.migrationmodel.builder.DocumentObjectBuilder
import com.quadient.migration.data.Active
import com.quadient.migration.example.common.mapping.DocumentObjectsExport
import com.quadient.migration.shared.DocumentObjectType
import com.quadient.migration.shared.SkipOptions
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.io.TempDir
import java.nio.file.Path
Expand All @@ -23,11 +20,25 @@ class DocumentObjectsMappingExportTest {
def migration = Utils.mockMigration()

when(migration.documentObjectRepository.listAll()).thenReturn([
new DocumentObject("empty", null, [], new CustomFieldMap([:]), DocumentObjectType.Block, [], false, null, null, null, null, null, null, null, [:], emptySkipOptions(), null),
new DocumentObject("should not be listed because internal", null, [], new CustomFieldMap([:]), DocumentObjectType.Block, [], true, null, null, null, null, null, null, null, [:], emptySkipOptions(), null),
new DocumentObject("full", "full", ["foo", "bar"], new CustomFieldMap([:]), DocumentObjectType.Page, [], false, "someDir", null, new VariableStructureRef("struct"), "tmpl.wfd", null, null, null, [:], new SkipOptions(true, "placeholder", "reason"), null),
new DocumentObject("overridden empty", null, [], new CustomFieldMap([:]), DocumentObjectType.Block, [], false, null, null, null, null, null, null, null, [:], emptySkipOptions(), null),
new DocumentObject("overridden full", "full", ["foo", "bar"], new CustomFieldMap(["originalName": "originalFull"]), DocumentObjectType.Page, [], false, "someDir", null, new VariableStructureRef("struct"), "tmpl.wfd", null, null, null, [:], emptySkipOptions(), null),
new DocumentObjectBuilder("empty", DocumentObjectType.Block).build(),
new DocumentObjectBuilder("should not be listed because internal", DocumentObjectType.Block).internal(true).build(),
new DocumentObjectBuilder("full", DocumentObjectType.Page)
.name("full")
.originLocations(["foo", "bar"])
.targetFolder("someDir")
.variableStructureRef("struct")
.baseTemplate("tmpl.wfd")
.skip("placeholder", "reason")
.build(),
new DocumentObjectBuilder("overridden empty", DocumentObjectType.Block).build(),
new DocumentObjectBuilder("overridden full", DocumentObjectType.Page)
.name("full")
.originLocations(["foo", "bar"])
.customFields(["originalName": "originalFull"])
.targetFolder("someDir")
.variableStructureRef("struct")
.baseTemplate("tmpl.wfd")
.build(),
])

when(migration.statusTrackingRepository.findLastEventRelevantToOutput(any(), any(), any())).thenReturn(new Active())
Expand All @@ -43,8 +54,4 @@ class DocumentObjectsMappingExportTest {
""".stripIndent()
Assertions.assertEquals(expected, mappingFile.toFile().text.replaceAll("\\r\\n|\\r", "\n"))
}

static SkipOptions emptySkipOptions() {
return new SkipOptions(false, null, null)
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import com.quadient.migration.api.Migration
import com.quadient.migration.api.dto.migrationmodel.CustomFieldMap
import com.quadient.migration.api.dto.migrationmodel.DocumentObject
import com.quadient.migration.api.dto.migrationmodel.MappingItem
import com.quadient.migration.api.dto.migrationmodel.VariableStructureRef
import com.quadient.migration.api.dto.migrationmodel.builder.DocumentObjectBuilder
import com.quadient.migration.example.common.mapping.DocumentObjectsImport
import com.quadient.migration.shared.DocumentObjectType
import com.quadient.migration.shared.SkipOptions
Expand Down Expand Up @@ -214,7 +212,24 @@ class DocumentObjectsMappingImportTest {
}

static void givenExistingDocumentObject(Migration mig, String id, String name, Boolean internal, String baseTemplate, String targetFolder, DocumentObjectType type, String varStructureRef) {
when(mig.documentObjectRepository.find(id)).thenReturn(new DocumentObject(id, name, [], new CustomFieldMap([:]), type ?: DocumentObjectType.Block, [], internal, targetFolder, null, varStructureRef ? new VariableStructureRef(varStructureRef) : null, baseTemplate, null, null, null, [:], new SkipOptions(false, null, null), null))
def builder = new DocumentObjectBuilder(id, type ?: DocumentObjectType.Block)
if (name != null) {
builder.name(name)
}
if (internal != null) {
builder.internal(internal)
}
if (targetFolder != null) {
builder.targetFolder(targetFolder)
}
if (varStructureRef != null) {
builder.variableStructureRef(varStructureRef)
}
if (baseTemplate != null) {
builder.baseTemplate(baseTemplate)
}

when(mig.documentObjectRepository.find(id)).thenReturn(builder.build())
}

static void givenExistingDocumentObjectMapping(Migration mig,
Expand All @@ -228,4 +243,4 @@ class DocumentObjectsMappingImportTest {
when(mig.mappingRepository.getDocumentObjectMapping(id))
.thenReturn(new MappingItem.DocumentObject(name, internal, baseTemplate, targetFolder, type, varStructureRef, null))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ data class DocumentObject(
var variableStructureRef: VariableStructureRef? = null,
var baseTemplate: String? = null,
var options: DocumentObjectOptions? = null,
var pdfMetadata: PdfMetadata? = null,
override var created: Instant? = null,
override var lastUpdated: Instant? = null,
val metadata: Map<String, List<MetadataPrimitive>>,
Expand All @@ -32,6 +33,9 @@ data class DocumentObject(
else -> emptyList()
}
}
return contentRefs + listOfNotNull(displayRuleRef, variableStructureRef)

val pdfMetadataRefs = pdfMetadata?.collectRefs().orEmpty()

return contentRefs + pdfMetadataRefs + listOfNotNull(displayRuleRef, variableStructureRef)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.quadient.migration.api.dto.migrationmodel

import com.quadient.migration.persistence.migrationmodel.PdfMetadataEntity

data class PdfMetadata(
val title: List<VariableStringContent>? = null,
val author: List<VariableStringContent>? = null,
val subject: List<VariableStringContent>? = null,
val keywords: List<VariableStringContent>? = null,
val producer: List<VariableStringContent>? = null,
) : RefValidatable {
override fun collectRefs(): List<Ref> {
return listOfNotNull(title, author, subject, keywords, producer).flatten().flatMap { it.collectRefs() }
}

fun toDb(): PdfMetadataEntity = PdfMetadataEntity(
title = title?.map { it.toDb() },
author = author?.map { it.toDb() },
subject = subject?.map { it.toDb() },
keywords = keywords?.map { it.toDb() },
producer = producer?.map { it.toDb() },
)

companion object {
fun fromDb(entity: PdfMetadataEntity): PdfMetadata = PdfMetadata(
title = entity.title?.map { VariableStringContent.fromDb(it) },
author = entity.author?.map { VariableStringContent.fromDb(it) },
subject = entity.subject?.map { VariableStringContent.fromDb(it) },
keywords = entity.keywords?.map { VariableStringContent.fromDb(it) },
producer = entity.producer?.map { VariableStringContent.fromDb(it) },
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ data class DocumentObjectRef(override val id: String, val displayRuleRef: Displa
fun toDb() = DocumentObjectEntityRef(id, displayRuleRef?.toDb())
}

data class VariableRef(override val id: String) : Ref, TextContent, RefValidatable {
data class VariableRef(override val id: String) : Ref, VariableStringContent, RefValidatable {
override fun collectRefs(): List<Ref> = listOf(this)

companion object {
fun fromDb(entity: VariableEntityRef) = VariableRef(entity.id)
}
Expand Down Expand Up @@ -122,10 +124,12 @@ data class VariableStructureRef(override val id: String) : Ref {
fun toDb() = VariableStructureEntityRef(id)
}

data class StringValue(val value: String) : TextContent {
data class StringValue(val value: String) : VariableStringContent {
companion object {
fun fromDb(entity: StringEntity) = StringValue(entity.value)
}

fun toDb() = StringEntity(value)

override fun collectRefs(): List<Ref> = emptyList()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.quadient.migration.api.dto.migrationmodel

import com.quadient.migration.persistence.migrationmodel.StringEntity
import com.quadient.migration.persistence.migrationmodel.VariableEntityRef
import com.quadient.migration.persistence.migrationmodel.VariableStringContentEntity

sealed interface VariableStringContent : TextContent, RefValidatable {
companion object {
fun fromDb(entity: VariableStringContentEntity): VariableStringContent = when (entity) {
is StringEntity -> StringValue.fromDb(entity)
is VariableEntityRef -> VariableRef.fromDb(entity)
}
}
}

fun VariableStringContent.toDb(): VariableStringContentEntity = when (this) {
is StringValue -> this.toDb()
is VariableRef -> this.toDb()
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.quadient.migration.api.dto.migrationmodel.DisplayRuleRef
import com.quadient.migration.api.dto.migrationmodel.DocumentContent
import com.quadient.migration.api.dto.migrationmodel.DocumentObject
import com.quadient.migration.api.dto.migrationmodel.VariableStructureRef
import com.quadient.migration.api.dto.migrationmodel.PdfMetadata
import com.quadient.migration.api.dto.migrationmodel.builder.documentcontent.AreaBuilder
import com.quadient.migration.shared.DocumentObjectOptions
import com.quadient.migration.shared.DocumentObjectType
Expand All @@ -19,6 +20,7 @@ class DocumentObjectBuilder(id: String, private val type: DocumentObjectType) :
private var variableStructureRef: VariableStructureRef? = null
private var baseTemplate: String? = null
private var options: DocumentObjectOptions? = null
private var pdfMetadata: PdfMetadata? = null
private var metadata: MutableMap<String, List<MetadataPrimitive>> = mutableMapOf()
private var skip = false
private var placeholder: String? = null
Expand Down Expand Up @@ -113,6 +115,15 @@ class DocumentObjectBuilder(id: String, private val type: DocumentObjectType) :
this.subject = subject
}

/**
* Set PDF metadata for the document object.
* @param builder Builder function where receiver is a [PdfMetadataBuilder].
* @return This builder instance for method chaining.
*/
fun pdfMetadata(builder: PdfMetadataBuilder.() -> Unit) = apply {
this.pdfMetadata = PdfMetadataBuilder().apply(builder).build()
}

override fun build(): DocumentObject {
return DocumentObject(
id = id,
Expand All @@ -127,9 +138,10 @@ class DocumentObjectBuilder(id: String, private val type: DocumentObjectType) :
variableStructureRef = variableStructureRef,
baseTemplate = baseTemplate,
options = options,
pdfMetadata = pdfMetadata,
metadata = metadata,
skip = SkipOptions(skipped = skip, reason = reason, placeholder = placeholder),
subject = subject,
)
}
}
}
Loading
Loading