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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)

### Changed

- Cleaned, standardized and extended content preview in mapping/report files
- More robust table fingerprint used for mapping

### Fixed

## [17.0.26] - 2026-07-09
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,66 +103,7 @@ static String buildArea(Migration migration, Number idx, Area area, DocumentObje
builder.append(Csv.serialize(area.position.width) + ",")
builder.append(Csv.serialize(area.position.height) + ",")

builder.append(Csv.serialize(buildContentPreview(migration, area.content)))
return builder.toString()
}

static String buildContentPreview(Migration migration, List<DocumentContent> content) {
def documentObjectIdsToNames = getDocumentObjectIdsToNames(migration, content)
def imageIdsToNames = getImageIdsToNames(migration, content)

def previewParts = content.collect {
switch (it) {
case DocumentObjectRef:
def name = documentObjectIdsToNames.get(it.id)
return name ? "DocObjRef($name)" : "DocObjRef(${it.id})"
case ImageRef:
def name = imageIdsToNames.get(it.id)
return name ? "ImageRef($name)" : "ImageRef(${it.id})"
default:
return it.toString()
}
}

if (previewParts.size() > 3) {
previewParts = previewParts.take(3) + ("(+${previewParts.size() - 3} more)" as String)
}

return previewParts.join(";").replace(",", " ")
}

static HashMap<String, String> getDocumentObjectIdsToNames(Migration migration, List<DocumentContent> content) {
def idsToNames = new HashMap<String, String>()

def refIds = content.findAll { it instanceof DocumentObjectRef }.collect { (it as Ref).id }
refIds.each {
def documentObject = migration.documentObjectRepository.find(it)
if (documentObject == null) {
throw new IllegalStateException("Document object '$it' not found.")
}
builder.append(Csv.serialize(migration.previewProvider.buildDocumentContentListPreview(area.content)))

if (documentObject.name != null) {
idsToNames[it] = documentObject.name
}
}

return idsToNames
}

static HashMap<String, String> getImageIdsToNames(Migration migration, List<DocumentContent> content) {
def idsToNames = new HashMap<String, String>()

def refIds = content.findAll { it instanceof ImageRef }.collect { (it as Ref).id }
refIds.each {
def image = migration.imageRepository.find(it)
if (image == null) {
throw new IllegalStateException("Image '$it' not found.")
}

if (image.name != null) {
idsToNames[it] = image.name
}
}

return idsToNames
return builder.toString()
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ import com.quadient.migration.api.repository.DocumentObjectRepository
import com.quadient.migration.example.common.util.Csv
import com.quadient.migration.example.common.util.Mapping
import com.quadient.migration.service.DocumentTable
import com.quadient.migration.service.PreviewProvider
import groovy.transform.Field

import java.nio.file.Path

import static com.quadient.migration.example.common.util.InitMigration.initMigration
import static com.quadient.migration.service.TableUtilKt.*
import static com.quadient.migration.service.TableUtilKt.collectDocumentTables

@Field Migration migration = initMigration(this.binding)

Expand Down Expand Up @@ -47,21 +48,21 @@ static void run(Migration migration, Path path) {
documentObjects.each { docObj ->
def documentTables = collectDocumentTables(docObj.content)
documentTables.each { docTable ->
writer.writeLine(buildRow(docObj.id, docObj.name, docTable))
writer.writeLine(buildRow(docObj.id, docObj.name, docTable, migration.previewProvider))
}
}
}
}

