diff --git a/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/GenerateAccessor.java b/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/GenerateAccessor.java new file mode 100644 index 00000000..350c31c0 --- /dev/null +++ b/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/GenerateAccessor.java @@ -0,0 +1,14 @@ +package kaufland.com.coachbasebinderapi; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.FIELD, ElementType.METHOD}) +public @interface GenerateAccessor { + + Class value() default Void.class; +} diff --git a/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/PersistenceConfig.java b/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/PersistenceConfig.java index 22e0b007..2122880a 100644 --- a/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/PersistenceConfig.java +++ b/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/PersistenceConfig.java @@ -2,6 +2,7 @@ import java.util.HashMap; +import java.util.List; import java.util.Map; import kotlin.reflect.KClass; @@ -22,6 +23,8 @@ public interface Connector { Map getDocument(String id, String dbName); + List> queryDoc(String dbName, Map queryParams); + void deleteDocument(String id, String dbName) throws PersistenceException; void upsertDocument(Map document, String id, String dbName) throws PersistenceException; diff --git a/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/query/Queries.java b/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/query/Queries.java new file mode 100644 index 00000000..fc0cf490 --- /dev/null +++ b/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/query/Queries.java @@ -0,0 +1,15 @@ +package kaufland.com.coachbasebinderapi.query; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import kaufland.com.coachbasebinderapi.Field; + +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.TYPE}) +public @interface Queries { + + Query[] value() default {}; +} diff --git a/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/query/Query.kt b/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/query/Query.kt new file mode 100644 index 00000000..a106dfc8 --- /dev/null +++ b/couchbase-entity-api/src/main/java/kaufland/com/coachbasebinderapi/query/Query.kt @@ -0,0 +1,4 @@ +package kaufland.com.coachbasebinderapi.query + +@Retention(AnnotationRetention.BINARY) +annotation class Query(val fields: Array) diff --git a/couchbase-entity-connector/src/main/java/kaufland/com/couchbaseentityconnector/Couchbase2Connector.kt b/couchbase-entity-connector/src/main/java/kaufland/com/couchbaseentityconnector/Couchbase2Connector.kt index ca115d95..e2d3a2e5 100644 --- a/couchbase-entity-connector/src/main/java/kaufland/com/couchbaseentityconnector/Couchbase2Connector.kt +++ b/couchbase-entity-connector/src/main/java/kaufland/com/couchbaseentityconnector/Couchbase2Connector.kt @@ -1,16 +1,10 @@ package kaufland.com.couchbaseentityconnector -import com.couchbase.lite.CouchbaseLiteException -import com.couchbase.lite.Database -import com.couchbase.lite.Document -import com.couchbase.lite.MutableDocument - -import java.util.ArrayList -import java.util.HashMap - +import com.couchbase.lite.* import kaufland.com.coachbasebinderapi.PersistenceConfig import kaufland.com.coachbasebinderapi.PersistenceException import kaufland.com.coachbasebinderapi.TypeConversion +import java.util.* import kotlin.reflect.KClass abstract class Couchbase2Connector : PersistenceConfig.Connector { @@ -102,6 +96,56 @@ abstract class Couchbase2Connector : PersistenceConfig.Connector { } + @Throws(PersistenceException::class) + override fun queryDoc(dbName: String, queryParams: Map): List> { + try { + + val builder = QueryBuilder.select(SelectResult.expression(Meta.id), SelectResult.all()) + .from(DataSource.database(getDatabase(dbName))) + + parseExpressions(queryParams)?.let { + builder.where(it) + } + + return queryResultToMap(builder.execute()) + } catch (e: CouchbaseLiteException) { + throw PersistenceException(e) + } + } + + private fun queryResultToMap(execute : ResultSet) : List>{ + val parsed: MutableList> = + ArrayList() + if (execute != null) { + for (result in execute) { + val item: MutableMap = + HashMap() + item["_id"] = result.getString(0) + item.putAll(result.getDictionary(1).toMap()) + parsed.add(item) + } + } + return parsed + } + + private fun parseExpressions(queryParams: Map): Expression? { + + var result: Expression? = null + + for (queryParam in queryParams) { + + val equalTo = Expression.property(queryParam.key).equalTo( + Expression.value(queryParam.value)) + result = if (result == null) { + equalTo + } else { + result.and(equalTo) + } + } + + return result + } + @Throws(PersistenceException::class) override fun upsertDocument(upsert: MutableMap, docId: String, name: String) { if (upsert["_id"] == null) { diff --git a/couchbase-entity/src/main/java/com/kaufland/CoachBaseBinderProcessor.kt b/couchbase-entity/src/main/java/com/kaufland/CoachBaseBinderProcessor.kt index db726390..f9a82bec 100644 --- a/couchbase-entity/src/main/java/com/kaufland/CoachBaseBinderProcessor.kt +++ b/couchbase-entity/src/main/java/com/kaufland/CoachBaseBinderProcessor.kt @@ -5,19 +5,23 @@ import com.kaufland.generation.CodeGenerator import com.kaufland.generation.EntityGeneration import com.kaufland.generation.WrapperGeneration import com.kaufland.model.EntityFactory +import com.kaufland.model.accessor.CblGenerateAccessorHolder import com.kaufland.validation.PreValidator import com.squareup.kotlinpoet.FileSpec import kaufland.com.coachbasebinderapi.Entity +import kaufland.com.coachbasebinderapi.Field +import kaufland.com.coachbasebinderapi.GenerateAccessor import kaufland.com.coachbasebinderapi.MapWrapper +import kaufland.com.coachbasebinderapi.query.Queries +import kaufland.com.coachbasebinderapi.query.Query import javax.annotation.processing.* import javax.lang.model.SourceVersion import javax.lang.model.element.Element +import javax.lang.model.element.ElementKind +import javax.lang.model.element.Modifier import javax.lang.model.element.TypeElement -import javax.swing.UIManager.put - -@SupportedAnnotationTypes("kaufland.com.coachbasebinderapi.Field", "kaufland.com.coachbasebinderapi.Entity", "kaufland.com.coachbasebinderapi.MapWrapper") @SupportedSourceVersion(SourceVersion.RELEASE_8) @AutoService(Processor::class) class CoachBaseBinderProcessor : AbstractProcessor() { @@ -39,12 +43,12 @@ class CoachBaseBinderProcessor : AbstractProcessor() { override fun process(set: Set, roundEnv: RoundEnvironment): Boolean { - var mapWrappers = roundEnv.getElementsAnnotatedWith(MapWrapper::class.java) var mapWrapperStrings = mapWrappers.map { element -> element.toString() } validateAndProcess(roundEnv.getElementsAnnotatedWith(Entity::class.java), object : EntityProcessor { override fun process(element: Element): FileSpec { + val holder = EntityFactory.createEntityHolder(element, mapWrapperStrings) return EntityGeneration().generateModel(holder) } @@ -81,5 +85,9 @@ class CoachBaseBinderProcessor : AbstractProcessor() { } } + override fun getSupportedAnnotationTypes(): MutableSet { + return setOf(Field::class.java.canonicalName, Entity::class.java.canonicalName, MapWrapper::class.java.canonicalName, Queries::class.java.canonicalName, Query::class.java.canonicalName, GenerateAccessor::class.java.canonicalName).toMutableSet() + } + } diff --git a/couchbase-entity/src/main/java/com/kaufland/generation/CblConstantGeneration.kt b/couchbase-entity/src/main/java/com/kaufland/generation/CblConstantGeneration.kt index bd63864f..399a0777 100644 --- a/couchbase-entity/src/main/java/com/kaufland/generation/CblConstantGeneration.kt +++ b/couchbase-entity/src/main/java/com/kaufland/generation/CblConstantGeneration.kt @@ -13,7 +13,7 @@ object CblConstantGeneration { fun addConstants(holder: BaseEntityHolder): FunSpec { val builder = FunSpec.builder("addConstants").addModifiers(KModifier.PRIVATE).addParameter("map", TypeUtil.mutableMapStringObject()) - for (fieldHolder in holder.fieldConstants) { + for (fieldHolder in holder.fieldConstants.values) { if (fieldHolder.isConstant) { builder.addStatement("map.put(%N, DOC_%N)", fieldHolder.constantName, fieldHolder.constantName) diff --git a/couchbase-entity/src/main/java/com/kaufland/generation/CblDefaultGeneration.kt b/couchbase-entity/src/main/java/com/kaufland/generation/CblDefaultGeneration.kt index 8d442cc1..635f0599 100644 --- a/couchbase-entity/src/main/java/com/kaufland/generation/CblDefaultGeneration.kt +++ b/couchbase-entity/src/main/java/com/kaufland/generation/CblDefaultGeneration.kt @@ -14,7 +14,7 @@ object CblDefaultGeneration { fun addDefaults(holder: BaseEntityHolder): FunSpec { val builder = FunSpec.builder("addDefaults").addModifiers(KModifier.PRIVATE).addParameter( "map", TypeUtil.mutableMapStringObject()) - for (fieldHolder in holder.fields) { + for (fieldHolder in holder.fields.values) { if (fieldHolder.isDefault) { builder.addStatement("map.put(%N, " + getConvertedValue(fieldHolder.typeMirror!!, fieldHolder.defaultValue) + ")", fieldHolder.constantName) diff --git a/couchbase-entity/src/main/java/com/kaufland/generation/EntityGeneration.kt b/couchbase-entity/src/main/java/com/kaufland/generation/EntityGeneration.kt index ff143899..58dcb232 100644 --- a/couchbase-entity/src/main/java/com/kaufland/generation/EntityGeneration.kt +++ b/couchbase-entity/src/main/java/com/kaufland/generation/EntityGeneration.kt @@ -20,6 +20,21 @@ class EntityGeneration { companionSpec.addProperty(idConstant()) companionSpec.addFunctions(create(holder)) + for (query in holder.queries) { + query.queryFun(holder.dbName, holder)?.let { + companionSpec.addFunction(it) + } + } + + for (generateAccessor in holder.generateAccessors) { + generateAccessor.accessorFunSpec()?.let { + companionSpec.addFunction(it) + } + generateAccessor.accessorPropertySpec()?.let { + companionSpec.addProperty(it) + } + } + val builderBuilder = BuilderClassGeneration.generateBaseBuilder(holder) val typeBuilder = TypeSpec.classBuilder(holder.entitySimpleName).addModifiers(KModifier.PUBLIC).addSuperinterface(TypeUtil.mapSupport()) @@ -69,7 +84,7 @@ class EntityGeneration { val toMapBuilder = FunSpec.builder("toMap").addModifiers(KModifier.OVERRIDE).returns(TypeUtil.mutableMapStringObject()).addStatement("val doc = %T.$GET_DOCUMENT_METHOD(getId(), %S)", PersistenceConfig::class, holder.dbName) - for (constantField in holder.fieldConstants) { + for (constantField in holder.fieldConstants.values) { toMapBuilder.addStatement("mDocChanges.put(%S, %S)", constantField.dbField, constantField.constantValue) } 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 a061420d..ff2a3413 100644 --- a/couchbase-entity/src/main/java/com/kaufland/model/EntityFactory.kt +++ b/couchbase-entity/src/main/java/com/kaufland/model/EntityFactory.kt @@ -1,15 +1,19 @@ package com.kaufland.model +import com.kaufland.model.accessor.CblGenerateAccessorHolder import com.kaufland.model.entity.BaseEntityHolder import com.kaufland.model.entity.EntityHolder import com.kaufland.model.entity.WrapperEntityHolder import com.kaufland.model.field.CblConstantHolder import com.kaufland.model.field.CblFieldHolder +import com.kaufland.model.query.CblQueryHolder import javax.lang.model.element.Element import kaufland.com.coachbasebinderapi.Entity import kaufland.com.coachbasebinderapi.Fields +import kaufland.com.coachbasebinderapi.GenerateAccessor +import kaufland.com.coachbasebinderapi.query.Queries import org.apache.commons.lang3.text.WordUtils import javax.lang.model.element.ElementKind import javax.lang.model.element.Modifier @@ -30,6 +34,15 @@ object EntityFactory { content.abstractParts = findPossibleOverrides(cblEntityElement) content.sourceElement = cblEntityElement + parseQueries(cblEntityElement, content) + parseFields(cblEntityElement, content, allWrappers) + parseGenerateAccessors(cblEntityElement, content) + + return content + + } + + private fun parseFields(cblEntityElement: Element, content: BaseEntityHolder, allWrappers: List) { val fields = cblEntityElement.getAnnotation(Fields::class.java) @@ -40,15 +53,46 @@ object EntityFactory { } if (cblField!!.readonly) { - content.fieldConstants.add(CblConstantHolder(cblField)) + content.fieldConstants[cblField.name] = CblConstantHolder(cblField) } else { val cblFieldHolder = CblFieldHolder(cblField, allWrappers) - content.fields.add(cblFieldHolder) + content.fields[cblField.name] = cblFieldHolder } } + } - return content + private fun parseGenerateAccessors(cblEntityElement: Element, content: BaseEntityHolder){ + for (childElement in cblEntityElement.enclosedElements) { + if(childElement.modifiers.contains(Modifier.STATIC)){ + if(childElement.kind == ElementKind.CLASS && childElement.simpleName.toString() == "Companion"){ + for (companionMembers in childElement.enclosedElements) { + addIfAnnotationIsPresent(content.sourceClazzSimpleName, companionMembers, content.generateAccessors) + } + continue + } + addIfAnnotationIsPresent(content.sourceClazzSimpleName, childElement, content.generateAccessors) + } + } + } + + private fun addIfAnnotationIsPresent(className: String, companionMembers: Element, generateAccessors: MutableList) { + if (companionMembers.getAnnotation(GenerateAccessor::class.java) != null) { + generateAccessors.add(CblGenerateAccessorHolder(className, companionMembers)) + } + } + + private fun parseQueries(cblEntityElement: Element, content: BaseEntityHolder) { + val queries = cblEntityElement.getAnnotation(Queries::class.java) ?: return + + for (cblQuery in queries.value) { + + if (cblQuery == null) { + continue + } + + content.queries.add(CblQueryHolder(cblQuery)) + } } private fun findPossibleOverrides(cblEntityElement: Element): HashSet { diff --git a/couchbase-entity/src/main/java/com/kaufland/model/accessor/CblGenerateAccessorHolder.kt b/couchbase-entity/src/main/java/com/kaufland/model/accessor/CblGenerateAccessorHolder.kt new file mode 100644 index 00000000..d36ad276 --- /dev/null +++ b/couchbase-entity/src/main/java/com/kaufland/model/accessor/CblGenerateAccessorHolder.kt @@ -0,0 +1,40 @@ +package com.kaufland.model.accessor + +import com.kaufland.javaToKotlinType +import com.kaufland.util.ConversionUtil +import com.kaufland.util.FieldExtractionUtil +import com.kaufland.util.TypeUtil +import com.squareup.kotlinpoet.* +import kaufland.com.coachbasebinderapi.Field +import org.apache.commons.lang3.text.WordUtils +import javax.lang.model.element.Element +import javax.lang.model.element.ElementKind +import javax.lang.model.element.ExecutableElement +import javax.lang.model.type.TypeMirror + +class CblGenerateAccessorHolder(private val className: String, val element: Element) { + + fun accessorFunSpec(): FunSpec? { + + if(element.kind == ElementKind.METHOD){ + var methodBuilder = FunSpec.builder(element.simpleName.toString()).addAnnotation(JvmStatic::class) + + (element as ExecutableElement)?.apply { + parameters.forEach { + methodBuilder.addParameter(it.simpleName.toString(), it.asType().asTypeName().javaToKotlinType()) + } + methodBuilder.addStatement("%N.%N(${parameters.joinToString { it.simpleName.toString() }})", className, element.simpleName.toString()) + } + return methodBuilder.build() + } + return null + } + + + fun accessorPropertySpec(): PropertySpec? { + if(element.kind == ElementKind.FIELD){ + return PropertySpec.builder(element.simpleName.toString(), element.asType().asTypeName().javaToKotlinType()).addAnnotation(JvmField::class).initializer("%N.%N", className, element.simpleName.toString()).build() + } + return null + } +} diff --git a/couchbase-entity/src/main/java/com/kaufland/model/entity/BaseEntityHolder.kt b/couchbase-entity/src/main/java/com/kaufland/model/entity/BaseEntityHolder.kt index 621c6de5..03c62d34 100644 --- a/couchbase-entity/src/main/java/com/kaufland/model/entity/BaseEntityHolder.kt +++ b/couchbase-entity/src/main/java/com/kaufland/model/entity/BaseEntityHolder.kt @@ -1,11 +1,14 @@ package com.kaufland.model.entity +import com.kaufland.model.accessor.CblGenerateAccessorHolder import com.kaufland.model.field.CblBaseFieldHolder import com.kaufland.model.field.CblConstantHolder import com.kaufland.model.field.CblFieldHolder +import com.kaufland.model.query.CblQueryHolder import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.TypeName import com.sun.tools.javac.code.Symbol +import kaufland.com.coachbasebinderapi.query.Query import java.util.ArrayList @@ -13,19 +16,23 @@ import javax.lang.model.element.Element abstract class BaseEntityHolder { - val fields: MutableList = ArrayList() + val fields: MutableMap = HashMap() var abstractParts: Set = HashSet() - val fieldConstants: MutableList = ArrayList() + val fieldConstants: MutableMap = HashMap() var sourceElement: Element? = null + val queries : MutableList = ArrayList() + + val generateAccessors : MutableList = ArrayList() + val allFields: List get() { val allField = ArrayList() - allField.addAll(fields) - allField.addAll(fieldConstants) + allField.addAll(fields.values) + allField.addAll(fieldConstants.values) return allField } diff --git a/couchbase-entity/src/main/java/com/kaufland/model/field/CblBaseFieldHolder.kt b/couchbase-entity/src/main/java/com/kaufland/model/field/CblBaseFieldHolder.kt index d2fcd2ff..fd07ee7a 100644 --- a/couchbase-entity/src/main/java/com/kaufland/model/field/CblBaseFieldHolder.kt +++ b/couchbase-entity/src/main/java/com/kaufland/model/field/CblBaseFieldHolder.kt @@ -2,6 +2,7 @@ package com.kaufland.model.field import com.kaufland.util.ConversionUtil import com.kaufland.util.FieldExtractionUtil +import com.kaufland.util.TypeUtil import com.squareup.kotlinpoet.FunSpec import com.squareup.kotlinpoet.PropertySpec import com.squareup.kotlinpoet.TypeName diff --git a/couchbase-entity/src/main/java/com/kaufland/model/field/CblConstantHolder.kt b/couchbase-entity/src/main/java/com/kaufland/model/field/CblConstantHolder.kt index 27460c29..aa53c962 100644 --- a/couchbase-entity/src/main/java/com/kaufland/model/field/CblConstantHolder.kt +++ b/couchbase-entity/src/main/java/com/kaufland/model/field/CblConstantHolder.kt @@ -5,13 +5,10 @@ import com.kaufland.util.TypeUtil import com.squareup.kotlinpoet.PropertySpec import com.squareup.kotlinpoet.FunSpec import com.squareup.kotlinpoet.KModifier -import com.squareup.kotlinpoet.TypeName import java.util.Arrays -import javax.lang.model.element.Modifier - import kaufland.com.coachbasebinderapi.Field /** @@ -22,6 +19,8 @@ class CblConstantHolder(field: Field) : CblBaseFieldHolder(field.name, field) { val constantValue: String = field.defaultValue + val constantValueAccessorName = "DOC_$constantName" + override fun property(dbName: String?, possibleOverrides: Set, useMDocChanges: Boolean): PropertySpec { val returnType = TypeUtil.parseMetaType(typeMirror!!, isIterable, null) @@ -34,7 +33,7 @@ class CblConstantHolder(field: Field) : CblBaseFieldHolder(field.name, field) { val fieldAccessorConstant = PropertySpec.builder(constantName, String::class, KModifier.FINAL, KModifier.PUBLIC).initializer("%S", dbField).addAnnotation(JvmField::class).build() return Arrays.asList(fieldAccessorConstant, - PropertySpec.builder("DOC_$constantName", String::class, KModifier.FINAL, KModifier.PUBLIC).initializer("%S", constantValue).addAnnotation(JvmField::class).build()) + PropertySpec.builder(constantValueAccessorName, String::class, KModifier.FINAL, KModifier.PUBLIC).initializer("%S", constantValue).addAnnotation(JvmField::class).build()) } override fun builderSetter(dbName: String?, packageName: String, entitySimpleName: String, useMDocChanges: Boolean): FunSpec? { 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 ad10329b..e5c71fc1 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 @@ -25,6 +25,8 @@ class CblFieldHolder(field: Field, allWrappers: List) : CblBaseFieldHold val isTypeOfSubEntity: Boolean get() = !StringUtils.isBlank(subEntitySimpleName) + val fieldType: TypeName = TypeUtil.parseMetaType(typeMirror!!, isIterable, subEntitySimpleName) + init { if (allWrappers.contains(typeMirror.toString())) { diff --git a/couchbase-entity/src/main/java/com/kaufland/model/query/CblQueryHolder.kt b/couchbase-entity/src/main/java/com/kaufland/model/query/CblQueryHolder.kt new file mode 100644 index 00000000..7ec9bf22 --- /dev/null +++ b/couchbase-entity/src/main/java/com/kaufland/model/query/CblQueryHolder.kt @@ -0,0 +1,46 @@ +package com.kaufland.model.query + +import com.kaufland.model.entity.BaseEntityHolder +import com.kaufland.util.TypeUtil +import com.squareup.kotlinpoet.* +import kaufland.com.coachbasebinderapi.PersistenceConfig +import kaufland.com.coachbasebinderapi.query.Query +import org.apache.commons.lang3.text.WordUtils + +/** + * Created by sbra0902 on 21.06.17. + */ + +class CblQueryHolder(private val mQuery: Query) { + + val fields: Array + get() = mQuery.fields + + + fun queryFun(dbName: String, entityHolder: BaseEntityHolder): FunSpec? { + + val builder = FunSpec.builder(queryFunName).addModifiers(KModifier.PUBLIC).addAnnotation(JvmStatic::class).addStatement("val queryParams = %T()", TypeUtil.hashMapStringObject()).returns(TypeUtil.list(entityHolder.entityTypeName)) + + fields.forEach { + entityHolder.fields[it]?.apply { + builder.addParameter(dbField, fieldType) + builder.addStatement("queryParams[%N] = %N", constantName, dbField) + } + entityHolder.fieldConstants[it]?.apply { + builder.addStatement("queryParams[%N] = %N", constantName, constantValueAccessorName) + } + } + + builder.addStatement("return %T.$QUERY_DOCUMENT_METHOD(%S, queryParams).map { create(it) }", PersistenceConfig::class, dbName) + + + + return builder.build() + } + + private val queryFunName: String = "findBy${fields.joinToString(separator = "And") { WordUtils.capitalize(it.replace("_", " ")).replace(" ", "") }}" + + companion object{ + private val QUERY_DOCUMENT_METHOD = "getInstance().getConnector().queryDoc" + } +} diff --git a/couchbase-entity/src/main/java/com/kaufland/util/FieldExtractionUtil.kt b/couchbase-entity/src/main/java/com/kaufland/util/FieldExtractionUtil.kt index d0886e89..5e6526b9 100644 --- a/couchbase-entity/src/main/java/com/kaufland/util/FieldExtractionUtil.kt +++ b/couchbase-entity/src/main/java/com/kaufland/util/FieldExtractionUtil.kt @@ -4,6 +4,7 @@ import javax.lang.model.type.MirroredTypeException import javax.lang.model.type.TypeMirror import kaufland.com.coachbasebinderapi.Field +import javax.management.Query object FieldExtractionUtil { diff --git a/couchbase-entity/src/main/java/com/kaufland/validation/PreValidator.kt b/couchbase-entity/src/main/java/com/kaufland/validation/PreValidator.kt index 0e7ab2e1..8757d464 100644 --- a/couchbase-entity/src/main/java/com/kaufland/validation/PreValidator.kt +++ b/couchbase-entity/src/main/java/com/kaufland/validation/PreValidator.kt @@ -5,6 +5,7 @@ import com.kaufland.util.FieldExtractionUtil import com.sun.tools.javac.code.Symbol import kaufland.com.coachbasebinderapi.Entity import kaufland.com.coachbasebinderapi.Fields +import kaufland.com.coachbasebinderapi.query.Queries import java.util.* import javax.lang.model.element.Element import javax.lang.model.element.ElementKind @@ -50,6 +51,22 @@ class PreValidator { } + val queries = entityElement.getAnnotation(Queries::class.java) + + if (queries != null) { + for (queryAnnotation in queries.value) { + + if (queryAnnotation != null) { + for (field in queryAnnotation.fields) { + if (names.contains(field).not()) { + logger.error("query param [$field] is not a part of this entity", entityElement) + } + } + } + } + } + + for (member in entityElement.enclosedElements) { if (member.kind == ElementKind.CONSTRUCTOR) { diff --git a/couchbase-entity/src/test/java/com/kaufland/CouchbaseBaseBinderProcessorKotlinTest.kt b/couchbase-entity/src/test/java/com/kaufland/CouchbaseBaseBinderProcessorKotlinTest.kt index 37640237..e2be4afe 100644 --- a/couchbase-entity/src/test/java/com/kaufland/CouchbaseBaseBinderProcessorKotlinTest.kt +++ b/couchbase-entity/src/test/java/com/kaufland/CouchbaseBaseBinderProcessorKotlinTest.kt @@ -1,5 +1,6 @@ package com.kaufland +import com.kaufland.testdata.TestDataHelper import com.tschuchort.compiletesting.KotlinCompilation import com.tschuchort.compiletesting.SourceFile import org.junit.Assert @@ -8,6 +9,14 @@ import org.junit.Test class CouchbaseBaseBinderProcessorKotlinTest { + @Test + fun testSucessWithQueries() { + val compilation = compileKotlin(TestDataHelper.clazzAsJavaFileObjects("EntityWithQueries")) + + + Assert.assertEquals(compilation.exitCode, KotlinCompilation.ExitCode.OK) + } + @Test fun testKotlinAbstractGeneration() { diff --git a/couchbase-entity/src/test/java/com/kaufland/testdata/TestDataHelper.kt b/couchbase-entity/src/test/java/com/kaufland/testdata/TestDataHelper.kt new file mode 100644 index 00000000..8b1eb803 --- /dev/null +++ b/couchbase-entity/src/test/java/com/kaufland/testdata/TestDataHelper.kt @@ -0,0 +1,16 @@ +package com.kaufland.testdata + +import com.tschuchort.compiletesting.SourceFile +import java.io.File + +object TestDataHelper { + + private const val PACKAGE_DECLARE = "package com.kaufland.testModels\n" + + fun clazzAsJavaFileObjects(clazz : String) : SourceFile { + val className = "$clazz.kt" + val file = javaClass.classLoader.getResource(className).file + return SourceFile.kotlin(className, "$PACKAGE_DECLARE${File(file).readText()}") + } + +} \ No newline at end of file diff --git a/couchbase-entity/src/test/resources/EntityWithQueries.kt b/couchbase-entity/src/test/resources/EntityWithQueries.kt new file mode 100644 index 00000000..eeeff1db --- /dev/null +++ b/couchbase-entity/src/test/resources/EntityWithQueries.kt @@ -0,0 +1,18 @@ +import kaufland.com.coachbasebinderapi.Entity +import kaufland.com.coachbasebinderapi.Field +import kaufland.com.coachbasebinderapi.Fields +import kaufland.com.coachbasebinderapi.query.Queries +import kaufland.com.coachbasebinderapi.query.Query +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) +) +@Queries( + Query(fields = ["type"]) +) +open class EntityWithQueries \ No newline at end of file diff --git a/demo/src/main/java/kaufland/com/demo/MainActivity.java b/demo/src/main/java/kaufland/com/demo/MainActivity.java index 1778bac9..42638235 100644 --- a/demo/src/main/java/kaufland/com/demo/MainActivity.java +++ b/demo/src/main/java/kaufland/com/demo/MainActivity.java @@ -24,18 +24,8 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); mAdapter = new ProductAdapter(this); - Query query = getQuery(); - query.addChangeListener(change -> { - mAdapter.setNotifyOnChange(false); - mAdapter.clear(); - if (change != null) { - for (Result item : change.getResults()) { - mAdapter.add(new ProductEntity(item.getDictionary(Application.DB).toMap())); - } - } - mAdapter.setNotifyOnChange(true); - mAdapter.notifyDataSetChanged(); - }); + mAdapter.addAll(ProductEntity.findByType()); + mAdapter.notifyDataSetChanged(); ListView listView = findViewById(R.id.list); listView.setAdapter(mAdapter); @@ -45,11 +35,4 @@ protected void onCreate(Bundle savedInstanceState) { }); } - private Query getQuery() { - - Application application = (Application) getApplication(); - Database database = application.getDatabase(); - - return QueryBuilder.select(SelectResult.all()).from(DataSource.database(database)).where(Expression.property("type").equalTo(Expression.string(ProductEntity.DOC_TYPE))); - } } diff --git a/demo/src/main/java/kaufland/com/demo/entity/Product.kt b/demo/src/main/java/kaufland/com/demo/entity/Product.kt index a7dc1780..469803c3 100644 --- a/demo/src/main/java/kaufland/com/demo/entity/Product.kt +++ b/demo/src/main/java/kaufland/com/demo/entity/Product.kt @@ -4,6 +4,8 @@ import com.couchbase.lite.Blob import kaufland.com.coachbasebinderapi.Entity import kaufland.com.coachbasebinderapi.Field import kaufland.com.coachbasebinderapi.Fields +import kaufland.com.coachbasebinderapi.query.Queries +import kaufland.com.coachbasebinderapi.query.Query @Entity(database = "mydb_db") @Fields( @@ -13,4 +15,7 @@ import kaufland.com.coachbasebinderapi.Fields Field(name = "image", type = Blob::class), Field(name = "identifiers", type = String::class, list = true) ) +@Queries( + Query(fields = ["type"]) +) open class Product \ No newline at end of file diff --git a/demo/src/main/java/kaufland/com/demo/tesst/Task.kt b/demo/src/main/java/kaufland/com/demo/tesst/Task.kt index 692261b6..4ca4cf4d 100644 --- a/demo/src/main/java/kaufland/com/demo/tesst/Task.kt +++ b/demo/src/main/java/kaufland/com/demo/tesst/Task.kt @@ -1,16 +1,11 @@ package schwarz.fwws.shared.model -import com.couchbase.lite.Blob -import kaufland.com.coachbasebinderapi.Entity -import kaufland.com.coachbasebinderapi.Field -import kaufland.com.coachbasebinderapi.Fields -import kaufland.com.coachbasebinderapi.MapWrapper -import kaufland.com.demo.Application -import kaufland.com.demo.entity.UserComment -import java.util.* - -@MapWrapper +import kaufland.com.coachbasebinderapi.* +import kaufland.com.coachbasebinderapi.query.Queries +import kaufland.com.coachbasebinderapi.query.Query + +@Entity @Fields( Field(name = "storeId", type = String::class), Field(name = "item_type", type = String::class), @@ -19,15 +14,28 @@ import java.util.* Field(name = "article_no", type = String::class), Field(name = "expiration", type = Long::class) ) +@Queries( + Query(fields = ["type"]), + Query(fields = ["type", "item_type"]) +) open class Task { companion object { + const val TYPE: String = "Task" + + @GenerateAccessor const val PREFIX: String = "task" + fun documentId(storeId: String, article_no: String, process: String, uuid: String): String { return "$PREFIX:$storeId:$article_no:$process:$uuid" } + + @GenerateAccessor + fun ultraComplexQuery(storeId: String){ + + } } // // override fun documentId(): String {