Search in sources :

Example 1 with EntityDetail

use of com.coredata.compiler.EntityDetail in project CoreData by FangCloud-Android.

the class BindCursorMethod method bind.

private void bind(MethodSpec.Builder builder) {
    // final int cursorIndexOfId = cursor.getColumnIndexOrThrow("id");
    // final int cursorIndexOfName = cursor.getColumnIndexOrThrow("name");
    // final int cursorIndexOfTags = cursor.getColumnIndexOrThrow("tags");
    // final int cursorIndexOfAuthor = cursor.getColumnIndexOrThrow("author_id");
    // final int cursorIndexOfContent = cursor.getColumnIndexOrThrow("desc_content");
    // final int cursorIndexOfEmail = cursor.getColumnIndexOrThrow("desc_email");
    // List<Book> bookList = new ArrayList<>();
    // Map<Integer, Book> authorIdWithBookMap = new HashMap<>();
    // while (cursor.moveToNext()) {
    // Book book = new Book();
    // book.id = cursor.getLong(cursorIndexOfId);
    // book.name = cursor.getString(cursorIndexOfName);
    // book.tags = __TagListConverter.convertToValue(cursor.getString(cursorIndexOfTags));
    // int authorId = cursor.getInt(cursorIndexOfAuthor);
    // book.desc = new Desc();
    // book.desc.content = cursor.getString(cursorIndexOfContent);
    // book.desc.email = cursor.getString(cursorIndexOfEmail);
    // bookList.add(book);
    // authorIdWithBookMap.put(authorId, book);
    // }
    // List<Author> authorList = __authorCoreDao.queryByKeys(authorIdWithBookMap.keySet().toArray(new Integer[]{}));
    // for (Author author : authorList) {
    // Book book = authorIdWithBookMap.get(author.getId());
    // if (book != null) {
    // book.author = author;
    // }
    // }
    // return bookList;
    TypeName typeNameEntity = ClassName.get(entityDetail.getEntityElement().asType());
    ParameterizedTypeName typeListEntity = ParameterizedTypeName.get(ClassName.get(ArrayList.class), typeNameEntity);
    List<Element> elementsForDb = entityDetail.getDbElements();
    List<Property> properties = entityDetail.getProperties(processingEnv);
    List<Element> relationElements = entityDetail.getRelationElements();
    for (Property property : properties) {
        builder.addStatement("int $N = cursor.getColumnIndexOrThrow($S)", "cursorIndexOf" + property.name, property.name);
    }
    // 创建自己的列表
    builder.addStatement("$T list = new $T()", typeListEntity, typeListEntity);
    // 创建多个关联数据的hashMap,主键类型为key
    for (Element relationElement : relationElements) {
        TypeElement typeRelation = (TypeElement) processingEnv.getTypeUtils().asElement(relationElement.asType());
        EntityDetail relationEntityDetail = EntityDetail.parse(processingEnv, typeRelation);
        Element primaryKeyElement = relationEntityDetail.getPrimaryKey();
        if (primaryKeyElement != null) {
            TypeMirror typeMirror = primaryKeyElement.asType();
            ParameterizedTypeName hashMapType = ParameterizedTypeName.get(ClassName.get(HashMap.class), ClassName.get(typeMirror).box(), typeNameEntity);
            builder.addStatement("$T __$NMap = new $T()", hashMapType, Utils.getColumnName(relationElement), hashMapType);
        }
    }
    builder.addCode("while (cursor.moveToNext()) {\n  ");
    // 创建一个对象
    String itemName = "entity";
    builder.addStatement("$T $N = new $T()", typeNameEntity, itemName, typeNameEntity);
    for (Element element : elementsForDb) {
        bindCursorToField(builder, element, itemName);
    }
    builder.addStatement("list.add(entity)");
    // 将对象放入相应关联对象对应的map
    builder.addCode("}\n");
    // 循环关联对象,赋值给主对象
    for (Element relationElement : relationElements) {
        ClassName classNameRelation = ClassName.bestGuess(relationElement.asType().toString());
        TypeElement typeRelationElement = (TypeElement) processingEnv.getTypeUtils().asElement(relationElement.asType());
        EntityDetail relationEntityDetail = EntityDetail.parse(processingEnv, typeRelationElement);
        Element primaryKeyElement = relationEntityDetail.getPrimaryKey();
        if (primaryKeyElement != null) {
            // List<Author> authorList = __authorCoreDao.queryByKeys(authorIdWithBookMap.keySet().toArray(new Integer[]{}));
            TypeName primaryTypeName = ClassName.get(primaryKeyElement.asType());
            ParameterizedTypeName listRelationType = ParameterizedTypeName.get(ClassName.get(List.class), classNameRelation);
            String listName = String.format("__%sList", typeRelationElement.getSimpleName());
            String mapName = String.format("__%sMap", Utils.getColumnName(relationElement));
            builder.addStatement("$T $N = $N.queryByKeys($N.keySet().toArray(new $T[]{}))", listRelationType, listName, Utils.relationDaoName(classNameRelation), mapName, primaryTypeName.box());
            builder.addCode("for($T item : $N){\n", classNameRelation, listName);
            builder.addStatement("  $T entity = $N.get($N)", typeNameEntity, mapName, Utils.methodGet(primaryKeyElement, "item"));
            builder.addCode("  if(entity != null){\n");
            builder.addStatement(Utils.methodSetFormat(relationElement, "entity"), "item");
            builder.addCode("  }\n");
            builder.addCode("}\n");
        }
    }
    builder.addStatement("return list");
}
Also used : ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) TypeName(com.squareup.javapoet.TypeName) HashMap(java.util.HashMap) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) ArrayList(java.util.ArrayList) TypeMirror(javax.lang.model.type.TypeMirror) ClassName(com.squareup.javapoet.ClassName) ArrayList(java.util.ArrayList) List(java.util.List) EntityDetail(com.coredata.compiler.EntityDetail) Property(com.coredata.db.Property) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName)

