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");
}
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;
}
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;
}
}
}
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;
}
Aggregations