use of com.abubusoft.kripton.processor.core.ModelAnnotation 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.core.ModelAnnotation in project kripton by xcesco.
the class BindSharedPreferencesSubProcessor method analyzeSharedPreferences.
private String analyzeSharedPreferences(final TypeElement sharedPreference) {
Element beanElement = sharedPreference;
String result = beanElement.getSimpleName().toString();
// create equivalent entity in the domain of bind processor
final BindEntity bindEntity = BindEntityBuilder.parse(null, sharedPreference);
final PrefsEntity currentEntity = new PrefsEntity(beanElement.getSimpleName().toString(), (TypeElement) beanElement, AnnotationUtility.buildAnnotationList((TypeElement) beanElement, classAnnotationFilter));
final boolean bindAllFields = AnnotationUtility.getAnnotationAttributeAsBoolean(currentEntity, BindType.class, AnnotationAttributeType.ALL_FIELDS, Boolean.TRUE);
PropertyUtility.buildProperties(elementUtils, currentEntity, new PropertyFactory<PrefsEntity, PrefsProperty>() {
@Override
public PrefsProperty createProperty(PrefsEntity entity, Element propertyElement) {
return new PrefsProperty(currentEntity, propertyElement, AnnotationUtility.buildAnnotationList(propertyElement));
}
}, propertyAnnotationFilter, new PropertyCreatedListener<PrefsEntity, PrefsProperty>() {
@Override
public boolean onProperty(PrefsEntity entity, PrefsProperty property) {
// if @BindDisabled is present, exit immediately
if (property.hasAnnotation(BindDisabled.class)) {
if (bindAllFields) {
return false;
} else {
throw new InvalidDefinition("@BindDisabled can not be used with @BindType(allField=false)");
}
}
if (property.getPropertyType().isArray() || property.getPropertyType().isList()) {
property.setPreferenceType(PreferenceType.STRING);
} else {
if (property.isType(Boolean.TYPE, Boolean.class)) {
property.setPreferenceType(PreferenceType.BOOL);
} else if (property.isType(Short.TYPE, Short.class)) {
property.setPreferenceType(PreferenceType.INT);
} else if (property.isType(Character.TYPE, Character.class)) {
property.setPreferenceType(PreferenceType.STRING);
} else if (property.isType(Integer.TYPE, Integer.class)) {
property.setPreferenceType(PreferenceType.INT);
} else if (property.isType(Long.TYPE, Long.class)) {
property.setPreferenceType(PreferenceType.LONG);
} else if (property.isType(Float.TYPE, Float.class)) {
property.setPreferenceType(PreferenceType.FLOAT);
} else if (property.isType(Double.TYPE, Double.class)) {
property.setPreferenceType(PreferenceType.STRING);
} else {
property.setPreferenceType(PreferenceType.STRING);
}
}
if (!bindAllFields && !property.hasAnnotation(BindPreference.class)) {
// skip field
return false;
}
// if field disable, skip property definition
ModelAnnotation annotation = property.getAnnotation(BindPreference.class);
if (annotation != null && AnnotationUtility.extractAsBoolean(property, annotation, AnnotationAttributeType.ENABLED) == false) {
return false;
}
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 to create SharedPreference", sharedPreference.asType(), property.getName())));
}
return true;
}
});
model.entityAdd(currentEntity);
return result;
}
use of com.abubusoft.kripton.processor.core.ModelAnnotation in project kripton by xcesco.
the class BindEntityBuilder method parse.
public static BindEntity parse(final BindModel model, TypeElement element) {
final Elements elementUtils = BaseProcessor.elementUtils;
final InnerCounter counterPropertyInValue = new InnerCounter();
final Converter<String, String> typeNameConverter = CaseFormat.UPPER_CAMEL.converterTo(CaseFormat.LOWER_CAMEL);
final TypeElement beanElement = element;
final BindEntity currentEntity = new BindEntity(beanElement.getSimpleName().toString(), beanElement, AnnotationUtility.buildAnnotationList(element, classAnnotationFilter));
// tag typeName
String tagName = AnnotationUtility.extractAsString(beanElement, BindType.class, AnnotationAttributeType.VALUE);
if (StringUtils.hasText(tagName)) {
currentEntity.xmlInfo.label = tagName;
} else {
currentEntity.xmlInfo.label = typeNameConverter.convert(beanElement.getSimpleName().toString());
}
final boolean bindAllFields = AnnotationUtility.getAnnotationAttributeAsBoolean(currentEntity, BindType.class, AnnotationAttributeType.ALL_FIELDS, Boolean.TRUE);
PropertyUtility.buildProperties(elementUtils, currentEntity, new PropertyFactory<BindEntity, BindProperty>() {
@Override
public BindProperty createProperty(BindEntity entity, Element propertyElement) {
return new BindProperty(currentEntity, propertyElement, AnnotationUtility.buildAnnotationList(propertyElement));
}
}, propertyAnnotationFilter, new PropertyCreatedListener<BindEntity, BindProperty>() {
@Override
public boolean onProperty(BindEntity entity, BindProperty property) {
// if we are build Map, the model are not null
boolean contextExternal = (model == null);
// if @BindDisabled is present, exit immediately
if (property.hasAnnotation(BindDisabled.class)) {
if (bindAllFields) {
return false;
} else {
throw new InvalidDefinition(String.format("In class '%s', @%s can not be used with @%s(allField=false)", property.getParent().getElement().asType().toString(), BindDisabled.class.getSimpleName(), BindType.class.getSimpleName()));
}
}
boolean enabled = bindAllFields;
ModelAnnotation annotationBind = property.getAnnotation(Bind.class);
enabled = enabled || (annotationBind != null && AnnotationUtility.extractAsBoolean(property, annotationBind, AnnotationAttributeType.ENABLED));
// we have to analyze in every case.
if (!enabled && !contextExternal) {
return false;
}
ModelAnnotation annotationBindXml = property.getAnnotation(BindXml.class);
property.order = 0;
property.mapKeyName = Bind.MAP_KEY_DEFAULT;
property.mapValueName = Bind.MAP_VALUE_DEFAULT;
// label for item and collection elements are the same for
// default
property.label = typeNameConverter.convert(property.getName());
property.xmlInfo.labelItem = property.label;
property.xmlInfo.wrappedCollection = false;
property.xmlInfo.xmlType = XmlType.valueOf(XmlType.TAG.toString());
property.xmlInfo.mapEntryType = MapEntryType.valueOf(MapEntryType.TAG.toString());
// check if there is an adapter
if ((property.getAnnotation(BindAdapter.class) != null)) {
BindTransform transform = BindTransformer.lookup(TypeUtility.typeName(property.typeAdapter.dataType));
if (!transform.isTypeAdapterSupported()) {
String msg = String.format("In class '%s', property '%s' uses @BindAdapter with unsupported 'dataType' '%s'", beanElement.asType().toString(), property.getName(), property.typeAdapter.dataType);
throw (new IncompatibleAnnotationException(msg));
}
if (property.getPropertyType().isPrimitive()) {
String msg = String.format("In class '%s', property '%s' is primitive of type '%s' and it can not be annotated with @BindAdapter", beanElement.asType().toString(), property.getName(), property.getPropertyType().getTypeName());
throw (new IncompatibleAnnotationException(msg));
}
}
// @Bind management
if (annotationBind != null) {
int order = AnnotationUtility.extractAsInt(property.getElement(), Bind.class, AnnotationAttributeType.ORDER);
property.order = order;
String tempName = AnnotationUtility.extractAsString(property.getElement(), Bind.class, AnnotationAttributeType.VALUE);
if (StringUtils.hasText(tempName)) {
// for the moment are the same
property.label = tempName;
property.xmlInfo.labelItem = property.label;
}
// map info
String mapKeyName = AnnotationUtility.extractAsString(property.getElement(), Bind.class, AnnotationAttributeType.MAP_KEY_NAME);
if (StringUtils.hasText(mapKeyName))
property.mapKeyName = mapKeyName;
String mapValueName = AnnotationUtility.extractAsString(property.getElement(), Bind.class, AnnotationAttributeType.MAP_VALUE_NAME);
if (StringUtils.hasText(mapValueName))
property.mapValueName = mapValueName;
}
// @BindXml management
if (annotationBindXml != null) {
String mapEntryType = AnnotationUtility.extractAsEnumerationValue(property.getElement(), BindXml.class, AnnotationAttributeType.MAP_ENTRY_TYPE);
if (StringUtils.hasText(mapEntryType))
property.xmlInfo.mapEntryType = MapEntryType.valueOf(mapEntryType);
// define element tag typeName
String tempElementName = AnnotationUtility.extractAsString(property.getElement(), BindXml.class, AnnotationAttributeType.XML_ELEMENT_TAG);
if (StringUtils.hasText(tempElementName)) {
property.xmlInfo.labelItem = tempElementName;
property.xmlInfo.wrappedCollection = true;
}
String xmlType = AnnotationUtility.extractAsEnumerationValue(property.getElement(), BindXml.class, AnnotationAttributeType.XML_TYPE);
if (StringUtils.hasText(xmlType))
property.xmlInfo.xmlType = XmlType.valueOf(xmlType);
}
if (property.xmlInfo.xmlType == XmlType.ATTRIBUTE) {
BindTransform transform = BindTransformer.lookup(property.getPropertyType().getTypeName());
// check if property is a array
if (property.isBindedArray() && !(transform instanceof ByteArrayBindTransform)) {
String msg = String.format("In class '%s', property '%s' is an array and it can not be mapped in a xml attribute", beanElement.asType().toString(), property.getName());
throw (new IncompatibleAttributesInAnnotationException(msg));
}
// check if property is a collection
if (property.isBindedCollection()) {
String msg = String.format("In class '%s', property '%s' is a collection and it can not be mapped in a xml attribute", beanElement.asType().toString(), property.getName());
throw (new IncompatibleAttributesInAnnotationException(msg));
}
// check if property is a map
if (property.isBindedMap()) {
String msg = String.format("In class '%s', property '%s' is an map and it can not be mapped in a xml attribute", beanElement.asType().toString(), property.getName());
throw (new IncompatibleAttributesInAnnotationException(msg));
}
if (transform != null && transform instanceof ObjectBindTransform) {
String msg = String.format("In class '%s', property '%s' is an object and it can not be mapped in a xml attribute", beanElement.asType().toString(), property.getName());
throw (new IncompatibleAttributesInAnnotationException(msg));
}
}
if (property.xmlInfo.xmlType == XmlType.VALUE || property.xmlInfo.xmlType == XmlType.VALUE_CDATA) {
counterPropertyInValue.inc();
BindTransform transform = BindTransformer.lookup(property.getPropertyType().getTypeName());
// check if property is a array
if (property.isBindedArray() && !(transform instanceof ByteArrayBindTransform)) {
String msg = String.format("In class '%s', property '%s' is an array and it can not be mapped in a xml value", beanElement.asType().toString(), property.getName());
throw (new IncompatibleAttributesInAnnotationException(msg));
}
// check if property is a collection
if (property.isBindedCollection()) {
String msg = String.format("In class '%s', property '%s' is a collection and it can not be mapped in a xml value", beanElement.asType().toString(), property.getName());
throw (new IncompatibleAttributesInAnnotationException(msg));
}
// check if property is a map
if (property.isBindedMap()) {
String msg = String.format("In class '%s', property '%s' is a map and it can not be mapped in a xml value", beanElement.asType().toString(), property.getName());
throw (new IncompatibleAttributesInAnnotationException(msg));
}
if (transform != null && transform instanceof ObjectBindTransform) {
String msg = String.format("In class '%s', property '%s' is an object and it can not be mapped in a xml value", beanElement.asType().toString(), property.getName());
throw (new IncompatibleAttributesInAnnotationException(msg));
}
}
if (counterPropertyInValue.value() > 1) {
String msg = String.format("In class '%s', property '%s' and other properties are mapped in a xml value, but only one property for class can be a xml value", beanElement.asType().toString(), property.getName());
throw (new IncompatibleAttributesInAnnotationException(msg));
}
property.bindedObject = BindTransformer.isBindedObject(property);
// set inCollection to true, permits this.
if (property.bindedObject && contextExternal) {
property.inCollection = true;
}
return true;
}
});
// if we don't have model, we dont save bean definition
if (model != null) {
model.entityAdd(currentEntity);
}
return currentEntity;
}
use of com.abubusoft.kripton.processor.core.ModelAnnotation in project kripton by xcesco.
the class SelectPaginatedResultHelper method buildSpecializedPagedResultClass.
/**
* Build paginated result class handler.
*
* @param classBuilder
* @param method
* @return name of generated class
*/
private static String buildSpecializedPagedResultClass(TypeSpec.Builder classBuilder, SQLiteModelMethod method) {
TypeName entityTypeName = TypeUtility.typeName(method.getParent().getEntityClassName());
String pagedResultName = "PaginatedResult" + (pagedResultCounter++);
TypeSpec.Builder typeBuilder = TypeSpec.classBuilder(pagedResultName).addModifiers(Modifier.PUBLIC).superclass(TypeUtility.parameterizedTypeName(TypeUtility.className(PaginatedResult.class), entityTypeName));
// add fields and define constructor
MethodSpec.Builder setupBuilder = MethodSpec.constructorBuilder();
MethodSpec.Builder executeBuilder = MethodSpec.methodBuilder("execute").addModifiers(Modifier.PUBLIC).returns(TypeUtility.parameterizedTypeName(TypeUtility.className(List.class), entityTypeName));
executeBuilder.addCode("list=$T.this.$L(", TypeUtility.typeName(method.getParent().getElement(), BindDaoBuilder.SUFFIX), method.getName());
// we have always a first parameter
String separator = "";
ParameterSpec parameterSpec;
for (Pair<String, TypeName> item : method.getParameters()) {
if (method.hasDynamicPageSizeConditions() && method.dynamicPageSizeName.equals(item.value0)) {
setupBuilder.addStatement("this.pageSize=$L", item.value0);
} else {
// field
typeBuilder.addField(item.value1, item.value0);
setupBuilder.addStatement("this.$L=$L", item.value0, item.value0);
}
// construtor
parameterSpec = ParameterSpec.builder(item.value1, item.value0).build();
setupBuilder.addParameter(parameterSpec);
// execute
if (method.dynamicPageSizeName != null && method.dynamicPageSizeName.equals(item.value0)) {
executeBuilder.addCode(separator + "this.pageSize");
} else {
executeBuilder.addCode(separator + item.value0);
}
separator = ", ";
}
if (!method.hasDynamicPageSizeConditions()) {
ModelAnnotation annotation = method.getAnnotation(BindSqlSelect.class);
int pageSize = annotation.getAttributeAsInt(AnnotationAttributeType.PAGE_SIZE);
setupBuilder.addStatement("this.pageSize=$L", pageSize);
}
typeBuilder.addMethod(setupBuilder.build());
executeBuilder.addCode(separator + "this);\n");
executeBuilder.addStatement("return list");
typeBuilder.addMethod(executeBuilder.build());
classBuilder.addType(typeBuilder.build());
return pagedResultName;
}
use of com.abubusoft.kripton.processor.core.ModelAnnotation in project kripton by xcesco.
the class SqlModifyBuilder method detectModifyType.
/**
* Detect method type
*
* @param method
* @param jqlType
* jql type is necessary because method.jql can be not properly
* initialized
* @return
*/
public static ModifyType detectModifyType(SQLiteModelMethod method, JQLType jqlType) {
// Elements elementUtils = BaseProcessor.elementUtils;
SQLiteDaoDefinition daoDefinition = method.getParent();
SQLiteEntity entity = daoDefinition.getEntity();
ModifyType updateResultType = null;
// check type of arguments
int count = 0;
for (Pair<String, TypeName> param : method.getParameters()) {
if (method.isThisDynamicWhereConditionsName(param.value0)) {
// if current parameter is dynamic where, skip it
continue;
}
if (TypeUtility.isEquals(param.value1, typeName(entity.getElement()))) {
count++;
}
}
if (count == 0) {
// method to update raw data: no bean is used
updateResultType = jqlType == JQLType.UPDATE ? ModifyType.UPDATE_RAW : ModifyType.DELETE_RAW;
ModelAnnotation annotation;
if (jqlType == JQLType.UPDATE) {
annotation = method.getAnnotation(BindSqlUpdate.class);
AssertKripton.assertTrueOrInvalidMethodSignException(AnnotationUtility.extractAsStringArray(method, annotation, AnnotationAttributeType.FIELDS).size() == 0, method, " can not use attribute %s in this kind of query definition", AnnotationAttributeType.FIELDS.getValue());
AssertKripton.assertTrueOrInvalidMethodSignException(AnnotationUtility.extractAsStringArray(method, annotation, AnnotationAttributeType.EXCLUDED_FIELDS).size() == 0, method, " can not use attribute %s in this kind of query definition", AnnotationAttributeType.EXCLUDED_FIELDS.getValue());
} else {
annotation = method.getAnnotation(BindSqlDelete.class);
}
// check if there is only one parameter
AssertKripton.failWithInvalidMethodSignException(method.getParameters().size() > 1 && TypeUtility.isEquals(method.getParameters().get(0).value1, daoDefinition.getEntityClassName()), method);
} else if (count == 1) {
updateResultType = jqlType == JQLType.UPDATE ? ModifyType.UPDATE_BEAN : ModifyType.DELETE_BEAN;
// with dynamic where conditions, we have to add 1 to parameter
// check size (one parameter is a bean and one is the where
// conditions)
AssertKripton.assertTrueOrInvalidMethodSignException(method.getParameters().size() == 1 + (method.hasDynamicWhereConditions() ? 1 : 0) + (method.hasDynamicWhereArgs() ? 1 : 0), method, " expected only one parameter of %s type", daoDefinition.getEntityClassName());
} else {
throw (new InvalidMethodSignException(method, "only one parameter of type " + typeName(entity.getElement()) + " can be used"));
}
return updateResultType;
}
Aggregations