Example 2 with EntityDetail

use of com.coredata.compiler.EntityDetail in project CoreData by FangCloud-Android.

the class BindStatementMethod method bindStatementMethodInternal.

private int bindStatementMethodInternal(MethodSpec.Builder builder, List<Element> elements, int index, String prefix, boolean carePrefix) {
    for (Element element : elements) {
        TypeName typeName = ClassName.get(element.asType());
        String fieldGetMethod = Utils.methodGet(element, prefix);
        if (typeName.isPrimitive() || typeName.isBoxedPrimitive()) {
            bindTo(builder, typeName, index, fieldGetMethod, prefix);
        } else {
            // throw exception
            if (typeName.equals(ClassName.get(String.class))) {
                bindTo(builder, typeName, index, fieldGetMethod, prefix);
            } else {
                Embedded embedded = element.getAnnotation(Embedded.class);
                if (embedded != null) {
                    Element elementEmbedded = processingEnv.getTypeUtils().asElement(element.asType());
                    List<Element> elementsForDbEmbedded = new ArrayList<>();
                    Utils.fillElementsForDbAndReturnPrimaryKey(processingEnv, elementsForDbEmbedded, (TypeElement) elementEmbedded);
                    index = bindStatementMethodInternal(builder, elementsForDbEmbedded, index, fieldGetMethod, true);
                    continue;
                }
                Convert convert = element.getAnnotation(Convert.class);
                if (convert != null) {
                    // 转换
                    ClassName classConverter = ClassName.bestGuess(Utils.getConverterType(convert).toString());
                    ClassName dbClassName = ClassName.bestGuess(Utils.getConvertDbType(convert).toString());
                    if (!carePrefix || TextUtils.isEmpty(prefix)) {
                        builder.addStatement("$T __temp_$N = $N", dbClassName, String.valueOf(index), formatBindMethod(fieldGetMethod, Utils.converterName(element, classConverter)));
                    } else {
                        builder.addStatement("$T __temp_$N = $N == null ? $N : $N", dbClassName, String.valueOf(index), prefix, getDefaultValue(dbClassName), formatBindMethod(fieldGetMethod, Utils.converterName(element, classConverter)));
                    }
                    bindTo(builder, dbClassName, index, "__temp_" + index, null);
                } else {
                    Relation relation = element.getAnnotation(Relation.class);
                    if (relation != null) {
                        TypeElement relationType = (TypeElement) processingEnv.getTypeUtils().asElement(element.asType());
                        EntityDetail relationEntityDetail = EntityDetail.parse(processingEnv, relationType);
                        Element relationEntityDetailPrimaryKey = relationEntityDetail.getPrimaryKey();
                        if (relationEntityDetailPrimaryKey == null) {
                            throw new RuntimeException(element.getSimpleName() + "#" + relationType.getSimpleName() + "must add has primaryKey");
                        }
                        TypeName dbClassName = ClassName.get(relationEntityDetailPrimaryKey.asType());
                        builder.addCode("$T __primaryKey_$N = ", dbClassName, String.valueOf(index));
                        if (carePrefix && !TextUtils.isEmpty(prefix)) {
                            builder.addCode("$N == null ? $N : ", prefix, getDefaultValue(dbClassName));
                        }
                        // 拼接当前数据判断为空
                        builder.addCode("($N == null ? $N : ", fieldGetMethod, getDefaultValue(dbClassName));
                        builder.addStatement("$N)", Utils.methodGet(relationEntityDetailPrimaryKey, fieldGetMethod));
                        bindTo(builder, dbClassName, index, "__primaryKey_" + index, null);
                    } else {
                        throw new RuntimeException(element.getSimpleName() + "must add @Relation or @Convert");
                    }
                }
            }
        }
        index++;
    }
    return index;
}
Also used : TypeName(com.squareup.javapoet.TypeName) Relation(com.coredata.annotation.Relation) Convert(com.coredata.annotation.Convert) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) ArrayList(java.util.ArrayList) ClassName(com.squareup.javapoet.ClassName) Embedded(com.coredata.annotation.Embedded) EntityDetail(com.coredata.compiler.EntityDetail)

