Search in sources :

Example 1 with Relation

use of com.coredata.annotation.Relation 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 2 with Relation

use of com.coredata.annotation.Relation 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 3 with Relation

use of com.coredata.annotation.Relation 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

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