From 4eae5c02fc6b035d5a3b8a61ee3ba2ca730253ad Mon Sep 17 00:00:00 2001 From: Michael Gut Date: Thu, 9 Sep 2021 12:50:22 +0200 Subject: [PATCH 1/5] Remove jcenter() and some cleanup --- build.gradle | 7 +++---- couchbase-entity-api/build.gradle | 4 ++-- .../java/kaufland/com/coachbasebinderapi/Comment.kt | 11 ++--------- .../schema/DefaultSchemaValidator.kt | 8 ++++---- couchbase-entity-connector/build.gradle | 2 +- couchbase-entity/build.gradle | 3 +-- .../src/main/java/com/kaufland/ProcessingContext.kt | 3 +-- .../java/com/kaufland/model/mapper/MapifyHolder.kt | 12 +----------- .../mapper/type/MapifyElementTypeGetterSetter.kt | 8 +++++--- .../main/java/com/kaufland/util/ConversionUtil.kt | 3 +-- .../src/test/resources/EntityWithDocId.kt | 2 +- demo/build.gradle | 5 ++--- .../kaufland/com/demo/mapper/DummyMapperSource.kt | 4 +--- 13 files changed, 25 insertions(+), 47 deletions(-) diff --git a/build.gradle b/build.gradle index 6c392819..efcbedfa 100755 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,10 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.3.72' + ext.kotlin_version = '1.5.30' repositories { google() - jcenter() + mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:4.0.0' @@ -19,10 +19,9 @@ allprojects { repositories { google() mavenCentral() - jcenter() maven { url 'https://maven.google.com' } maven { - url "http://mobile.maven.couchbase.com/maven2/dev/" + url "https://mobile.maven.couchbase.com/maven2/dev/" } } } diff --git a/couchbase-entity-api/build.gradle b/couchbase-entity-api/build.gradle index 4ef999b5..0bc4a42b 100644 --- a/couchbase-entity-api/build.gradle +++ b/couchbase-entity-api/build.gradle @@ -23,7 +23,7 @@ artifacts { archives javadocJar } buildscript { - ext.kotlin_version = '1.3.41' + ext.kotlin_version = '1.5.30' repositories { mavenCentral() } @@ -43,4 +43,4 @@ compileTestKotlin { kotlinOptions { jvmTarget = "1.8" } -} \ No newline at end of file +} diff --git a/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/Comment.kt b/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/Comment.kt index ce3fd729..9a12393a 100644 --- a/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/Comment.kt +++ b/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/Comment.kt @@ -1,12 +1,5 @@ package kaufland.com.coachbasebinderapi - -import java.lang.annotation.ElementType -import java.lang.annotation.Retention -import java.lang.annotation.RetentionPolicy -import java.lang.annotation.Target -import kotlin.reflect.KClass - -@Retention(RetentionPolicy.CLASS) -@Target(ElementType.TYPE) +@kotlin.annotation.Retention(AnnotationRetention.BINARY) +@kotlin.annotation.Target annotation class Comment(val comment: Array = []) diff --git a/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/schema/DefaultSchemaValidator.kt b/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/schema/DefaultSchemaValidator.kt index 03ac8eb6..54cd896c 100644 --- a/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/schema/DefaultSchemaValidator.kt +++ b/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/schema/DefaultSchemaValidator.kt @@ -20,7 +20,7 @@ open class DefaultSchemaValidator : SchemaValidator { current?.let { released.docId?.let { - if (current?.docId?.scheme != it.scheme) { + if (current.docId?.scheme != it.scheme) { logger.error(released, "forbidden DocId Schema change") } } @@ -40,7 +40,7 @@ open class DefaultSchemaValidator : SchemaValidator { } protected open fun validateFieldLevel(released: EntitySchema, key: String, logger: SchemaValidationLogger) { - if (released?.deprecatedSchema?.deprecatedFields?.find { it.field == key }?.inUse != false) { + if (released.deprecatedSchema?.deprecatedFields?.find { it.field == key }?.inUse != false) { logger.error(released, "forbidden change on existing field [$key]") } else { logger.info(released, "allowed change on existing field [$key] since it's deprecated and no longer in use") @@ -48,10 +48,10 @@ open class DefaultSchemaValidator : SchemaValidator { } private fun modelDeletedDuringValidDeprecationPeriod(released: EntitySchema, logger: SchemaValidationLogger) { - if (released?.deprecatedSchema == null || released?.deprecatedSchema.inUse) { + if (released.deprecatedSchema == null || released.deprecatedSchema.inUse) { logger.error(released, "forbidden model deletion") } else { logger.error(released, "allowed model deletion") } } -} \ No newline at end of file +} diff --git a/couchbase-entity-connector/build.gradle b/couchbase-entity-connector/build.gradle index 30345c23..79f8bbd4 100644 --- a/couchbase-entity-connector/build.gradle +++ b/couchbase-entity-connector/build.gradle @@ -5,7 +5,7 @@ apply plugin: 'kotlin-android' buildscript { repositories { google() - jcenter() + mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:4.0.0' diff --git a/couchbase-entity/build.gradle b/couchbase-entity/build.gradle index 927c5439..1b92331e 100644 --- a/couchbase-entity/build.gradle +++ b/couchbase-entity/build.gradle @@ -22,7 +22,6 @@ dependencies { kapt "com.google.auto.service:auto-service:1.0-rc7" compileOnly "com.google.auto.service:auto-service:1.0-rc7" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - } targetCompatibility = '1.7' @@ -54,7 +53,7 @@ artifacts { archives javadocJar } buildscript { - ext.kotlin_version = '1.3.41' + ext.kotlin_version = '1.5.30' repositories { mavenCentral() } diff --git a/couchbase-entity/src/main/java/com/kaufland/ProcessingContext.kt b/couchbase-entity/src/main/java/com/kaufland/ProcessingContext.kt index 13b5cf20..7b77eb6e 100644 --- a/couchbase-entity/src/main/java/com/kaufland/ProcessingContext.kt +++ b/couchbase-entity/src/main/java/com/kaufland/ProcessingContext.kt @@ -80,5 +80,4 @@ object ProcessingContext { return createdQualifiedClazzNames.any { it.simpleName == name } && name.let { it.endsWith("Wrapper") || it.endsWith("Entity") } } } - -} \ No newline at end of file +} diff --git a/couchbase-entity/src/main/java/com/kaufland/model/mapper/MapifyHolder.kt b/couchbase-entity/src/main/java/com/kaufland/model/mapper/MapifyHolder.kt index 2b53c29d..9ec85f59 100644 --- a/couchbase-entity/src/main/java/com/kaufland/model/mapper/MapifyHolder.kt +++ b/couchbase-entity/src/main/java/com/kaufland/model/mapper/MapifyHolder.kt @@ -1,23 +1,13 @@ package com.kaufland.model.mapper import com.kaufland.ProcessingContext -import com.kaufland.ProcessingContext.asDeclaringName -import com.kaufland.ProcessingContext.asTypeElement import com.kaufland.ProcessingContext.isAssignable -import com.kaufland.javaToKotlinType import com.kaufland.model.mapper.type.MapifyElementType -import com.kaufland.util.FieldExtractionUtil -import com.squareup.kotlinpoet.TypeName -import com.squareup.kotlinpoet.asTypeName -import kaufland.com.coachbasebinderapi.mapify.Mapify import kaufland.com.coachbasebinderapi.mapify.Mapifyable import kaufland.com.coachbasebinderapi.mapify.Mapper import java.io.Serializable -import java.math.BigDecimal +import java.util.* import javax.annotation.processing.ProcessingEnvironment -import javax.lang.model.element.Element -import javax.lang.model.element.Modifier - class MapifyHolder(val mapifyElement : MapifyElementType, env: ProcessingEnvironment) : MapifyElementType by mapifyElement{ diff --git a/couchbase-entity/src/main/java/com/kaufland/model/mapper/type/MapifyElementTypeGetterSetter.kt b/couchbase-entity/src/main/java/com/kaufland/model/mapper/type/MapifyElementTypeGetterSetter.kt index e1c9e736..b081f437 100644 --- a/couchbase-entity/src/main/java/com/kaufland/model/mapper/type/MapifyElementTypeGetterSetter.kt +++ b/couchbase-entity/src/main/java/com/kaufland/model/mapper/type/MapifyElementTypeGetterSetter.kt @@ -34,13 +34,15 @@ class MapifyElementTypeGetterSetter(val getterSetter: GetterSetter, override val } } - override val elements: Array = arrayOf(getterSetter.getterElement, getterSetter.setterElement).map { it as? Element }?.filterNotNull().toTypedArray() + override val elements: Array = arrayOf(getterSetter.getterElement, getterSetter.setterElement).map { it as? Element } + .filterNotNull() + .toTypedArray() override val mapName = getterSetter.mapify?.name?.let { if(it.isNotBlank()) it else null } ?: fieldName override val typeName = getterSetter.setterElement!!.params()[0]!!.asType().asTypeName().javaToKotlinType() - override val accessible = getterSetter?.let { + override val accessible = getterSetter.let { it.getterElement?.modifiers?.contains(Modifier.PUBLIC) == true && it.setterElement?.modifiers?.contains(Modifier.PUBLIC) == true } ?: false @@ -68,4 +70,4 @@ class MapifyElementTypeGetterSetter(val getterSetter: GetterSetter, override val override fun setterFunSpec(): FunSpec { return FunSpec.setterBuilder().addParameter("value", declaringName.asFullTypeName()!!).addStatement("%N.invoke(this,·value)", getterSetter.setterInternalAccessor()).build() } -} \ No newline at end of file +} diff --git a/couchbase-entity/src/main/java/com/kaufland/util/ConversionUtil.kt b/couchbase-entity/src/main/java/com/kaufland/util/ConversionUtil.kt index 9313846f..d41d946b 100644 --- a/couchbase-entity/src/main/java/com/kaufland/util/ConversionUtil.kt +++ b/couchbase-entity/src/main/java/com/kaufland/util/ConversionUtil.kt @@ -2,7 +2,6 @@ package com.kaufland.util import com.kaufland.javaToKotlinType import com.squareup.kotlinpoet.asTypeName -import java.util.regex.Matcher import java.util.regex.Pattern import javax.lang.model.type.TypeMirror @@ -17,7 +16,7 @@ object ConversionUtil { val sb = StringBuffer() while (m.find()) { - m.appendReplacement(sb, "_" + m.group().toLowerCase()) + m.appendReplacement(sb, "_" + m.group().lowercase()) } m.appendTail(sb) diff --git a/couchbase-entity/src/test/resources/EntityWithDocId.kt b/couchbase-entity/src/test/resources/EntityWithDocId.kt index b05640cf..da4f580b 100644 --- a/couchbase-entity/src/test/resources/EntityWithDocId.kt +++ b/couchbase-entity/src/test/resources/EntityWithDocId.kt @@ -12,4 +12,4 @@ import java.lang.String @DocId("my:%name%:%type%") open class EntityWithDocId { -} \ No newline at end of file +} diff --git a/demo/build.gradle b/demo/build.gradle index 826a0047..d85c8e97 100644 --- a/demo/build.gradle +++ b/demo/build.gradle @@ -1,9 +1,9 @@ buildscript { - ext.kotlin_version = '1.3.72' + ext.kotlin_version = '1.5.30' repositories { google() - jcenter() + mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:4.2.1' @@ -17,7 +17,6 @@ buildscript { apply plugin: 'com.android.application' apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' //TODO enable to localy test plugin diff --git a/demo/src/main/java/kaufland/com/demo/mapper/DummyMapperSource.kt b/demo/src/main/java/kaufland/com/demo/mapper/DummyMapperSource.kt index ec798929..6a01ae99 100644 --- a/demo/src/main/java/kaufland/com/demo/mapper/DummyMapperSource.kt +++ b/demo/src/main/java/kaufland/com/demo/mapper/DummyMapperSource.kt @@ -73,6 +73,4 @@ class DummyMapperSource(simple: String = "test123") { } } - - -} \ No newline at end of file +} From 0fda3ed391f164693542a68bc51ddd4f02dd114e Mon Sep 17 00:00:00 2001 From: Michael Gut Date: Thu, 9 Sep 2021 12:50:35 +0200 Subject: [PATCH 2/5] Test class for Enum --- .../src/test/resources/EntityWithEnum.kt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 couchbase-entity/src/test/resources/EntityWithEnum.kt diff --git a/couchbase-entity/src/test/resources/EntityWithEnum.kt b/couchbase-entity/src/test/resources/EntityWithEnum.kt new file mode 100644 index 00000000..ba246f83 --- /dev/null +++ b/couchbase-entity/src/test/resources/EntityWithEnum.kt @@ -0,0 +1,21 @@ +import kaufland.com.coachbasebinderapi.* +import java.lang.String + + +@Entity(database = "mydb_db") +@Fields( + Field(name = "name", type = String::class), + Field(name = "type", type = String::class, defaultValue = "entityWithQueries", readonly = true), + Field(name = "identifiers", type = String::class, list = true), + Field(name = "process_group", type = ProcessGroup::class, list = true) +) +@DocId("my:%name%:%type%") +open class EntityWithEnum { + +} + +enum class ProcessGroup { + GROUP_1, + GROUP_2, + GROUP_3 +} From 34b6d49f5c6fe19f2ed5721f79f8178b6997de74 Mon Sep 17 00:00:00 2001 From: Sven Braun Date: Mon, 13 Sep 2021 15:49:09 +0200 Subject: [PATCH 3/5] # fix deprecated issue --- .../java/kaufland/com/coachbasebinderapi/Comment.kt | 2 +- .../com/kaufland/model/deprecated/DeprecatedModel.kt | 10 ++++++++++ .../java/com/kaufland/model/field/CblFieldHolder.kt | 2 +- demo/build.gradle | 1 + 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/Comment.kt b/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/Comment.kt index 9a12393a..9d9f171d 100644 --- a/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/Comment.kt +++ b/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/Comment.kt @@ -1,5 +1,5 @@ package kaufland.com.coachbasebinderapi @kotlin.annotation.Retention(AnnotationRetention.BINARY) -@kotlin.annotation.Target +@kotlin.annotation.Target(AnnotationTarget.CLASS) annotation class Comment(val comment: Array = []) diff --git a/couchbase-entity/src/main/java/com/kaufland/model/deprecated/DeprecatedModel.kt b/couchbase-entity/src/main/java/com/kaufland/model/deprecated/DeprecatedModel.kt index 48c1f297..93a275d5 100644 --- a/couchbase-entity/src/main/java/com/kaufland/model/deprecated/DeprecatedModel.kt +++ b/couchbase-entity/src/main/java/com/kaufland/model/deprecated/DeprecatedModel.kt @@ -17,16 +17,26 @@ class DeprecatedModel(deprecated: Deprecated) { val deprecatedFields: Map = deprecated.fields.map { it.field to it }.toMap() + init { + deprecatedFields.forEach { + print("field ${it.key}, value ${it.value.inUse}") + } + } + fun addDeprecated(field: String, spec: PropertySpec.Builder) { deprecatedFields[field]?.let { + print("field ${it.field} inUse ${it.inUse}") spec.addAnnotation(buildDeprecatedAnnotation(it.inUse, it.replacedBy)) } } + fun evaluateFieldDeprecationLevel(field: String) : DeprecationLevel? = deprecatedFields[field]?.let { evaluateDeprecationLevel(it.inUse) } + fun addDeprecated(field: String, spec: FunSpec.Builder) : Boolean { return deprecatedFields[field]?.let { + print("field ${it.field} inUse ${it.inUse}") spec.addAnnotation(buildDeprecatedAnnotation(it.inUse, it.replacedBy)) true } ?: false diff --git a/couchbase-entity/src/main/java/com/kaufland/model/field/CblFieldHolder.kt b/couchbase-entity/src/main/java/com/kaufland/model/field/CblFieldHolder.kt index 8b985358..d9d94525 100644 --- a/couchbase-entity/src/main/java/com/kaufland/model/field/CblFieldHolder.kt +++ b/couchbase-entity/src/main/java/com/kaufland/model/field/CblFieldHolder.kt @@ -115,7 +115,7 @@ class CblFieldHolder(field: Field, allWrappers: List) : CblBaseFieldHold builder.addKdoc(KDocGeneration.generate(comment)) } - if (deprecated?.inUse == false && deprecated.addDeprecated(dbField, builder)){ + if (deprecated?.evaluateFieldDeprecationLevel(dbField) == DeprecationLevel.ERROR && deprecated?.addDeprecated(dbField, builder)){ builder.addStatement("throw %T()", UnsupportedOperationException::class) } else { builder.addStatement("obj.${accessorSuffix()} = value") diff --git a/demo/build.gradle b/demo/build.gradle index d85c8e97..0d9b1137 100644 --- a/demo/build.gradle +++ b/demo/build.gradle @@ -79,6 +79,7 @@ android { } kapt { + correctErrorTypes = true arguments { arg("useSuspend", "false") arg("entityframework.documentation.generated", "${buildDir.absolutePath}/entity") From 4746640b99f145e570476921df90518d02c0a6d2 Mon Sep 17 00:00:00 2001 From: Sven Braun Date: Tue, 14 Sep 2021 13:13:11 +0200 Subject: [PATCH 4/5] # Inheritance of DocId and Segments --- .../java/com/kaufland/model/EntityFactory.kt | 75 +++++++++++++--- .../java/com/kaufland/model/id/DocIdHolder.kt | 86 ++++++++++++++----- .../com/demo/entity/AnotherBaseModel.kt | 9 +- .../kaufland/com/demo/entity/TestClass.kt | 7 +- 4 files changed, 139 insertions(+), 38 deletions(-) diff --git a/couchbase-entity/src/main/java/com/kaufland/model/EntityFactory.kt b/couchbase-entity/src/main/java/com/kaufland/model/EntityFactory.kt index b8079c61..5bdbca90 100644 --- a/couchbase-entity/src/main/java/com/kaufland/model/EntityFactory.kt +++ b/couchbase-entity/src/main/java/com/kaufland/model/EntityFactory.kt @@ -24,26 +24,58 @@ import javax.lang.model.element.Modifier object EntityFactory { - fun createEntityHolder(cblEntityElement: Element, allWrappers: List, allBaseModels: Map): EntityHolder { + fun createEntityHolder( + cblEntityElement: Element, + allWrappers: List, + allBaseModels: Map + ): EntityHolder { val annotation = cblEntityElement.getAnnotation(Entity::class.java) - return create(cblEntityElement, EntityHolder(annotation.database, annotation.modifierOpen, annotation.type), allWrappers, allBaseModels) as EntityHolder + return create( + cblEntityElement, + EntityHolder(annotation.database, annotation.modifierOpen, annotation.type), + allWrappers, + allBaseModels + ) as EntityHolder } - fun createBaseModelHolder(cblEntityElement: Element, allWrappers: List): BaseModelHolder { - return create(cblEntityElement, BaseModelHolder(), allWrappers, emptyMap()) as BaseModelHolder + fun createBaseModelHolder( + cblEntityElement: Element, + allWrappers: List + ): BaseModelHolder { + return create( + cblEntityElement, + BaseModelHolder(), + allWrappers, + emptyMap() + ) as BaseModelHolder } - fun createChildEntityHolder(cblEntityElement: Element, allWrappers: List, allBaseModels: Map): WrapperEntityHolder { + fun createChildEntityHolder( + cblEntityElement: Element, + allWrappers: List, + allBaseModels: Map + ): WrapperEntityHolder { val annotation = cblEntityElement.getAnnotation(MapWrapper::class.java) - return create(cblEntityElement, WrapperEntityHolder(annotation.modifierOpen), allWrappers, allBaseModels) as WrapperEntityHolder + return create( + cblEntityElement, + WrapperEntityHolder(annotation.modifierOpen), + allWrappers, + allBaseModels + ) as WrapperEntityHolder } - private fun create(cblEntityElement: Element, content: BaseEntityHolder, allWrappers: List, allBaseModels: Map): BaseEntityHolder { + private fun create( + cblEntityElement: Element, + content: BaseEntityHolder, + allWrappers: List, + allBaseModels: Map + ): BaseEntityHolder { content.abstractParts = findPossibleOverrides(cblEntityElement) content.sourceElement = cblEntityElement content.comment = cblEntityElement.getAnnotation(Comment::class.java)?.comment ?: arrayOf() - content.deprecated = cblEntityElement.getAnnotation(Deprecated::class.java)?.let { DeprecatedModel(it) } + content.deprecated = + cblEntityElement.getAnnotation(Deprecated::class.java)?.let { DeprecatedModel(it) } addBasedOn(cblEntityElement, allBaseModels, content) @@ -56,14 +88,22 @@ object EntityFactory { parseStaticsFromStructure(cblEntityElement) { if (it.getAnnotation(GenerateAccessor::class.java) != null) { - content.generateAccessors.add(CblGenerateAccessorHolder(content.sourceClazzTypeName, it)) + content.generateAccessors.add( + CblGenerateAccessorHolder( + content.sourceClazzTypeName, + it + ) + ) } it.getAnnotation(DocIdSegment::class.java)?.apply { docIdSegments.add(DocIdSegmentHolder(this, it)) } } - content.docId = docId?.let { DocIdHolder(it, docIdSegments) } + content.docId = docId?.let { DocIdHolder(it, docIdSegments) } ?: content.docId?.apply { + customSegmentSource.addAll(docIdSegments) + recompile() + } return content @@ -79,6 +119,14 @@ object EntityFactory { basedOnValue?.forEach { type -> allBaseModels[type.toString()]?.let { + it.docId?.let { + if (content.docId == null) { + content.docId = it + } else { + content.docId?.customSegmentSource?.addAll(it.customSegmentSource) + content.docId?.recompile() + } + } content.basedOn.add(it) content.fieldConstants.putAll(it.fieldConstants) content.fields.putAll(it.fields) @@ -88,7 +136,12 @@ object EntityFactory { } } - private fun parseFields(cblEntityElement: Element, content: BaseEntityHolder, allWrappers: List, allBaseModels: Map) { + private fun parseFields( + cblEntityElement: Element, + content: BaseEntityHolder, + allWrappers: List, + allBaseModels: Map + ) { val fields = cblEntityElement.getAnnotation(Fields::class.java) for (cblField in fields.value) { diff --git a/couchbase-entity/src/main/java/com/kaufland/model/id/DocIdHolder.kt b/couchbase-entity/src/main/java/com/kaufland/model/id/DocIdHolder.kt index c4f3d3d5..6f75cf30 100644 --- a/couchbase-entity/src/main/java/com/kaufland/model/id/DocIdHolder.kt +++ b/couchbase-entity/src/main/java/com/kaufland/model/id/DocIdHolder.kt @@ -8,11 +8,15 @@ import kaufland.com.coachbasebinderapi.DocId import java.util.regex.Pattern -class DocIdHolder(docId: DocId, customSegments: List) { +class DocIdHolder(docId: DocId, val customSegmentSource: MutableList) { private val docIdSegmentCallPattern = Pattern.compile("\\((.+?)\\)") - data class Segment(val segment: String, val fields: List, val customSegment: DocIdSegmentHolder?) { + data class Segment( + val segment: String, + val fields: List, + val customSegment: DocIdSegmentHolder? + ) { fun fieldsToModelFields(entity: BaseEntityHolder) = fields.map { entity.fields[it] ?: entity.fieldConstants[it] @@ -22,46 +26,83 @@ class DocIdHolder(docId: DocId, customSegments: List) { val pattern = docId.value - val customSegments = customSegments.associateBy { it.name } + init { + recompile() + } - //contains all segments placed between % - val segments: List = Pattern.compile("%(.+?)%").matcher(pattern).let { - val segments = mutableListOf() - while (it.find()) { - val plainSegment = it.group(1) - - val segmentMatcher = docIdSegmentCallPattern.matcher(plainSegment) - if (segmentMatcher.find()) { - val fields = segmentMatcher.group(1).split(',').map { it.trim() } - segments.add(Segment(plainSegment, fields, this.customSegments[plainSegment.removeSuffix("(${segmentMatcher.group(1)})").removePrefix("this.")])) - } else { - segments.add(Segment(plainSegment, listOf(plainSegment), null)) + fun recompile() { + customSegments = customSegmentSource.associateBy { it.name }.toMutableMap() + segments = Pattern.compile("%(.+?)%").matcher(pattern).let { + val segments = mutableListOf() + while (it.find()) { + val plainSegment = it.group(1) + val segmentMatcher = docIdSegmentCallPattern.matcher(plainSegment) + if (segmentMatcher.find()) { + val fields = segmentMatcher.group(1).split(',').map { it.trim() } + segments.add( + Segment( + plainSegment, + fields, + this.customSegments[plainSegment.removeSuffix("(${segmentMatcher.group(1)})") + .removePrefix("this.")] + ) + ) + } else if (plainSegment.contains("()")) { + segments.add( + Segment( + plainSegment, + listOf(), + this.customSegments[plainSegment.removeSuffix("()") + .removePrefix("this.")] + ) + ) + } else { + segments.add(Segment(plainSegment, listOf(plainSegment), null)) + + } } + segments } - segments } - private fun List.distinctFieldAccessors(model: BaseEntityHolder)=this.map { it.fieldsToModelFields(model) }.flatten().map { it.accessorSuffix() }.distinct() + lateinit var customSegments: MutableMap + + //contains all segments placed between % + lateinit var segments: List + + private fun List.distinctFieldAccessors(model: BaseEntityHolder) = + this.map { it.fieldsToModelFields(model) }.flatten().map { it.accessorSuffix() }.distinct() fun companionFunction(entity: BaseEntityHolder): FunSpec { - val spec = FunSpec.builder(COMPANION_BUILD_FUNCTION_NAME).addAnnotation(JvmStatic::class).returns(TypeUtil.string()) + val spec = FunSpec.builder(COMPANION_BUILD_FUNCTION_NAME).addAnnotation(JvmStatic::class) + .returns(TypeUtil.string()) var statement = pattern val addedFields = mutableListOf() for (segment in segments) { val entityFields = segment.fieldsToModelFields(entity).associateBy { it.dbField } val statementValue = segment.customSegment?.let { - "\${${it.name}(${entityFields.map { it.value.accessorSuffix() }.joinToString(separator = ",")})}" + "\${${it.name}(${ + entityFields.map { it.value.accessorSuffix() }.joinToString(separator = ",") + })}" } - ?: entityFields.map { it.value.accessorSuffix() }.joinToString(separator = ","){"\$$it"} + ?: entityFields.map { it.value.accessorSuffix() } + .joinToString(separator = ",") { "\$$it" } statement = statement.replace("%${segment.segment}%", statementValue) entityFields.values.forEach { if (!addedFields.contains(it.dbField)) { addedFields.add(it.dbField) - spec.addParameter(it.accessorSuffix(), TypeUtil.parseMetaType(it.typeMirror, it.isIterable, (it as? CblFieldHolder?)?.subEntitySimpleName).copy(nullable = !it.isConstant)) + spec.addParameter( + it.accessorSuffix(), + TypeUtil.parseMetaType( + it.typeMirror, + it.isIterable, + (it as? CblFieldHolder?)?.subEntitySimpleName + ).copy(nullable = !it.isConstant) + ) } } } @@ -71,7 +112,8 @@ class DocIdHolder(docId: DocId, customSegments: List) { } fun buildExpectedDocId(entity: BaseEntityHolder): FunSpec { - val spec = FunSpec.builder(BUILD_FUNCTION_NAME).returns(TypeUtil.string()).addModifiers(KModifier.OVERRIDE) + val spec = FunSpec.builder(BUILD_FUNCTION_NAME).returns(TypeUtil.string()) + .addModifiers(KModifier.OVERRIDE) val list: List = segments.distinctFieldAccessors(entity) spec.addStatement("return $COMPANION_BUILD_FUNCTION_NAME(${list.joinToString(separator = ",")})") diff --git a/demo/src/main/java/kaufland/com/demo/entity/AnotherBaseModel.kt b/demo/src/main/java/kaufland/com/demo/entity/AnotherBaseModel.kt index 8196816e..64e2030e 100644 --- a/demo/src/main/java/kaufland/com/demo/entity/AnotherBaseModel.kt +++ b/demo/src/main/java/kaufland/com/demo/entity/AnotherBaseModel.kt @@ -1,9 +1,7 @@ package kaufland.com.demo.entity +import kaufland.com.coachbasebinderapi.* import kaufland.com.coachbasebinderapi.BaseModel -import kaufland.com.coachbasebinderapi.BasedOn -import kaufland.com.coachbasebinderapi.Field -import kaufland.com.coachbasebinderapi.Fields import kaufland.com.demo.customtypes.GenerateClassName @BaseModel @@ -12,4 +10,7 @@ import kaufland.com.demo.customtypes.GenerateClassName Field(name = "clazzName", type = GenerateClassName::class, defaultValue = "GenerateClassName(this::class.simpleName ?: \"\")") ) @BasedOn(kaufland.com.demo.entity.BaseModel::class) -class AnotherBaseModel +@DocId("%this.prefix()%:dummy:%anotherBaseThing%") +class AnotherBaseModel{ + +} diff --git a/demo/src/main/java/kaufland/com/demo/entity/TestClass.kt b/demo/src/main/java/kaufland/com/demo/entity/TestClass.kt index a969522f..f24b3c35 100644 --- a/demo/src/main/java/kaufland/com/demo/entity/TestClass.kt +++ b/demo/src/main/java/kaufland/com/demo/entity/TestClass.kt @@ -12,4 +12,9 @@ import kaufland.com.coachbasebinderapi.* Field(name = "map", type = Map::class, list = true) ) @BasedOn(AnotherBaseModel::class) -open class TestClass \ No newline at end of file +open class TestClass{ + companion object{ + @DocIdSegment + fun prefix() = "hurra" + } +} \ No newline at end of file From 1f951fd83b6e8f9c5c780b1f93c88c7764c3fca2 Mon Sep 17 00:00:00 2001 From: Michael Gut Date: Tue, 14 Sep 2021 16:34:05 +0200 Subject: [PATCH 5/5] NFWWS-3070 Handle lists of Enums in EnumConversion --- .gitignore | 2 ++ .../com/kaufland/model/field/CblFieldHolder.kt | 6 +++++- .../src/main/java/com/kaufland/util/TypeUtil.kt | 4 ++++ .../kaufland/com/demo/mapper/ExposingSource.kt | 8 ++------ .../com/demo/tesst/CaptureStateItemPosition.kt | 16 ++++++++++++++++ .../java/kaufland/com/demo/TypeConversionTest.kt | 4 ++++ .../com/demo/entity/ProductWrapperTest.kt | 4 ++++ .../com/demo/mapper/DummyMapperSourceTest.kt | 6 +++++- 8 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 demo/src/main/java/kaufland/com/demo/tesst/CaptureStateItemPosition.kt diff --git a/.gitignore b/.gitignore index 520a8635..ef148681 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,8 @@ captures/ .idea/gradle.xml .idea/dictionaries .idea/libraries +.idea/sonarlint +.idea/shelf # Keystore files *.jks diff --git a/couchbase-entity/src/main/java/com/kaufland/model/field/CblFieldHolder.kt b/couchbase-entity/src/main/java/com/kaufland/model/field/CblFieldHolder.kt index d9d94525..00b4a742 100644 --- a/couchbase-entity/src/main/java/com/kaufland/model/field/CblFieldHolder.kt +++ b/couchbase-entity/src/main/java/com/kaufland/model/field/CblFieldHolder.kt @@ -132,7 +132,11 @@ class CblFieldHolder(field: Field, allWrappers: List) : CblBaseFieldHold private fun evaluateClazzForTypeConversion(): TypeName { return if (isIterable) { - TypeUtil.string() + if (TypeUtil.isMap(fieldType)) { + TypeUtil.string() + } else { + fieldType + } } else TypeUtil.parseMetaType(typeMirror, isIterable, false, subEntitySimpleName) } } diff --git a/couchbase-entity/src/main/java/com/kaufland/util/TypeUtil.kt b/couchbase-entity/src/main/java/com/kaufland/util/TypeUtil.kt index 37d7e0c5..0f88f02e 100644 --- a/couchbase-entity/src/main/java/com/kaufland/util/TypeUtil.kt +++ b/couchbase-entity/src/main/java/com/kaufland/util/TypeUtil.kt @@ -164,4 +164,8 @@ object TypeUtil { fun classStar(): ParameterizedTypeName { return ClassName("kotlin.reflect", "KClass").parameterizedBy(star()) } + + fun isMap(fieldType: TypeName): Boolean { + return fieldType.toString().startsWith("kotlin.collections.Map") + } } diff --git a/demo/src/main/java/kaufland/com/demo/mapper/ExposingSource.kt b/demo/src/main/java/kaufland/com/demo/mapper/ExposingSource.kt index 16016920..6406976f 100644 --- a/demo/src/main/java/kaufland/com/demo/mapper/ExposingSource.kt +++ b/demo/src/main/java/kaufland/com/demo/mapper/ExposingSource.kt @@ -1,16 +1,12 @@ package kaufland.com.demo.mapper -import androidx.lifecycle.MutableLiveData import kaufland.com.coachbasebinderapi.mapify.Mapify import kaufland.com.coachbasebinderapi.mapify.Mapper @Mapper -class ExposingSource(value : T) : HiddingSource(){ - +class ExposingSource(value : T) : HiddingSource() { @get:Mapify @set:Mapify var exposedVal : T? = myValue - - -} \ No newline at end of file +} diff --git a/demo/src/main/java/kaufland/com/demo/tesst/CaptureStateItemPosition.kt b/demo/src/main/java/kaufland/com/demo/tesst/CaptureStateItemPosition.kt new file mode 100644 index 00000000..f066bc51 --- /dev/null +++ b/demo/src/main/java/kaufland/com/demo/tesst/CaptureStateItemPosition.kt @@ -0,0 +1,16 @@ +package schwarz.fwws.shared.model + + +import kaufland.com.coachbasebinderapi.* + +@Entity +@Fields( + Field(name = "here_state", type = CaptureState::class, list = true), +) +open class CaptureStateItemPosition {} + +enum class CaptureState { + STATE_1, + STATE_2, + STATE_3 +} diff --git a/demo/src/test/java/kaufland/com/demo/TypeConversionTest.kt b/demo/src/test/java/kaufland/com/demo/TypeConversionTest.kt index 8be8a0fd..fa4c1615 100644 --- a/demo/src/test/java/kaufland/com/demo/TypeConversionTest.kt +++ b/demo/src/test/java/kaufland/com/demo/TypeConversionTest.kt @@ -32,6 +32,10 @@ class TypeConversionTest { return emptyMap() } + override fun getDocuments(ids: List, dbName: String): List?> { + TODO("Not yet implemented") + } + override fun queryDoc(dbName: String, queryParams: Map): List> { throw Exception("should not called") } diff --git a/demo/src/test/java/kaufland/com/demo/entity/ProductWrapperTest.kt b/demo/src/test/java/kaufland/com/demo/entity/ProductWrapperTest.kt index 05140cab..c0aff398 100644 --- a/demo/src/test/java/kaufland/com/demo/entity/ProductWrapperTest.kt +++ b/demo/src/test/java/kaufland/com/demo/entity/ProductWrapperTest.kt @@ -19,6 +19,10 @@ class ProductWrapperTest { TODO("Not yet implemented") } + override fun getDocuments(ids: List, dbName: String): List?> { + TODO("Not yet implemented") + } + override fun queryDoc(dbName: String, queryParams: Map): List> { TODO("Not yet implemented") } diff --git a/demo/src/test/java/kaufland/com/demo/mapper/DummyMapperSourceTest.kt b/demo/src/test/java/kaufland/com/demo/mapper/DummyMapperSourceTest.kt index c3af2d42..4afbd8f0 100644 --- a/demo/src/test/java/kaufland/com/demo/mapper/DummyMapperSourceTest.kt +++ b/demo/src/test/java/kaufland/com/demo/mapper/DummyMapperSourceTest.kt @@ -23,6 +23,10 @@ class DummyMapperSourceTest { return null } + override fun getDocuments(ids: List, dbName: String): List?> { + TODO("Not yet implemented") + } + override fun queryDoc(dbName: String, queryParams: Map): List> { return emptyList() } @@ -46,7 +50,7 @@ class DummyMapperSourceTest { booleanValue = true product = ProductEntity.create().builder().setName("Foo").exit() testSerializable = DummyMapperSource.TestSerializable("Bar", 1) - liveData.exposedVal = "myLiveVal" + liveData.exposedVal = DummyMapperSource.TestSerializable("myLiveVal", 1) nullableList.add("1") } val mapToPersist = mapper.toMap(obj)