Example 3 with EntityDetail

use of com.coredata.compiler.EntityDetail in project CoreData by FangCloud-Android.

the class BindCursorMethod method bindCursorToField.

private void bindCursorToField(MethodSpec.Builder builder, Element element, String prefix) {
    // 基本类型
    // String
    // 内嵌类型
    // 关联类型
    // 转换类型
    ClassName stringClassName = ClassName.get(String.class);
    TypeName typeName = ClassName.get(element.asType());
    Element typeElement = processingEnv.getTypeUtils().asElement(element.asType());
    if (typeName.isPrimitive() || typeName.isBoxedPrimitive() || typeName.equals(stringClassName)) {
        // 基础类型 // 封装基础类型 // 字符串类型
        builder.addStatement(Utils.methodSetFormat(element, prefix), cursorGetMethod(element, Utils.getDbType(element)));
    } else {
        Embedded embedded = element.getAnnotation(Embedded.class);
        if (embedded != null) {
            // 内嵌类型循环添加
            // 创建临时变量
            String embeddedTempName = "__" + element.getSimpleName() + "Temp";
            builder.addStatement("$T $N = new $T()", typeName, embeddedTempName, typeName);
            // 赋值
            List<Element> elementsForDbEmbedded = new ArrayList<>();
            Utils.fillElementsForDbAndReturnPrimaryKey(processingEnv, elementsForDbEmbedded, (TypeElement) typeElement);
            ;
            for (Element eleEmbeddedChild : elementsForDbEmbedded) {
                bindCursorToField(builder, eleEmbeddedChild, embeddedTempName);
            }
            builder.addStatement(Utils.methodSetFormat(element, prefix), embeddedTempName);
            return;
        }
        Convert convert = element.getAnnotation(Convert.class);
        if (convert != null) {
            ClassName classConverter = ClassName.bestGuess(Utils.getConverterType(convert).toString());
            TypeName convertDbType = Utils.getConvertDbType(convert);
            if (!convertDbType.isPrimitive()) {
                builder.addCode("if(!cursor.isNull(cursorIndexOf$N)){\n  ", Utils.getColumnName(element));
            }
            builder.addStatement(Utils.methodSetFormat(element, prefix), Utils.converterName(element, classConverter) + ".convertToValue(" + cursorGetMethod(element, Utils.getDbType(element)) + ")");
            if (!convertDbType.isPrimitive()) {
                builder.addCode("}");
            }
            return;
        }
        Relation relation = element.getAnnotation(Relation.class);
        if (relation != null) {
            TypeElement typeRelation = (TypeElement) processingEnv.getTypeUtils().asElement(element.asType());
            EntityDetail relationEntityDetail = EntityDetail.parse(processingEnv, typeRelation);
            Element primaryKeyElement = relationEntityDetail.getPrimaryKey();
            if (primaryKeyElement != null) {
                TypeName typePrimary = ClassName.get(primaryKeyElement.asType());
                String columnName = Utils.getColumnName(element);
                if (!typePrimary.isPrimitive()) {
                    builder.addCode("if(!cursor.isNull(cursorIndexOf$N)){\n  ", columnName);
                }
                builder.addStatement("__$NMap.put($N, entity)", columnName, cursorGetMethod(element, Utils.getDbType(primaryKeyElement)));
                if (!typePrimary.isPrimitive()) {
                    builder.addCode("}");
                }
            }
            return;
        }
    }
}
Also used : ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) TypeName(com.squareup.javapoet.TypeName) Relation(com.coredata.annotation.Relation) Convert(com.coredata.annotation.Convert) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) ClassName(com.squareup.javapoet.ClassName) ArrayList(java.util.ArrayList) Embedded(com.coredata.annotation.Embedded) EntityDetail(com.coredata.compiler.EntityDetail)

