Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*******************************************************************************
* Copyright 2015, 2017 Francesco Benincasa ([email protected]).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package com.abubusoft.kripton.processor.sqlite;
import static com.abubusoft.kripton.processor.core.reflect.PropertyUtility.getter;
import static com.abubusoft.kripton.processor.core.reflect.TypeUtility.isTypeIncludedIn;
import static com.abubusoft.kripton.processor.core.reflect.TypeUtility.typeName;
import java.util.List;
import javax.lang.model.element.Modifier;
import com.abubusoft.kripton.android.annotation.BindSqlDelete;
import com.abubusoft.kripton.android.annotation.BindSqlUpdate;
import com.abubusoft.kripton.android.sqlite.KriptonContentValues;
import com.abubusoft.kripton.android.sqlite.KriptonDatabaseWrapper;
import com.abubusoft.kripton.common.One;
import com.abubusoft.kripton.common.Pair;
import com.abubusoft.kripton.common.StringUtils;
import com.abubusoft.kripton.processor.BaseProcessor;
import com.abubusoft.kripton.processor.core.AssertKripton;
import com.abubusoft.kripton.processor.core.reflect.TypeUtility;
import com.abubusoft.kripton.processor.exceptions.InvalidMethodSignException;
import com.abubusoft.kripton.processor.sqlite.GenericSQLHelper.SubjectType;
import com.abubusoft.kripton.processor.sqlite.SqlModifyBuilder.ModifyCodeGenerator;
import com.abubusoft.kripton.processor.sqlite.grammars.jql.JQL.JQLDynamicStatementType;
import com.abubusoft.kripton.processor.sqlite.grammars.jql.JQL.JQLType;
import com.abubusoft.kripton.processor.sqlite.grammars.jql.JQLChecker;
import com.abubusoft.kripton.processor.sqlite.grammars.jql.JQLReplacerListenerImpl;
import com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Where_stmtContext;
import com.abubusoft.kripton.processor.sqlite.model.SQLProperty;
import com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition;
import com.abubusoft.kripton.processor.sqlite.model.SQLiteEntity;
import com.abubusoft.kripton.processor.sqlite.model.SQLiteModelMethod;
import com.abubusoft.kripton.processor.sqlite.transform.SQLTransformer;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import android.database.sqlite.SQLiteStatement;
/**
* The Class ModifyBeanHelper.
*
* @author Francesco Benincasa ([email protected])
*/
public class ModifyBeanHelper implements ModifyCodeGenerator {
/*
* (non-Javadoc)
*
* @see com.abubusoft.kripton.processor.sqlite.SqlModifyBuilder.
* ModifyCodeGenerator#generate(com.squareup.javapoet.TypeSpec.Builder,
* com.squareup.javapoet.MethodSpec.Builder, boolean,
* com.abubusoft.kripton.processor.sqlite.model.SQLiteModelMethod,
* com.squareup.javapoet.TypeName)
*/
@Override
public void generate(TypeSpec.Builder classBuilder, MethodSpec.Builder methodBuilder, boolean updateMode, SQLiteModelMethod method, TypeName returnType) {
String beanNameParameter = method.getParameters().get(0).value0;
AssertKripton.assertTrueOrInvalidMethodSignException(!method.hasAdapterForParam(beanNameParameter), method, "method's parameter '%s' can not use a type adapter", beanNameParameter);
SqlAnalyzer analyzer = new SqlAnalyzer();
String whereCondition = ModifyRawHelper.extractWhereConditions(updateMode, method);
if (StringUtils.hasText(whereCondition)) {
whereCondition = whereCondition.trim();
}
analyzer.execute(BaseProcessor.elementUtils, method, whereCondition);
// retrieve content values
if (method.jql.hasDynamicParts() || method.jql.containsSelectOperation) {
methodBuilder.addStatement("$T _contentValues=contentValuesForUpdate()", KriptonContentValues.class);
} else {
String psName = method.buildPreparedStatementName();
// generate SQL for insert
classBuilder.addField(FieldSpec.builder(TypeName.get(SQLiteStatement.class), psName, Modifier.PRIVATE, Modifier.STATIC).build());
methodBuilder.beginControlFlow("if ($L==null)", psName);
SqlBuilderHelper.generateSQLForStaticQuery(method, methodBuilder);
methodBuilder.addStatement("$L = $T.compile(_context, _sql)", psName, KriptonDatabaseWrapper.class);
methodBuilder.endControlFlow();
methodBuilder.addStatement("$T _contentValues=contentValuesForUpdate($L)", KriptonContentValues.class, psName);
}
List listUsedProperty;
if (updateMode) {
listUsedProperty = CodeBuilderUtility.extractUsedProperties(methodBuilder, method, BindSqlUpdate.class);
AssertKripton.assertTrueOrInvalidMethodSignException(listUsedProperty.size() > 0, method, "no column was selected for update");
CodeBuilderUtility.generateContentValuesFromEntity(BaseProcessor.elementUtils, method, BindSqlUpdate.class, methodBuilder, analyzer.getUsedBeanPropertyNames());
} else {
listUsedProperty = CodeBuilderUtility.extractUsedProperties(methodBuilder, method, BindSqlDelete.class);
}
// build javadoc
buildJavadoc(methodBuilder, updateMode, method, beanNameParameter, whereCondition, listUsedProperty, analyzer.getUsedBeanPropertyNames());
// build where condition
generateWhereCondition(methodBuilder, method, analyzer);
methodBuilder.addCode("\n");
generateModifyQueryCommonPart(method, classBuilder, methodBuilder);
SQLiteDaoDefinition daoDefinition = method.getParent();
// support for livedata
if (daoDefinition.hasLiveData()) {
methodBuilder.addComment("support for livedata");
methodBuilder.addStatement(BindDaoBuilder.METHOD_NAME_REGISTRY_EVENT + "(result)");
}
// define return value
buildReturnCode(methodBuilder, updateMode, method, returnType);
}
/**
* Generate modify query common part.
*
* @param method
* the method
* @param classBuilder
* the class builder
* @param methodBuilder
* the method builder
*/
static void generateModifyQueryCommonPart(SQLiteModelMethod method, TypeSpec.Builder classBuilder, MethodSpec.Builder methodBuilder) {
boolean updateMode = (method.jql.operationType == JQLType.UPDATE);
SqlModifyBuilder.generateInitForDynamicWhereVariables(method, methodBuilder, method.dynamicWhereParameterName, method.dynamicWhereArgsParameterName);
if (method.jql.hasDynamicParts() || method.jql.containsSelectOperation) {
// query builder
if (method.jql.isWhereConditions()) {
methodBuilder.addStatement("$T _sqlBuilder=sqlBuilder()", StringBuilder.class);
}
// generate where condition
SqlBuilderHelper.generateWhereCondition(methodBuilder, method, true);
// generate SQL
SqlModifyBuilder.generateSQL(method, methodBuilder);
}
if (method.isLogEnabled()) {
// generate log section
methodBuilder.addComment("log section BEGIN");
methodBuilder.beginControlFlow("if (_context.isLogEnabled())");
SqlModifyBuilder.generateLogForModifiers(method, methodBuilder);
if (method.jql.operationType == JQLType.UPDATE && method.isLogEnabled()) {
// generate log for content values
SqlBuilderHelper.generateLogForContentValues(method, methodBuilder);
}
SqlBuilderHelper.generateLogForWhereParameters(method, methodBuilder);
methodBuilder.endControlFlow();
methodBuilder.addComment("log section END");
}
if (method.jql.hasDynamicParts() || method.jql.containsSelectOperation) {
// does not memorize compiled statement, it can vary every time
// generate SQL for insert
methodBuilder.addStatement("int result = $T.updateDelete(_context, _sql, _contentValues)", KriptonDatabaseWrapper.class);
} else {
String psName = method.buildPreparedStatementName();
methodBuilder.addStatement("int result = $T.updateDelete($L, _contentValues)", KriptonDatabaseWrapper.class, psName);
}
if (method.getParent().getParent().generateRx) {
if (updateMode) {
GenericSQLHelper.generateSubjectNext(method.getEntity(), methodBuilder, SubjectType.UPDATE, "result");
} else {
GenericSQLHelper.generateSubjectNext(method.getEntity(), methodBuilder, SubjectType.DELETE, "result");
}
}
}
/**
* Generate where condition.
*
* @param methodBuilder
* the method builder
* @param method
* the method
* @param analyzer
* the analyzer
*/
public void generateWhereCondition(MethodSpec.Builder methodBuilder, SQLiteModelMethod method, SqlAnalyzer analyzer) {
SQLiteEntity entity = method.getEntity();
String beanParamName = method.getParameters().get(0).value0;
SQLProperty property;
boolean nullable;
TypeName beanClass = typeName(entity.getElement());
// methodBuilder.addStatement("$T
// _sqlWhereParams=getWhereParamsArray()", ArrayList.class);
for (String item : analyzer.getUsedBeanPropertyNames()) {
property = entity.findPropertyByName(item);
// methodBuilder.addCode("_sqlWhereParams.add(");
methodBuilder.addCode("_contentValues.addWhereArgs(");
nullable = TypeUtility.isNullable(property);
if (nullable && !(property.hasTypeAdapter())) {
// transform null in ""
methodBuilder.addCode("($L==null?\"\":", getter(beanParamName, beanClass, property));
}
// check for string conversion
TypeUtility.beginStringConversion(methodBuilder, property);
SQLTransformer.javaProperty2WhereCondition(methodBuilder, method, beanParamName, beanClass, property);
// check for string conversion
TypeUtility.endStringConversion(methodBuilder, property);
if (nullable && !(property.hasTypeAdapter())) {
methodBuilder.addCode(")");
}
methodBuilder.addCode(");\n");
}
}
/**
* Builds the return code.
*
* @param methodBuilder
* the method builder
* @param updateMode
* the update mode
* @param method
* the method
* @param returnType
* the return type
*/
public void buildReturnCode(MethodSpec.Builder methodBuilder, boolean updateMode, SQLiteModelMethod method, TypeName returnType) {
if (returnType == TypeName.VOID) {
} else if (isTypeIncludedIn(returnType, Boolean.TYPE, Boolean.class)) {
methodBuilder.addJavadoc("\n");
if (updateMode)
methodBuilder.addJavadoc("@return true if record is updated, false otherwise");
else
methodBuilder.addJavadoc("@return true if record is deleted, false otherwise");
methodBuilder.addJavadoc("\n");
methodBuilder.addCode("return result!=0;\n");
} else if (isTypeIncludedIn(returnType, Long.TYPE, Long.class, Integer.TYPE, Integer.class, Short.TYPE, Short.class)) {
methodBuilder.addJavadoc("\n");
if (updateMode) {
methodBuilder.addJavadoc("@return number of updated records");
} else {
methodBuilder.addJavadoc("@return number of deleted records");
}
methodBuilder.addJavadoc("\n");
methodBuilder.addCode("return result;\n");
} else {
// more than one listener found
throw (new InvalidMethodSignException(method, "invalid return type"));
}
}
/**
* Builds the javadoc.
*
* @param methodBuilder
* the method builder
* @param updateMode
* the update mode
* @param method
* the method
* @param beanNameParameter
* the bean name parameter
* @param whereCondition
* the where condition
* @param listUsedProperty
* the list used property
* @param attributesUsedInWhereConditions
* the attributes used in where conditions
* @return the string
*/
public String buildJavadoc(MethodSpec.Builder methodBuilder, boolean updateMode, final SQLiteModelMethod method, String beanNameParameter, String whereCondition,
List listUsedProperty, List attributesUsedInWhereConditions) {
// SQLDaoDefinition daoDefinition = method.getParent();
// SQLEntity entity = daoDefinition.getEntity();
// in this case, only one parameter can exists for method
Pair beanParameter = method.getParameters().get(0);
String sqlResult;
// generate javadoc
StringBuilder buffer = new StringBuilder();
StringBuilder bufferQuestion = new StringBuilder();
String separator = "";
for (SQLProperty property : listUsedProperty) {
// this line genearate only :{attribute}
buffer.append(String.format("%s%s=" + SqlAnalyzer.PARAM_PREFIX + "%s" + SqlAnalyzer.PARAM_SUFFIX, separator, property.columnName, property.getName()));
bufferQuestion.append(separator);
bufferQuestion.append(property.columnName + "=");
bufferQuestion.append("'\"+StringUtils.checkSize(_contentValues.get(\"" + property.columnName + "\"))+\"'");
separator = ", ";
}
String sqlForJavaDoc = extractSQLForJavaDoc(method);
sqlResult = method.jql.value;
if (updateMode) {
// query
methodBuilder.addJavadoc("
SQL update
\n");
methodBuilder.addJavadoc("
$L
", sqlForJavaDoc);
methodBuilder.addJavadoc("\n\n");
// list of updated fields
// Set
// updateColumns=JQLChecker.getInstance().extractColumnsToUpdate(method.jql.value,
// entity);
methodBuilder.addJavadoc("
");
methodBuilder.addJavadoc("\n\n");
}
if (attributesUsedInWhereConditions.size() > 0) {
// list of attributes used in where condition
methodBuilder.addJavadoc("
Parameters used in where conditions:
\n");
methodBuilder.addJavadoc("
\n");
for (String attribute : attributesUsedInWhereConditions) {
methodBuilder.addJavadoc("\t