Skip to content

Commit

Permalink
Merge pull request #12 from Kaufland/feature/typeConversion
Browse files Browse the repository at this point in the history
# implemented type conversion
  • Loading branch information
sbra0902 authored Jan 24, 2019
2 parents 81e2a1b + a16d173 commit 5a8b0fb
Show file tree
Hide file tree
Showing 15 changed files with 169 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kaufland.com.coachbasebinderapi;


import java.util.HashMap;
import java.util.Map;

public class PersistenceConfig {
Expand All @@ -15,15 +16,17 @@ private PersistenceConfig(Connector connector) {

public interface Connector {

Map<Class<?>, TypeConversion> getTypeConversions();

Map<String, Object> getDocument(String id, String dbName);

void deleteDocument(String id, String dbName) throws PersistenceException;

void upsertDocument(Map<String, Object> document, String id, String dbName) throws PersistenceException;

}

public static void configure(Connector connector) {

mInstance = new PersistenceConfig(connector);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package kaufland.com.coachbasebinderapi;

public interface TypeConversion {

Object write(Object value);

Object read(Object value);

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,77 @@
import com.couchbase.lite.Document;
import com.couchbase.lite.MutableDocument;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import kaufland.com.coachbasebinderapi.PersistenceConfig;
import kaufland.com.coachbasebinderapi.PersistenceException;
import kaufland.com.coachbasebinderapi.TypeConversion;

public abstract class Couchbase2Connector implements PersistenceConfig.Connector {

protected abstract Database getDatabase(String name);

private Map<Class<?>, TypeConversion> mTypeConversions = new HashMap<>();

public Couchbase2Connector() {
mTypeConversions.put(Integer.class, new TypeConversion() {

@Override
public Object write(Object value) {
return value;
}

@Override
public Object read(Object value) {
if (value instanceof Number) {
return ((Number) value).intValue();
}
if(value instanceof Iterable){
List<Object> result = new ArrayList<>();
for (Object itValue : ((Iterable) value)) {
result.add(read(itValue));
}
return result;
}
return value;
}
});
}

@Override
public Map<Class<?>, TypeConversion> getTypeConversions() {
return mTypeConversions;
}

@Override
public Map<String, Object> getDocument(String docId, String name) {

if(docId == null){
if (docId == null) {
return new HashMap<>();
}

Document document = getDatabase(name).getDocument(docId);
if(document == null){
return new HashMap<>();
if (document == null) {
HashMap<String, Object> result = new HashMap<>();
result.put("_id", docId);
return result;
}
return document.toMap();
Map<String, Object> result = document.toMap();
result.put("_id", docId);
return result;
}

@Override
public void deleteDocument(String id, String dbName) throws PersistenceException {

try {
getDatabase(dbName).delete(getDatabase(dbName).getDocument(id));
Document document = getDatabase(dbName).getDocument(id);
if (document != null) {
getDatabase(dbName).delete(document);
}
} catch (CouchbaseLiteException e) {
throw new PersistenceException(e);
}
Expand All @@ -44,6 +85,9 @@ public void deleteDocument(String id, String dbName) throws PersistenceException
@Override
public void upsertDocument(Map<String, Object> upsert, String docId, String name) throws PersistenceException {

if (upsert.get("_id") == null) {
upsert.put("_id", docId);
}
MutableDocument unsavedDoc = new MutableDocument(docId, upsert);
try {
unsavedDoc.setString("_id", unsavedDoc.getId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public JavaFile generateModel(EntityHolder holder) {
addMethods(create(holder)).
addMethod(contructor(holder)).
addMethod(setAll(holder)).
addMethods(new TypeConversionMethodsGeneration().generate()).
addMethod(getId()).
addMethod(toMap(holder)).
addField(idConstant()).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.kaufland.generation;

import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeVariableName;

import java.util.Arrays;
import java.util.Collection;

import kaufland.com.coachbasebinderapi.PersistenceConfig;
import kaufland.com.coachbasebinderapi.TypeConversion;

public class TypeConversionMethodsGeneration {

public static final String READ_METHOD_NAME = "read";

public static final String WRITE_METHOD_NAME = "write";

private static final String GET_TYPE_CONVERSION_METHOD = "getInstance().getConnector().getTypeConversions";

public Collection<MethodSpec> generate() {

return Arrays.asList(
MethodSpec.methodBuilder(READ_METHOD_NAME).
addParameter(TypeName.OBJECT, "value").
addParameter(Class.class, "clazz").
addTypeVariable(TypeVariableName.get("T")).
returns(TypeVariableName.get("T")).
addCode(CodeBlock.builder().
addStatement("$N conversion = $N." + GET_TYPE_CONVERSION_METHOD + "().get(clazz)", TypeConversion.class.getCanonicalName(), PersistenceConfig.class.getCanonicalName()).
beginControlFlow("if(conversion == null)").
addStatement("return (T) value").
endControlFlow().
addStatement("return (T) conversion.read(value)").
build()).build(),

MethodSpec.methodBuilder(WRITE_METHOD_NAME).
addParameter(TypeName.OBJECT, "value").
addParameter(Class.class, "clazz").
addTypeVariable(TypeVariableName.get("T")).
returns(TypeVariableName.get("T")).
addCode(CodeBlock.builder().
addStatement("$N conversion = $N." + GET_TYPE_CONVERSION_METHOD + "().get(clazz)", TypeConversion.class.getCanonicalName(), PersistenceConfig.class.getCanonicalName()).
beginControlFlow("if(conversion == null)").
addStatement("return (T) value").
endControlFlow().
addStatement("return (T) conversion.write(value)").
build()).build()

);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public JavaFile generateModel(WrapperEntityHolder holder) {
typeBuilder.addMethod(new RebindMethodGeneration().generate(false));
typeBuilder.addMethods(fromMap(holder));
typeBuilder.addMethods(toMap(holder));
typeBuilder.addMethods(new TypeConversionMethodsGeneration().generate());

return JavaFile.builder(holder.getPackage(), typeBuilder.build()).
build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,4 @@ public String getConstantName(){
return ConversionUtil.convertCamelToUnderscore(getDbField()).toUpperCase();
}

public Element getFieldElement() {
return mFieldElement;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.kaufland.model.field;

import com.kaufland.generation.TypeConversionMethodsGeneration;
import com.kaufland.util.TypeUtil;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.MethodSpec;
Expand Down Expand Up @@ -34,18 +35,14 @@ public String getConstantValue() {
return mConstantValue;
}

public void setConstantValue(String constantValue) {
this.mConstantValue = constantValue;
}

@Override
public MethodSpec getter(String dbName, boolean useMDocChanges) {
TypeName returnType = TypeUtil.parseMetaType(getMetaField().getType(), null);

MethodSpec.Builder builder = MethodSpec.methodBuilder("get" + WordUtils.capitalize(getMetaField().getName())).
addModifiers(Modifier.PUBLIC).
returns(returnType).
addStatement("return ($T) mDoc.get($N)", returnType, getConstantName());
addStatement("return " + TypeConversionMethodsGeneration.READ_METHOD_NAME + "(mDoc.get($N), $T.class)", getConstantName(), returnType);
return builder.build();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.kaufland.model.field;

import com.kaufland.ElementMetaModel;
import com.kaufland.generation.TypeConversionMethodsGeneration;
import com.kaufland.util.TypeUtil;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
Expand Down Expand Up @@ -31,6 +32,12 @@ public class CblFieldHolder extends CblBaseFieldHolder {

private boolean subEntityIsTypeParam;

private boolean isIterable;

private String typeParamPackage;

private String typeParamSimpleName;

private CblDefaultHolder defaultHolder;

public CblFieldHolder(Field field, Element fieldElement, JavaField metaField, CblDefaultHolder defaultHolder, ElementMetaModel metaModel) {
Expand All @@ -46,6 +53,12 @@ public CblFieldHolder(Field field, Element fieldElement, JavaField metaField, Cb
for (JavaType typeParameter : ((DefaultJavaParameterizedType) metaField.getType()).getActualTypeArguments()) {

String canonicalName = typeParameter.getCanonicalName();
isIterable = metaField.getType().isArray() || metaField.getType().isA(Iterable.class.getCanonicalName());
if(isIterable){
JavaClass metaClazz = metaModel.getMetaFor(canonicalName);
typeParamSimpleName = metaClazz.getSimpleName();
typeParamPackage = metaClazz.getPackageName();
}
if (metaModel.isMapWrapper(canonicalName)) {
JavaClass metaClazz = metaModel.getMetaFor(canonicalName);
subEntitySimpleName = metaClazz.getSimpleName() + "Wrapper";
Expand All @@ -69,6 +82,14 @@ public boolean isSubEntityIsTypeParam() {
return subEntityIsTypeParam;
}

public boolean isIterable() {
return isIterable;
}

public TypeName getTypeParamTypeName() {
return ClassName.get(typeParamPackage, typeParamSimpleName);
}

public CblDefaultHolder getDefaultHolder() {
return defaultHolder;
}
Expand Down Expand Up @@ -103,20 +124,22 @@ public MethodSpec getter(String dbName, boolean useMDocChanges) {

builder.addStatement("return null");
} else {

TypeName forTypeConversion = evaluateClazzForTypeConversion();
if (useMDocChanges) {
builder.addCode(CodeBlock.builder().beginControlFlow("if(mDocChanges.containsKey($N))", getConstantName()).
addStatement("return ($T) mDocChanges.get($N)", returnType, getConstantName()).
addStatement("return " + TypeConversionMethodsGeneration.READ_METHOD_NAME + "(mDocChanges.get($N), $T.class)", getConstantName(), forTypeConversion).
endControlFlow().
build());
}

builder.addCode(CodeBlock.builder().beginControlFlow("if(mDoc.containsKey($N))", getConstantName()).
addStatement("return ($T) mDoc.get($N)", returnType, getConstantName()).
addStatement("return " + TypeConversionMethodsGeneration.READ_METHOD_NAME + "(mDoc.get($N), $T.class)", getConstantName(), forTypeConversion).
endControlFlow().
build());

if (defaultHolder != null) {
builder.addStatement("return ($T) mDocDefaults.get($N)", returnType, getConstantName());
builder.addStatement("return " + TypeConversionMethodsGeneration.READ_METHOD_NAME + "(mDocDefaults.get($N), $T.class)", getConstantName(), forTypeConversion);
} else {
builder.addStatement("return null");
}
Expand All @@ -141,7 +164,8 @@ public MethodSpec setter(String dbName, TypeName entityTypeName, boolean useMDoc
builder.addStatement("$N.put($N, $T.toMap(($T)value))", docName, getConstantName(), getSubEntityTypeName(), fieldType);
builder.addStatement("return this");
} else {
builder.addStatement("$N.put($N, value)", docName, getConstantName());
TypeName forTypeConversion = evaluateClazzForTypeConversion();
builder.addStatement("$N.put($N, "+ TypeConversionMethodsGeneration.WRITE_METHOD_NAME +"(value, $T.class))", docName, getConstantName(), forTypeConversion);
builder.addStatement("return this");
}

Expand All @@ -157,4 +181,12 @@ public List<FieldSpec> createFieldConstant() {

return Collections.singletonList(fieldAccessorConstant);
}

private TypeName evaluateClazzForTypeConversion(){
if(isIterable && getTypeParamTypeName() != null){
return getTypeParamTypeName();
}

return TypeUtil.parseMetaType(getMetaField().getType(), getSubEntitySimpleName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public void testSuccessProcessing() {
" @Field(\"title\")\n" +
" private String title;\n" +
"\n" +
"\n" +
" @Field(\"count\")\n" +
" private Integer count;\n" +
"\n" +
" @Constant(value = \"type\", constant = \"List\")\n" +
" private String type;\n" +
"\n" +
Expand Down
2 changes: 1 addition & 1 deletion demo/src/main/java/kaufland/com/demo/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ private void createMockArticle() {
setImage(new Blob("image/jpeg", getResources().openRawResource(R.raw.ic_kaufland_placeholder))).
save();
ProductEntity.create().setName("Beer (no alcohol)").
setComments(new ArrayList<>(Arrays.asList(UserCommentWrapper.create().setComment("very bad"), UserCommentWrapper.create().setComment("not tasty")))).
setComments(new ArrayList<>(Arrays.asList(UserCommentWrapper.create().setComment("very bad"), UserCommentWrapper.create().setComment("not tasty").setAge(99)))).
setImage(new Blob("image/jpeg", getResources().openRawResource(R.raw.ic_kaufland_placeholder))).
save();
ProductEntity.create().setName("Wodka").
Expand Down
2 changes: 1 addition & 1 deletion demo/src/main/java/kaufland/com/demo/CommentActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ private List<String> map(List<UserCommentWrapper> userCommentEntities) {
List<String> result = new ArrayList<>();

for (UserCommentWrapper entity : userCommentEntities) {
result.add(entity.getComment() + "\n[" + entity.getUserName() + "]");
result.add(entity.getComment() + "\n[" + entity.getUserName() + "(" + entity.getAge() + ")]");
}

return result;
Expand Down
3 changes: 3 additions & 0 deletions demo/src/main/java/kaufland/com/demo/entity/Product.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,7 @@ public class Product {
@Field(value = "image")
private Blob image;

@Field("identifiers")
private List<String> identifiers;

}

This file was deleted.

4 changes: 4 additions & 0 deletions demo/src/main/java/kaufland/com/demo/entity/UserComment.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ public class UserComment {
@Field("user")
@Default("anonymous")
private String userName;

@Field("age")
@Default("0")
private Integer age;
}

0 comments on commit 5a8b0fb

Please sign in to comment.