Example 4 with EntityDetail

use of com.coredata.compiler.EntityDetail in project CoreData by FangCloud-Android.

the class Utils method getProperties.

public static List<Property> getProperties(ProcessingEnvironment env, List<Element> elements, Element primaryKey) {
    Elements elementUtils = env.getElementUtils();
    Types typeUtils = env.getTypeUtils();
    List<Property> propertyList = new ArrayList<>();
    for (Element element : elements) {
        String columnName = Utils.getColumnName(element);
        TypeName dbBaseType;
        TypeMirror typeMirror = element.asType();
        TypeName typeNameElement = ClassName.get(typeMirror);
        if (Utils.isBaseType(typeNameElement)) {
            dbBaseType = typeNameElement;
        } else {
            TypeElement elementFieldType = (TypeElement) typeUtils.asElement(typeMirror);
            Relation annotationRelation = element.getAnnotation(Relation.class);
            if (annotationRelation != null) {
                // 关联数据
                Entity relationEntity = elementFieldType.getAnnotation(Entity.class);
                if (relationEntity == null) {
                    throw new IllegalStateException("@Relation 添加的属性必须是 @Entity 的类");
                }
                EntityDetail relationEntityDetail = EntityDetail.parse(env, elementFieldType);
                Element relationEntityPrimaryKey = relationEntityDetail.getPrimaryKey();
                if (relationEntityPrimaryKey == null) {
                    throw new IllegalStateException(relationEntityDetail.getEntityName() + "是关联类型,@Relation 属性必须有主键");
                }
                dbBaseType = ClassName.get(relationEntityPrimaryKey.asType());
            } else {
                Embedded embedded = element.getAnnotation(Embedded.class);
                if (embedded != null) {
                    // 内嵌数据, 循环解析内嵌结构的字段
                    List<Element> embeddedEleList = new ArrayList<>();
                    fillElementsForDbAndReturnPrimaryKey(env, embeddedEleList, (TypeElement) typeUtils.asElement(typeMirror));
                    propertyList.addAll(getProperties(env, embeddedEleList, null));
                    continue;
                } else {
                    Convert convert = element.getAnnotation(Convert.class);
                    if (convert != null) {
                        TypeName classConvertDb = Utils.getConvertDbType(convert);
                        if (Utils.isBaseType(classConvertDb)) {
                            dbBaseType = classConvertDb;
                        } else {
                            throw new IllegalStateException(element.getSimpleName() + "converter dbtype is not a base type");
                        }
                    } else {
                        throw new IllegalStateException(element.getSimpleName() + " is a complex structure field," + "must indicate it as @Relation or @Embedded, " + "or supply a @Convert for it");
                    }
                }
            }
        }
        propertyList.add(new Property(columnName, Utils.getTypeByTypeName(dbBaseType), element == primaryKey));
    }
    return propertyList;
}
Also used : Types(javax.lang.model.util.Types) Entity(com.coredata.annotation.Entity) TypeName(com.squareup.javapoet.TypeName) Convert(com.coredata.annotation.Convert) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) ArrayList(java.util.ArrayList) Elements(javax.lang.model.util.Elements) Relation(com.coredata.annotation.Relation) TypeMirror(javax.lang.model.type.TypeMirror) Embedded(com.coredata.annotation.Embedded) EntityDetail(com.coredata.compiler.EntityDetail) Property(com.coredata.db.Property)

Aggregations

EntityDetail (com.coredata.compiler.EntityDetail)4 TypeName (com.squareup.javapoet.TypeName)4 ArrayList (java.util.ArrayList)4 Element (javax.lang.model.element.Element)4 TypeElement (javax.lang.model.element.TypeElement)4 Convert (com.coredata.annotation.Convert)3 Embedded (com.coredata.annotation.Embedded)3 Relation (com.coredata.annotation.Relation)3 ClassName (com.squareup.javapoet.ClassName)3 Property (com.coredata.db.Property)2 ParameterizedTypeName (com.squareup.javapoet.ParameterizedTypeName)2 TypeMirror (javax.lang.model.type.TypeMirror)2 Entity (com.coredata.annotation.Entity)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Elements (javax.lang.model.util.Elements)1 Types (javax.lang.model.util.Types)1