use of com.abubusoft.kripton.processor.exceptions.PropertyNotFoundException in project kripton by xcesco.
the class BindDataSourceSubProcessor method createSQLEntityFromDao.
/**
* <p>
* Create bean's definition for each dao definition contained in dataSource
* </p>
*
* @param dataSource
* @param daoName
*/
private boolean createSQLEntityFromDao(final SQLiteDatabaseSchema schema, Element dataSource, String daoName) {
TypeElement daoElement = globalDaoElements.get(daoName);
if (daoElement == null) {
String msg = String.format("Data source %s references a DAO %s without @BindDao annotation", dataSource.toString(), daoName);
throw (new InvalidNameException(msg));
}
ModelProperty property;
String beanName = AnnotationUtility.extractAsClassName(daoElement, BindDao.class, AnnotationAttributeType.VALUE);
if (!StringUtils.hasText(beanName)) {
return false;
}
final TypeElement beanElement = globalBeanElements.get(beanName);
// this.isGeneratedEntity(beanName);
AssertKripton.asserTrueOrMissedAnnotationOnClassException(beanElement != null, daoElement, beanName);
// create equivalent entity in the domain of bind processor
final BindEntity bindEntity = BindEntityBuilder.parse(null, beanElement);
// assert: bean is present
final SQLiteEntity currentEntity = new SQLiteEntity(schema, bindEntity);
if (schema.contains(currentEntity.getName())) {
// bean already defined in datasource
return true;
}
final boolean bindAllFields = AnnotationUtility.getAnnotationAttributeAsBoolean(currentEntity, BindType.class, AnnotationAttributeType.ALL_FIELDS, Boolean.TRUE);
{
PropertyUtility.buildProperties(elementUtils, currentEntity, new PropertyFactory<SQLiteEntity, SQLProperty>() {
@Override
public SQLProperty createProperty(SQLiteEntity entity, Element propertyElement) {
return new SQLProperty(entity, propertyElement, AnnotationUtility.buildAnnotationList(propertyElement));
}
}, propertyAnnotationFilter, new PropertyCreatedListener<SQLiteEntity, SQLProperty>() {
@Override
public boolean onProperty(SQLiteEntity entity, SQLProperty property) {
if (property.hasAnnotation(BindDisabled.class)) {
if (bindAllFields) {
return false;
} else {
throw new InvalidDefinition("@BindDisabled can not be used with @BindType(allField=false)");
}
}
ModelAnnotation annotationBindColumn = property.getAnnotation(BindColumn.class);
if (annotationBindColumn != null && AnnotationUtility.extractAsBoolean(property, annotationBindColumn, AnnotationAttributeType.ENABLED) == false) {
return false;
}
if (!bindAllFields && annotationBindColumn == null) {
return false;
}
if (annotationBindColumn != null) {
property.setNullable(AnnotationUtility.extractAsBoolean(property, annotationBindColumn, AnnotationAttributeType.NULLABLE));
ColumnType columnType = ColumnType.valueOf(AnnotationUtility.extractAsEnumerationValue(property, annotationBindColumn, AnnotationAttributeType.COLUMN_TYPE));
property.columnType = columnType;
property.setPrimaryKey(columnType == ColumnType.PRIMARY_KEY);
String foreignClassName = annotationBindColumn.getAttributeAsClassName(AnnotationAttributeType.FOREIGN_KEY);
property.foreignClassName = foreignClassName;
if (property.hasForeignKeyClassName() && property.columnType == ColumnType.PRIMARY_KEY) {
AssertKripton.failIncompatibleAttributesInAnnotationException("In class '%s' property '%s' can not be defined as PRIMARY KEY and FOREIGN KEY", bindEntity.getElement().asType(), property.getName());
}
ForeignKeyAction onDeleteAction = ForeignKeyAction.valueOf(AnnotationUtility.extractAsEnumerationValue(property, annotationBindColumn, AnnotationAttributeType.ON_DELETE));
ForeignKeyAction onUpdateAction = ForeignKeyAction.valueOf(AnnotationUtility.extractAsEnumerationValue(property, annotationBindColumn, AnnotationAttributeType.ON_UPDATE));
if (!property.hasForeignKeyClassName() && onDeleteAction != ForeignKeyAction.NO_ACTION) {
String msg = String.format("In class '%s', property '%s' defines 'onDelete' attribute but it is not a foreign key", bindEntity.getElement().asType(), property.getName());
AssertKripton.failIncompatibleAttributesInAnnotationException(msg);
}
if (!property.hasForeignKeyClassName() && onUpdateAction != ForeignKeyAction.NO_ACTION) {
String msg = String.format("In class '%s', property '%s' defines 'onUpdate' attribute but it is not a foreign key", bindEntity.getElement().asType(), property.getName());
AssertKripton.failIncompatibleAttributesInAnnotationException(msg);
}
property.onDeleteAction = onDeleteAction;
property.onUpdateAction = onUpdateAction;
} else {
// primary key is set in other places
property.setNullable(true);
// ColumnType columnType = ColumnType.STANDARD;
property.columnType = ColumnType.STANDARD;
}
if (bindEntity.contains(property.getName())) {
BindProperty bindProperty = bindEntity.get(property.getName());
if (bindProperty.isBindedArray() || bindProperty.isBindedCollection() || bindProperty.isBindedMap() || bindProperty.isBindedObject()) {
property.bindProperty = bindProperty;
}
} else {
throw (new KriptonRuntimeException(String.format("In class '%s' property '%s' has a wrong definition for create SQLite DataSource", bindEntity.getElement().asType(), property.getName())));
}
String columnName = null;
if (annotationBindColumn != null) {
columnName = annotationBindColumn.getAttribute(AnnotationAttributeType.VALUE);
}
if (!StringUtils.hasText(columnName)) {
columnName = property.getName();
}
// convert column typeName from field typeName to table:
// fieldName
// to field_name
property.columnName = schema.columnNameConverter.convert(columnName);
return true;
}
});
}
// just to fix that property id can be the default PK without
// annotation.
// this operation force primary key flag for property
SQLProperty primaryKey = currentEntity.getPrimaryKey();
if (primaryKey != null) {
primaryKey.setPrimaryKey(true);
primaryKey.columnType = ColumnType.PRIMARY_KEY;
primaryKey.setNullable(false);
}
if (currentEntity.getCollection().size() == 0) {
String msg = String.format("Class '%s', used in %s database definition, has no property!", currentEntity.getName(), dataSource.getSimpleName().toString());
throw (new PropertyNotFoundException(msg));
}
if (currentEntity.countPrimaryKeys() > 1) {
throw (new TooManySQLPrimaryKeyFoundException(currentEntity));
}
// check primary key
property = currentEntity.getPrimaryKey();
if (property == null)
throw (new SQLPrimaryKeyNotFoundException(currentEntity));
if (!property.isType(Long.TYPE, Long.class))
throw (new SQLPrimaryKeyNotValidTypeException(currentEntity, property));
// add entity to schema after properties definition!
schema.addEntity(currentEntity);
return true;
}
use of com.abubusoft.kripton.processor.exceptions.PropertyNotFoundException in project kripton by xcesco.
the class GenericSQLHelper method generateGenericExecSQL.
/**
* @param methodBuilder
* @param method
* @param daoDefinition
* @param schema
*/
public static void generateGenericExecSQL(MethodSpec.Builder methodBuilder, final SQLiteModelMethod method) {
final SQLiteDaoDefinition daoDefinition = method.getParent();
boolean nullable;
final List<String> paramsList = new ArrayList<String>();
final List<String> contentValueList = new ArrayList<String>();
final One<Boolean> columnsToUpdate = new One<Boolean>(true);
String sql = JQLChecker.getInstance().replace(method, method.jql, new JQLReplacerListenerImpl(method) {
@Override
public void onWhereStatementBegin(Where_stmtContext ctx) {
super.onWhereStatementBegin(ctx);
columnsToUpdate.value0 = false;
}
@Override
public void onWhereStatementEnd(Where_stmtContext ctx) {
super.onWhereStatementEnd(ctx);
columnsToUpdate.value0 = true;
}
@Override
public String onColumnName(String columnName) {
String resolvedName = currentSchema.findColumnNameByPropertyName(method, columnName);
AssertKripton.assertTrueOrUnknownPropertyInJQLException(resolvedName != null, method, columnName);
return resolvedName;
}
@Override
public String onBindParameter(String bindParameterName) {
String propertyName = method.findParameterAliasByName(bindParameterName);
if (columnsToUpdate.value0) {
contentValueList.add(propertyName);
} else {
paramsList.add(propertyName);
}
return "?";
}
});
// update/insert columns
final SQLiteEntity entity = daoDefinition.getEntity();
for (String item : contentValueList) {
// ASSERT: property is always in entity
String propertyName = method.findParameterNameByAlias(item);
TypeName paramType = method.findParameterTypeByAliasOrName(item);
SQLProperty property = entity.get(item);
if (propertyName == null)
throw (new PropertyNotFoundException(method, propertyName, paramType));
Pair<String, TypeName> methodParam = new Pair<String, TypeName>(propertyName, paramType);
// check same type
TypeUtility.checkTypeCompatibility(method, methodParam, property);
if (method.isLogEnabled()) {
methodBuilder.addCode("_contentValues.put($S, ", property.columnName);
} else {
methodBuilder.addCode("_contentValues.put(");
}
// it does not need to be converted in string
SQLTransformer.javaMethodParam2ContentValues(methodBuilder, method, methodParam.value0, methodParam.value1, property);
methodBuilder.addCode(");\n");
// if (nullable) {
// methodBuilder.nextControlFlow("else");
//
// if (method.isLogEnabled()) {
// methodBuilder.addStatement("_contentValues.putNull($S)", property.columnName);
// } else {
// methodBuilder.addStatement("_contentValues.putNull()");
// }
//
// methodBuilder.endControlFlow();
// }
}
// where condition
methodBuilder.addComment("build where condition");
{
// String separator = "";
TypeName paramType;
String realName;
for (String item : paramsList) {
methodBuilder.addCode("_contentValues.addWhereArgs(");
paramType = method.findParameterTypeByAliasOrName(item);
realName = method.findParameterNameByAlias(item);
AssertKripton.assertTrueOrUnknownPropertyInJQLException(paramType != null, method, item);
// code for query arguments
nullable = TypeUtility.isNullable(paramType);
if (nullable) {
methodBuilder.addCode("($L==null?\"\":", realName);
}
// check for string conversion
TypeUtility.beginStringConversion(methodBuilder, paramType);
SQLTransformer.javaMethodParam2ContentValues(methodBuilder, method, realName, paramType, null);
// check for string conversion
TypeUtility.endStringConversion(methodBuilder, paramType);
if (nullable) {
methodBuilder.addCode(")");
}
methodBuilder.addCode(");\n");
}
}
// log for where parames
SqlBuilderHelper.generateLog(method, methodBuilder);
// log
methodBuilder.addCode("\n");
methodBuilder.addStatement("database().execSQL($S, _contentValues.whereArgsAsArray())", sql);
}
use of com.abubusoft.kripton.processor.exceptions.PropertyNotFoundException in project kripton by xcesco.
the class InsertRawHelper method generate.
@Override
public void generate(TypeSpec.Builder classBuilder, MethodSpec.Builder methodBuilder, boolean mapFields, final SQLiteModelMethod method, TypeName returnType) {
final SQLiteDaoDefinition daoDefinition = method.getParent();
final SQLiteEntity entity = daoDefinition.getEntity();
// boolean nullable;
// generate javadoc
generateJavaDoc(methodBuilder, method, returnType);
// standard INSERT
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);
}
if (method.jql.containsSelectOperation) {
// INSERT-SELECT
GenericSQLHelper.generateGenericExecSQL(methodBuilder, method);
} else {
methodBuilder.addCode("\n");
List<Pair<String, TypeName>> fieldsToUpdate = method.getParameters();
fieldsToUpdate = SqlBuilderHelper.orderContentValues(method, fieldsToUpdate);
for (Pair<String, TypeName> item : fieldsToUpdate) {
String propertyName = method.findParameterAliasByName(item.value0);
SQLProperty property = entity.get(propertyName);
if (property == null)
throw (new PropertyNotFoundException(method, propertyName, item.value1));
// check same type
TypeUtility.checkTypeCompatibility(method, item, property);
if (method.isLogEnabled()) {
methodBuilder.addCode("_contentValues.put($S, ", property.columnName);
} else {
methodBuilder.addCode("_contentValues.put(");
}
// it does not need to be converted in string
SQLTransformer.javaMethodParam2ContentValues(methodBuilder, method, item.value0, item.value1, property);
methodBuilder.addCode(");\n");
}
methodBuilder.addCode("\n");
SqlBuilderHelper.generateLog(method, methodBuilder);
methodBuilder.addComment("insert operation");
if (method.jql.hasDynamicParts() || method.jql.containsSelectOperation) {
// does not memorize compiled statement, it can vary every time generate SQL for insert
SqlBuilderHelper.generateSQLForInsertDynamic(method, methodBuilder);
methodBuilder.addStatement("long result = $T.insert(_context, _sql, _contentValues)", KriptonDatabaseWrapper.class);
} else {
String psName = method.buildPreparedStatementName();
methodBuilder.addStatement("long result = $T.insert($L, _contentValues)", KriptonDatabaseWrapper.class, psName);
}
if (daoDefinition.getParent().generateRx) {
GenericSQLHelper.generateSubjectNext(methodBuilder, SubjectType.INSERT);
}
// support for livedata
if (daoDefinition.hasLiveData()) {
methodBuilder.addComment("support for livedata");
methodBuilder.addStatement(BindDaoBuilder.METHOD_NAME_REGISTRY_EVENT + "(result)");
}
// define return value
if (returnType == TypeName.VOID) {
} else if (TypeUtility.isTypeIncludedIn(returnType, Boolean.TYPE, Boolean.class)) {
methodBuilder.addCode("return result!=-1;\n");
} else if (TypeUtility.isTypeIncludedIn(returnType, Long.TYPE, Long.class)) {
methodBuilder.addCode("return result;\n");
} else if (TypeUtility.isTypeIncludedIn(returnType, Integer.TYPE, Integer.class)) {
methodBuilder.addCode("return (int)result;\n");
} else {
// more than one listener found
throw (new InvalidMethodSignException(method, "invalid return type"));
}
}
}
use of com.abubusoft.kripton.processor.exceptions.PropertyNotFoundException in project kripton by xcesco.
the class ModifyRawHelper method generate.
@Override
public void generate(TypeSpec.Builder classBuilder, MethodSpec.Builder methodBuilder, boolean updateMode, SQLiteModelMethod method, TypeName returnType) {
SQLiteDaoDefinition daoDefinition = method.getParent();
SQLiteEntity entity = daoDefinition.getEntity();
// separate params used for update bean and params used in
// whereCondition
// analyze whereCondition
String whereCondition = extractWhereConditions(updateMode, method);
// this method is invoked to check if every parameter is binded to an method param
SqlUtility.extractParametersFromString(method.jql.value, method, entity);
Pair<String, List<Pair<String, TypeName>>> where = SqlUtility.extractParametersFromString(whereCondition, method, entity);
// defines which parameter is used like update field and which is used
// in where condition.
List<Pair<String, TypeName>> methodParams = method.getParameters();
List<Pair<String, TypeName>> updateableParams = new ArrayList<Pair<String, TypeName>>();
List<Pair<String, TypeName>> whereParams = new ArrayList<Pair<String, TypeName>>();
String name;
for (Pair<String, TypeName> param : methodParams) {
name = method.findParameterAliasByName(param.value0);
if (method.isThisDynamicWhereConditionsName(name)) {
// skip for dynamic where
continue;
}
if (method.isThisDynamicWhereArgsName(name)) {
// skip for dynamic where
continue;
}
if (where.value1.contains(new Pair<>(name, param.value1))) {
whereParams.add(param);
} else {
updateableParams.add(param);
}
}
// clear contentValues
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);
}
if (method.jql.containsSelectOperation) {
generateJavaDoc(method, methodBuilder, updateMode);
GenericSQLHelper.generateGenericExecSQL(methodBuilder, method);
} else {
// generate javadoc
generateJavaDoc(method, methodBuilder, updateMode, whereCondition, where, methodParams);
if (updateMode) {
AssertKripton.assertTrueOrInvalidMethodSignException(updateableParams.size() > 0, method, "no column was selected for update");
// order item for content values
updateableParams = SqlBuilderHelper.orderContentValues(method, updateableParams);
for (Pair<String, TypeName> item : updateableParams) {
String resolvedParamName = method.findParameterAliasByName(item.value0);
SQLProperty property = entity.get(resolvedParamName);
if (property == null)
throw (new PropertyNotFoundException(method, resolvedParamName, item.value1));
// check same type
TypeUtility.checkTypeCompatibility(method, item, property);
// here it needed raw parameter typeName
if (method.isLogEnabled()) {
methodBuilder.addCode("_contentValues.put($S, ", property.columnName);
} else {
methodBuilder.addCode("_contentValues.put(");
}
SQLTransformer.javaMethodParam2ContentValues(methodBuilder, method, item.value0, TypeUtility.typeName(property.getElement()), property);
methodBuilder.addCode(");\n");
// if (nullable) {
// methodBuilder.nextControlFlow("else");
//
// if (method.isLogEnabled()) {
// methodBuilder.addStatement("_contentValues.putNull($S)", property.columnName);
// } else {
// methodBuilder.addStatement("_contentValues.putNull()");
// }
//
// methodBuilder.endControlFlow();
// }
}
methodBuilder.addCode("\n");
} else {
if (updateableParams.size() > 0) {
String separator = "";
StringBuilder buffer = new StringBuilder();
for (Pair<String, TypeName> item : updateableParams) {
String resolvedParamName = method.findParameterAliasByName(item.value0);
buffer.append(separator + resolvedParamName);
separator = ", ";
}
// in DELETE can not be updated fields
if (updateableParams.size() > 1) {
throw (new InvalidMethodSignException(method, " parameters " + buffer.toString() + " are not used in where conditions"));
} else {
throw (new InvalidMethodSignException(method, " parameter " + buffer.toString() + " is not used in where conditions"));
}
}
}
// build where condition
generateWhereCondition(methodBuilder, method, where);
methodBuilder.addCode("\n");
ModifyBeanHelper.generateModifyQueryCommonPart(method, classBuilder, methodBuilder);
// support for livedata
if (daoDefinition.hasLiveData()) {
methodBuilder.addComment("support for livedata");
methodBuilder.addStatement(BindDaoBuilder.METHOD_NAME_REGISTRY_EVENT + "(result)");
}
// if true, field must be associate to ben attributes
if (returnType == TypeName.VOID) {
} else {
if (isIn(returnType, Boolean.TYPE, Boolean.class)) {
methodBuilder.addStatement("return result!=0");
} else if (isIn(returnType, Long.TYPE, Long.class, Integer.TYPE, Integer.class, Short.TYPE, Short.class)) {
methodBuilder.addStatement("return result");
} else {
// more than one listener found
throw (new InvalidMethodSignException(method, "invalid return type"));
}
}
}
}
Aggregations