static String buildRow(String docObjId, String docObjName, DocumentTable docTable) {
static String buildRow(String docObjId, String docObjName, DocumentTable docTable, PreviewProvider previewProvider) {
def contentPath = docTable.contentPath
def table = docTable.table

def builder = new StringBuilder()
builder.append(Csv.serialize(docObjId) + ",")
builder.append(Csv.serialize(docObjName) + ",")
builder.append(Csv.serialize(contentPath) + ",")
builder.append(Csv.serialize(buildContentPreview(table)) + ",")
builder.append(Csv.serialize(previewProvider.getPreview(table)) + ",")
builder.append(Csv.serialize(table.name) + ",")
builder.append(Csv.serialize(table.pdfTaggingRule) + ",")
builder.append(Csv.serialize(table.pdfAlternateText) + ",")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import java.nio.file.Path

import static com.quadient.migration.example.common.util.InitMigration.initMigration
import static com.quadient.migration.service.TableUtilKt.collectDocumentTables
import static com.quadient.migration.service.TableUtilKt.computeFingerprint

@Field static Logger log = LoggerFactory.getLogger(this.class.name)

Expand Down Expand Up @@ -70,7 +69,7 @@ static void run(Migration migration, Path path) {
continue
}

def fingerprint = computeFingerprint(docTable.table)
def fingerprint = docTable.table.computeFingerprint()

def entry = new MappingItem.Table.TableEntry(
contentPath,
Expand Down
2 changes: 1 addition & 1 deletion migration-examples/src/test/groovy/AreasExportTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class AreasExportTest {

def expected = """\
templateId,templateName (read-only),pageId,pageName (read-only),pageWidth (read-only),pageHeight (read-only),interactiveFlowName,flowToNextPage,x (read-only),y (read-only),width (read-only),height (read-only),contentPreview (read-only)
,,page with preview,,,,test flow,false,0mm,0mm,0mm,0mm,DocObjRef(Block One);ImageRef(Image One);DocObjRef(Block Two);(+2 more)
,,page with preview,,,,test flow,false,0mm,0mm,0mm,0mm,docRef: Block One;imageRef: Image One;docRef: Block Two;(+2 more)
""".stripIndent()
Assertions.assertEquals(expected, mappingFile.toFile().text.replaceAll("\\r\\n|\\r", "\n"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ class TablesMappingExportTest {

def expected = """\
documentObjectId,documentObjectName (read-only),tableId,contentPreview (read-only),tableName,pdfTaggingRule,pdfAlternateText,action
doc1,My Doc,table:0,0 cols | 0 body rows,First,Default,,Keep
doc1,My Doc,table:1,0 cols | 0 body rows,Second,Table,Alt text,Flatten
doc1,My Doc,table:0,table: 0 cols | 0 body rows,First,Default,,Keep
doc1,My Doc,table:1,table: 0 cols | 0 body rows,Second,Table,Alt text,Flatten
""".stripIndent()
Assertions.assertEquals(expected, mappingFile.toFile().text.replaceAll("\\r\\n|\\r", "\n"))
}
Expand All @@ -57,8 +57,8 @@ class TablesMappingExportTest {

def expected = """\
documentObjectId,documentObjectName (read-only),tableId,contentPreview (read-only),tableName,pdfTaggingRule,pdfAlternateText,action
doc1,First Doc,table:0,0 cols | 0 body rows,T1,Default,,Keep
doc2,Second Doc,table:0,0 cols | 0 body rows,T2,Default,,Keep
doc1,First Doc,table:0,table: 0 cols | 0 body rows,T1,Default,,Keep
doc2,Second Doc,table:0,table: 0 cols | 0 body rows,T2,Default,,Keep
""".stripIndent()
Assertions.assertEquals(expected, mappingFile.toFile().text.replaceAll("\\r\\n|\\r", "\n"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import org.junit.jupiter.api.io.TempDir
import java.nio.file.Path
import java.nio.file.Paths

import static com.quadient.migration.service.TableUtilKt.computeFingerprint
import static org.mockito.Mockito.verify
import static org.mockito.Mockito.when

Expand Down Expand Up @@ -40,11 +39,11 @@ class TablesMappingImportTest {

verify(migration.mappingRepository).upsertBatch([
"doc1": new MappingItem.Table(null, [
new MappingItem.Table.TableEntry("table:0", TableAction.Keep, TablePdfTaggingRule.Table, "Alt text", computeFingerprint(table10), "TableOne"),
new MappingItem.Table.TableEntry("table:1", TableAction.Keep, null, null, computeFingerprint(table11), null)
new MappingItem.Table.TableEntry("table:0", TableAction.Keep, TablePdfTaggingRule.Table, "Alt text", table10.computeFingerprint(), "TableOne"),
new MappingItem.Table.TableEntry("table:1", TableAction.Keep, null, null, table11.computeFingerprint(), null)
]),
"doc2": new MappingItem.Table(null, [
new MappingItem.Table.TableEntry("table:0", TableAction.Flatten, TablePdfTaggingRule.Table, "Alt", computeFingerprint(table20), "TableTwo")
new MappingItem.Table.TableEntry("table:0", TableAction.Flatten, TablePdfTaggingRule.Table, "Alt", table20.computeFingerprint(), "TableTwo")
])
])
}
Expand Down
4 changes: 4 additions & 0 deletions migration-examples/src/test/groovy/Utils.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.quadient.migration.api.repository.StatusTrackingRepository
import com.quadient.migration.api.repository.TextStyleRepository
import com.quadient.migration.api.repository.VariableRepository
import com.quadient.migration.api.repository.VariableStructureRepository
import com.quadient.migration.service.PreviewProvider

import static org.mockito.Mockito.mock
import static org.mockito.Mockito.when
Expand Down Expand Up @@ -45,5 +46,8 @@ static Migration mockMigration() {
when(migration.getMappingRepository()).thenReturn(mappingRepo)
when(migration.getDisplayRuleRepository()).thenReturn(displayRuleRepo)

def previewProvider = new PreviewProvider(docObjectRepo, imageRepo, attachmentRepo, varRepo)
when(migration.getPreviewProvider()).thenReturn(previewProvider)

return migration
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.quadient.migration.service.IcmDataCache
import com.quadient.migration.service.inspirebuilder.InteractiveDocumentObjectBuilder
import com.quadient.migration.service.InteractiveIcmDataCache
import com.quadient.migration.service.InteractiveResourcePathProvider
import com.quadient.migration.service.PreviewProvider
import com.quadient.migration.service.ResourcePathProvider
import com.quadient.migration.service.deploy.utility.ConflictDetectorImpl
import com.quadient.migration.service.deploy.utility.ProgressReporterImpl
Expand Down Expand Up @@ -110,6 +111,7 @@ class Migration(val config: MigConfig, val projectConfig: ProjectConfig) {
singleOf(::ReferenceValidator)
singleOf(::StylesValidator)
singleOf(::RefCollector)
singleOf(::PreviewProvider)
}

private val koinApp: KoinApplication = koinApplication {
Expand Down Expand Up @@ -137,6 +139,7 @@ class Migration(val config: MigConfig, val projectConfig: ProjectConfig) {
val stylesValidator: StylesValidator by lazy { koin.get() }
val referenceCollector: RefCollector by lazy { koin.get() }
val pathProvider: ResourcePathProvider by lazy { koin.get() }
val previewProvider: PreviewProvider by lazy { koin.get() }
val storage: Storage by lazy { koin.get() }

private val ipsService: IpsService by lazy { koin.get() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ sealed interface TextContent {

data class DocumentObjectRef(override val id: String, val displayRuleRef: DisplayRuleRef? = null) : Ref(id),
DocumentContent, TextContent, RefValidatable {
override val pathName = "docRef"

override fun toPreview(nameResolver: (DocumentContent) -> String?): String =
"$pathName: ${nameResolver(this) ?: id}"

constructor(id: String) : this(id, null)

Expand All @@ -65,6 +69,9 @@ data class DocumentObjectRef(override val id: String, val displayRuleRef: Displa
}

data class VariableRef(override val id: String) : Ref(id), VariableStringContent, RefValidatable {
override val pathName = "varRef"
override fun toPreview(nameResolver: (DocumentContent) -> String?): String =
"$${nameResolver(this) ?: id}$"
override fun collectRefs(): List<Ref> = listOf(this)

companion object {
Expand Down Expand Up @@ -104,6 +111,10 @@ sealed class ResourceRef(override val id: String) : Ref(id), DocumentContent, Te
}

data class ImageRef(override val id: String) : ResourceRef(id) {
override val pathName = "imageRef"
override fun toPreview(nameResolver: (DocumentContent) -> String?): String =
"imageRef: ${nameResolver(this) ?: id}"

companion object {
fun fromDb(entity: ImageEntityRef) = ImageRef(entity.id)
}
Expand All @@ -112,6 +123,10 @@ data class ImageRef(override val id: String) : ResourceRef(id) {
}

data class AttachmentRef(override val id: String) : ResourceRef(id) {
override val pathName = "attachRef"
override fun toPreview(nameResolver: (DocumentContent) -> String?): String =
"$pathName: ${nameResolver(this) ?: id}"

companion object {
fun fromDb(entity: AttachmentEntityRef) = AttachmentRef(entity.id)
}
Expand All @@ -124,6 +139,10 @@ data class VariableStructureRef(override val id: String) : Ref(id) {
}

data class StringValue(val value: String) : VariableStringContent {
override val pathName = "str"
override fun toPreview(nameResolver: (DocumentContent) -> String?): String =
value.replace('\r', ' ').replace('\n', ' ').take(30)

companion object {
fun fromDb(entity: StringEntity) = StringValue(entity.value)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import com.quadient.migration.shared.Position

data class Area(var content: List<DocumentContent>, var position: Position?, var interactiveFlowName: String?, var flowToNextPage: Boolean = false) :
DocumentContent, RefValidatable {
val pathName: String get() = "area"

override val pathName = "area"

override fun toPreview(nameResolver: (DocumentContent) -> String?): String =
"$pathName: ${content.size} items"

constructor(content: List<DocumentContent>, position: Position?, interactiveFlowName: String?) : this(content, position, interactiveFlowName, false)
override fun collectRefs(): List<Ref> {
return content.flatMap {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ sealed interface Barcode : DocumentContent, TextContent {
val backgroundFill: Color?
val variableRef: VariableRef?

override fun toPreview(nameResolver: (DocumentContent) -> String?): String {
val label = data?.take(30) ?: variableRef?.toPreview(nameResolver)
return if (label != null) "$pathName: $label" else pathName
}

companion object {
fun fromDb(entity: BarcodeEntity): Barcode = when (entity) {
is QrCodeEntity -> QrCode.fromDb(entity)
Expand All @@ -37,6 +42,7 @@ data class QrCode(
val moduleWidth: Size,
val quiteZone: Size,
): Barcode {
override val pathName = "qrCode"

companion object {
fun fromDb(entity: QrCodeEntity): QrCode = QrCode(
Expand Down Expand Up @@ -83,6 +89,7 @@ data class Code39Barcode(
val firstBarSpace: Size,
val secondBarSpace: Size,
) : Barcode {
override val pathName = "code39Barcode"

companion object {
fun fromDb(entity: Code39BarcodeEntity): Code39Barcode = Code39Barcode(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ data class ColumnLayout(
val balancingType: ColumnBalancingType? = null,
val applyTo: ColumnApplyTo? = null,
) : DocumentContent, TextContent {
override val pathName = "columnLayout"

override fun toPreview(nameResolver: (DocumentContent) -> String?): String = "$pathName: $numberOfColumns cols"

companion object {
fun fromDb(entity: ColumnLayoutEntity): ColumnLayout = ColumnLayout(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import com.quadient.migration.persistence.migrationmodel.RepeatedContentEntity
import com.quadient.migration.persistence.migrationmodel.VariableStringContentEntity

sealed interface DocumentContent {
val pathName: String
fun toPreview(nameResolver: (DocumentContent) -> String?): String
fun toPreview(): String = toPreview { null }

companion object {
fun fromDbContent(entity: DocumentContentEntity): DocumentContent = when (entity) {
is TableEntity -> Table.fromDb(entity)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package com.quadient.migration.api.dto.migrationmodel
import com.quadient.migration.persistence.migrationmodel.FirstMatchEntity

data class FirstMatch(val cases: List<Case>, val default: List<DocumentContent>) : DocumentContent, TextContent, RefValidatable {
val pathName: String get() = "firstMatch"
override val pathName = "firstMatch"

override fun toPreview(nameResolver: (DocumentContent) -> String?): String = "$pathName: ${cases.size} cases"

override fun collectRefs(): List<Ref> {
return cases.flatMap { it.collectRefs() } + default.flatMap {
when (it) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ data class Paragraph(
val styleRef: ParagraphStyleRef?,
val displayRuleRef: DisplayRuleRef?
) : DocumentContent, RefValidatable {
override val pathName = "par"
override fun toPreview(nameResolver: (DocumentContent) -> String?): String {
val preview = content.flatMap { it.content }.joinToString("") {
when (it) {
is DocumentContent -> it.toPreview(nameResolver)
is Hyperlink -> it.displayText ?: it.url
}
}.replace('\r', ' ').replace('\n', ' ').take(50)
return "$pathName: $preview"
}

override fun collectRefs(): List<Ref> {
return content.flatMap { it.collectRefs() } + listOfNotNull(styleRef, displayRuleRef)
}
Expand Down
Loading
Loading