generate live data method.

@param classBuilder
the class builder
@param method
the method
510160
@Override
	public void generateLiveData(TypeSpec.Builder classBuilder, SQLiteModelMethod method) {
		SQLiteDaoDefinition daoDefinition = method.getParent();
		Set<JQLProjection> fieldList = JQLChecker.getInstance().extractProjections(method, method.jql.value, method.getEntity());

		// generate method code
		MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(method.getName().replaceAll(LIVE_DATA_PREFIX, "")).addAnnotation(Override.class).addModifiers(Modifier.PUBLIC);

		methodBuilder.addJavadoc("<h2>Live data</h2>\n");
		methodBuilder.addJavadoc("<p>This method open a connection internally.</p>\n\n");

		generateCommonPart(method, classBuilder, methodBuilder, fieldList, GenerationType.NO_CONTENT, method.liveDataReturnClass, true, false);

		boolean pagedLiveData = method.isPagedLiveData();

		if (pagedLiveData) {
			SelectType.PAGED_RESULT.generate(classBuilder, method);

			String pageResultName = SelectPaginatedResultHelper.getCurrentPagedResultClass();
			SelectPaginatedResultHelper.createPagedResult(method, pageResultName, methodBuilder);
		}

		ClassName dataSourceClazz = BindDataSourceBuilder.generateDataSourceName(daoDefinition.getParent());
		ClassName daoFactoryClazz = TypeUtility.className(BindDaoFactoryBuilder.generateDaoFactoryName(daoDefinition.getParent()));
		ClassName batchClazz = TypeUtility.mergeTypeNameWithSuffix(dataSourceClazz, ".Batch");

		List<Pair<String, TypeName>> methodParameters = method.getParameters();
		StringBuilder buffer = new StringBuilder();
		String separator = "";

		for (Pair<String, TypeName> item : methodParameters) {
			buffer.append(separator + item.value0);
			separator = ", ";
		}

		ClassName handlerClass = KriptonLiveDataManager.getInstance().getLiveDataHandlerClazz();
		if (pagedLiveData) {
			handlerClass = KriptonLiveDataManager.getInstance().getPagedLiveDataHandlerClazz();

			TypeSpec batchBuilder = TypeSpec.anonymousClassBuilder("").addSuperinterface(ParameterizedTypeName.get(batchClazz, method.getReturnClass()))
					.addMethod(
							MethodSpec.methodBuilder("onExecute").addAnnotation(Override.class).addModifiers(Modifier.PUBLIC).addParameter(ParameterSpec.builder(daoFactoryClazz, "daoFactory").build())
									.returns(method.getReturnClass()).addStatement("return paginatedResult.execute(daoFactory)").build())
					.build();

			// return
			TypeSpec.Builder liveDataBuilderBuilder = TypeSpec.anonymousClassBuilder("paginatedResult")
					.addSuperinterface(ParameterizedTypeName.get(handlerClass, method.getReturnClass())).addMethod(MethodSpec.methodBuilder("compute").addAnnotation(Override.class)
							.addModifiers(Modifier.PROTECTED).returns(method.getReturnClass()).addStatement("return $T.getInstance().executeBatch($L)", dataSourceClazz, batchBuilder).build());
			TypeSpec liveDataBuilder = liveDataBuilderBuilder.build();

			methodBuilder.addStatement("final $T builder=$L", ParameterizedTypeName.get(handlerClass, method.getReturnClass()), liveDataBuilder);
		} else {
			TypeSpec batchBuilder = TypeSpec.anonymousClassBuilder("").addSuperinterface(ParameterizedTypeName.get(batchClazz, method.getReturnClass()))
					.addMethod(MethodSpec.methodBuilder("onExecute").addAnnotation(Override.class).addModifiers(Modifier.PUBLIC)
							.addParameter(ParameterSpec.builder(daoFactoryClazz, "daoFactory").build()).returns(method.getReturnClass())
							.addStatement("return daoFactory.get$L().$L($L)", daoDefinition.getName(), method.getName() + LIVE_DATA_PREFIX, buffer.toString()).build())
					.build();

			TypeSpec.Builder liveDataBuilderBuilder = TypeSpec.anonymousClassBuilder("").addSuperinterface(ParameterizedTypeName.get(handlerClass, method.getReturnClass()))
					.addMethod(MethodSpec.methodBuilder("compute").addAnnotation(Override.class).addModifiers(Modifier.PROTECTED).returns(method.getReturnClass())
							.addStatement("return $T.getInstance().executeBatch($L)", dataSourceClazz, batchBuilder).build());
			TypeSpec liveDataBuilder = liveDataBuilderBuilder.build();

			methodBuilder.addStatement("final $T builder=$L", ParameterizedTypeName.get(handlerClass, method.getReturnClass()), liveDataBuilder);
		}

		methodBuilder.addStatement("registryLiveData(builder)");
		methodBuilder.addStatement("return builder.getLiveData()");

		classBuilder.addMethod(methodBuilder.build());
	}
1347499
public static MethodMetadata build(Method method) {
        return new MethodMetadata(method.getName(), method.getDeclaringClass(), method,
            method.getParameterTypes());
    }
390726
private static void generateSelectForContentProvider(Builder builder, final SQLiteModelMethod method, SelectType selectResultType) {
		final SQLiteDaoDefinition daoDefinition = method.getParent();
		final SQLiteEntity entity = method.getEntity();
		final Set<String> columns = new LinkedHashSet<>();

		MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(method.contentProviderMethodName);
		if (!method.getParent().hasSamePackageOfSchema()) {
			methodBuilder.addModifiers(Modifier.PUBLIC);
		}

		// params
		methodBuilder.addParameter(ParameterSpec.builder(Uri.class, "uri").build());
		methodBuilder.addParameter(ParameterSpec.builder(ArrayTypeName.of(String.class), "projection").build());
		methodBuilder.addParameter(ParameterSpec.builder(String.class, "selection").build());
		methodBuilder.addParameter(ParameterSpec.builder(ArrayTypeName.of(String.class), "selectionArgs").build());
		methodBuilder.addParameter(ParameterSpec.builder(String.class, "sortOrder").build());

		methodBuilder.returns(Cursor.class);

		SqlBuilderHelper.generateLogForContentProviderBeginning(method, methodBuilder);

		JQLChecker jqlChecker = JQLChecker.getInstance();
		SplittedSql splittedSql = generateSQL(method, methodBuilder, true);

		List<JQLPlaceHolder> placeHolders = jqlChecker.extractFromVariableStatement(method, splittedSql.sqlWhereStatement);
		// remove placeholder for dynamic where, we are not interested here
		placeHolders = SqlBuilderHelper.removeDynamicPlaceHolder(placeHolders);
		AssertKripton.assertTrue(placeHolders.size() == method.contentProviderUriVariables.size(),
				"In '%s.%s' content provider URI path variables and variables in where conditions are different. If SQL uses parameters, they must be defined in URI path.", daoDefinition.getName(),
				method.getName());

		Set<JQLProjection> projectedColumns = jqlChecker.extractProjections(method, method.jql.value, entity);
		for (JQLProjection item : projectedColumns) {
			if (item.type == ProjectionType.COLUMN) {
				if (item.alias != null) {
					columns.add(entity.get(item.alias.trim()).columnName);
				} else {
					columns.add(entity.get(item.column.trim()).columnName);
				}
			} else {
				columns.add(item.expression.trim());
			}
		}

		methodBuilder.addStatement("$T _contentValues=contentValues()", KriptonContentValues.class);
		methodBuilder.addStatement("$T _sqlBuilder=sqlBuilder()", StringBuilder.class);
		SqlModifyBuilder.generateInitForDynamicWhereVariables(method, methodBuilder, "selection", "selectionArgs");

		methodBuilder.addStatement("$T _projectionBuffer=new $T()", StringBuilder.class, StringBuilder.class);
		if (method.jql.isOrderBy()) {
			methodBuilder.addStatement("String _sortOrder=sortOrder");
		}

		methodBuilder.addStatement("_sqlBuilder.append($S)", splittedSql.sqlBasic);

		SqlBuilderHelper.generateWhereCondition(methodBuilder, method, false);

		generateDynamicPartOfQuery(method, methodBuilder, splittedSql, false);

		// generate and check columns
		{
			methodBuilder.addCode("\n// manage projected columns\n");
			methodBuilder.addStatement("String _columnSeparator=\"\"");
			methodBuilder.beginControlFlow("if (projection!=null && projection.length>0)");
			// generate projected column check
			String columnCheckSetName = SqlBuilderHelper.generateColumnCheckSet(builder, method, columns);
			SqlBuilderHelper.forEachColumnInContentValue(methodBuilder, method, "projection", true, new OnColumnListener() {

				@Override
				public void onColumnCheck(MethodSpec.Builder methodBuilder, String projectedColumnVariable) {
					methodBuilder.addStatement("_projectionBuffer.append(_columnSeparator + $L)", projectedColumnVariable);
					methodBuilder.addStatement("_columnSeparator=\", \"");
				}
			});
			methodBuilder.nextControlFlow("else");
			methodBuilder.beginControlFlow("for (String column: $L)", columnCheckSetName);
			methodBuilder.addStatement("_projectionBuffer.append(_columnSeparator + column)");
			methodBuilder.addStatement("_columnSeparator=\", \"");
			methodBuilder.endControlFlow();
			methodBuilder.endControlFlow();

			int i = 0;
			// extract pathVariables
			// every controls was done in constructor of SQLiteModelMethod
			for (ContentUriPlaceHolder variable : method.contentProviderUriVariables) {
				AssertKripton.assertTrue(SqlBuilderHelper.validate(variable.value, placeHolders, i), "In '%s.%s' content provider URI path and where conditions must use same set of variables",
						daoDefinition.getName(), method.getName());

				SQLProperty entityProperty = entity.get(variable.value);
				TypeName methodParameterType = method.findParameterTypeByAliasOrName(variable.value);

				methodBuilder.addCode("// Add parameter $L at path segment $L\n", variable.value, variable.pathSegmentIndex);
				// methodBuilder.addStatement("_sqlWhereParams.add(uri.getPathSegments().get($L))",
				// variable.pathSegmentIndex);
				methodBuilder.addStatement("_contentValues.addWhereArgs(uri.getPathSegments().get($L))", variable.pathSegmentIndex);

				if (entityProperty != null) {

					AssertKripton.assertTrue(TypeUtility.isTypeIncludedIn(entityProperty.getPropertyType().getTypeName(), String.class, Long.class, Long.TYPE),
							"In '%s.%s' content provider URI path variables %s must be String of Long type", daoDefinition.getName(), method.getName(), entityProperty.getName());
				} else if (methodParameterType != null) {
					AssertKripton.assertTrue(TypeUtility.isTypeIncludedIn(methodParameterType, String.class, Long.class, Long.TYPE),
							"In '%s.%s' content provider URI path variables %s must be String of Long type", daoDefinition.getName(), method.getName(),
							method.findParameterNameByAlias(variable.value));
				}

				i++;
			}
		}

		// _sql must be always defined
		methodBuilder.addStatement("String _sql=String.format(_sqlBuilder.toString(), _projectionBuffer.toString())");
		SqlBuilderHelper.generateLogForSQL(method, methodBuilder);

		SqlBuilderHelper.generateLogForWhereParameters(method, methodBuilder);

		methodBuilder.addCode("\n// execute query\n");
		// methodBuilder.addStatement("Cursor _result =
		// database().rawQuery(_sql, _sqlWhereParams.toArray(new
		// String[_sqlWhereParams.size()]))");
		methodBuilder.addStatement("Cursor _result = database().rawQuery(_sql, _contentValues.whereArgsAsArray())");

		methodBuilder.addStatement("return _result");

		// we add at last javadoc, because need info is built at last.
		SqlBuilderHelper.generateJavaDocForContentProvider(method, methodBuilder);

		methodBuilder.addJavadoc("@param uri $S\n", method.contentProviderUriTemplate.replace("*", "[*]"));
		methodBuilder.addJavadoc("@param selection dynamic part of <code>where</code> statement $L\n", method.hasDynamicWhereConditions() ? "" : "<b>NOT USED</b>");
		methodBuilder.addJavadoc("@param selectionArgs arguments of dynamic part of <code>where</code> statement $L\n", method.hasDynamicWhereConditions() ? "" : "<b>NOT USED</b>");

		methodBuilder.addJavadoc("@return number of effected rows\n");

		builder.addMethod(methodBuilder.build());
	}
714711
public final void writeMethod(int access, Method method, ClassVisitor visitor) {
    writeMethodTo(new CodeBuilder(access, method, null, visitor));
  }
716853
public void addNewStaticMethod(Method method) {
        final CachedMethod cachedMethod = CachedMethod.find(method);
        NewStaticMetaMethod newMethod = new NewStaticMetaMethod(cachedMethod);
        final CachedClass declaringClass = newMethod.getDeclaringClass();
        addNewStaticMethodToIndex(newMethod, metaMethodIndex.getHeader(declaringClass.getTheClass()));
    }
1360220
private void storeMethod(Method method, Map<Key, Array> methodsMap) {
	Key methodName = KeyImpl.init(method.getName());

	Array methodArgs;
	synchronized (methodsMap) {
	    methodArgs = methodsMap.get(methodName);
	    if (methodArgs == null) {
		methodArgs = new ArrayImpl();
		methodsMap.put(methodName, methodArgs);
	    }
	}

	storeArgs(method, methodArgs);
	// Modifier.isStatic(method.getModifiers());
    }
1131644
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");
			}
		}

	}
1021764
public static JQL buildJQL(final SQLiteModelMethod method, String preparedJql) {
		Map<JQLDynamicStatementType, String> dynamicReplace = new HashMap<>();
		final JQL result = new JQL();

		// for each method's parameter
		forEachParameter(method, new OnMethodParameterListener() {

			@Override
			public void onMethodParameter(VariableElement item) {
				if (method.getEntity().getElement().asType().equals(item.asType())) {
					result.paramBean = item.getSimpleName().toString();
				}
			}
		});

		// defined how jql is defined
		result.declarationType = JQLDeclarationType.JQL_COMPACT;
		if (StringUtils.hasText(preparedJql)) {
			result.declarationType = JQLDeclarationType.JQL_EXPLICIT;
		}

		if (method.hasAnnotation(BindSqlSelect.class)) {
			checkFieldsDefinitions(method, BindSqlSelect.class);
			return buildJQLSelect(method, result, dynamicReplace, preparedJql);
		} else if (method.hasAnnotation(BindSqlInsert.class)) {
			checkFieldsDefinitions(method, BindSqlInsert.class);
			return buildJQLInsert(method, result, preparedJql);
		} else if (method.hasAnnotation(BindSqlUpdate.class)) {
			checkFieldsDefinitions(method, BindSqlUpdate.class);
			return buildJQLUpdate(method, result, dynamicReplace, preparedJql);
		} else if (method.hasAnnotation(BindSqlDelete.class)) {
			return buildJQLDelete(method, result, dynamicReplace, preparedJql);
		}

		return null;
	}
968092
private static Method getMethod(final Class<?> mbean,
                                  final String method,
                                  final String... params) {
    try {
      final ClassLoader loader = mbean.getClassLoader();
      final Class<?>[] paramClasses = new Class<?>[params.length];
      for (int i = 0; i < params.length; i++) {
        paramClasses[i] = primitives.get(params[i]);
        if (paramClasses[i] == null) {
          paramClasses[i] = Class.forName(params[i], false, loader);
        }
      }
      return mbean.getMethod(method, paramClasses);
    } catch (RuntimeException e) {
      throw e;
    } catch (Exception e) {
      return null;
    }
  }
725866
@Nonnull
    public BugInstance addClassAndMethod(JavaClass javaClass, Method method) {
        addClass(javaClass.getClassName());
        addMethod(javaClass, method);

        if (!MemberUtils.isUserGenerated(method)) {
            foundInAutogeneratedMethod();
        }
        return this;
    }
196690
public void scan(JavaBackend javaBackend, Method method, Class<?> glueCodeClass) {
        Annotation[] methodAnnotations = method.getAnnotations();
        for (Annotation annotation : methodAnnotations) {
            if (isHookAnnotation(annotation)) {
                validateMethod(method, glueCodeClass);
                javaBackend.addHook(annotation, method);
            } else if (isStepdefAnnotation(annotation)) {
                validateMethod(method, glueCodeClass);
                javaBackend.addStepDefinition(annotation, method);
            }
        }
    }
681730
private void addStubMethods(TypeSpec.Builder classBuilder, Element member, int methodIndex, MethodSpec.Builder methodBuilder) {
        ExecutableElement executableElement = (ExecutableElement) member;
        String methodName = executableElement.getSimpleName().toString();
        boolean isOneWay = executableElement.getReturnType().getKind() == TypeKind.VOID
                && member.getAnnotation(Oneway.class) != null;


        methodBuilder.beginControlFlow("case TRANSACTION_" + methodName + "_" + methodIndex + ":");

        methodBuilder.addStatement("data.enforceInterface(DESCRIPTOR)");
        List<String> paramNames = new ArrayList<>();
        int paramIndex = 0;
        List<VariableElement> outParams = new ArrayList<>();
        List<String> outParamsNames = new ArrayList<>();

        //pass parameters
        for (VariableElement param : executableElement.getParameters()) {
            ParamBuilder.ParamType paramType = param.getAnnotation(ParamIn.class) != null ? ParamBuilder.ParamType.IN
                    : param.getAnnotation(ParamOut.class) != null ? ParamBuilder.ParamType.OUT : ParamBuilder.ParamType.IN_OUT;

            ParamBuilder paramBuilder = getBindingManager().getBuilderForParam(param.asType());
            if (paramBuilder != null) {
                String paramName = "arg_stb_" + paramIndex;
                paramNames.add(paramName);
                paramBuilder.writeParamsToStub(param, paramType, paramName, methodBuilder);
                if (paramType != ParamBuilder.ParamType.IN) {
                    outParams.add(param);
                    outParamsNames.add(paramName);
                }
            } else {
                logError("Parameter cannot be marshalled " + param.getSimpleName());
            }
            paramIndex++;
        }

        String methodCall = "serviceImpl." + methodName + "(";
        int paramSize = paramNames.size();
        for (int paramCount = 0; paramCount < paramSize; paramCount++) {
            methodCall += paramNames.get(paramCount);
            if (paramCount < paramSize - 1) {
                methodCall += ", ";
            }
        }
        methodCall += ")";

        if (executableElement.getReturnType().getKind() != TypeKind.VOID) {
            methodBuilder.addStatement("$T result = " + methodCall, executableElement.getReturnType());
        } else {
            methodBuilder.addStatement(methodCall);
        }

        if (!isOneWay) {
            methodBuilder.addStatement("reply.writeNoException()");


            if (executableElement.getReturnType().getKind() != TypeKind.VOID) {
                ParamBuilder paramBuilder = getBindingManager().getBuilderForParam(executableElement.getReturnType());
                if (paramBuilder != null) {
                    paramBuilder.readResultsFromStub(executableElement.getReturnType(), methodBuilder);
                } else {
                    logError("Unmarshallable return type " + executableElement.getReturnType());
                }
            }

            int pIndex = 0;
            for (VariableElement param : outParams) {
                ParamBuilder.ParamType paramType = param.getAnnotation(ParamIn.class) != null ? ParamBuilder.ParamType.IN
                        : param.getAnnotation(ParamOut.class) != null ? ParamBuilder.ParamType.OUT : ParamBuilder.ParamType.IN_OUT;
                ParamBuilder paramBuilder = getBindingManager().getBuilderForParam(param.asType());
                if (paramBuilder != null) {
                    paramBuilder.readOutResultsFromStub(param, paramType, outParamsNames.get(pIndex), methodBuilder);
                }
                pIndex++;
            }
        }

        methodBuilder.addStatement("return true");
        methodBuilder.endControlFlow();
    }
281832
public static void generateSQL(final SQLiteModelMethod method, MethodSpec.Builder methodBuilder) {
		JQLChecker jqlChecker = JQLChecker.getInstance();

		methodBuilder.addCode("\n// generate sql\n");
		String sql = jqlChecker.replace(method, method.jql, new JQLReplacerListenerImpl(method) {
			@Override
			public String onColumnNameToUpdate(String columnName) {
				// only entity's columns
				return currentEntity.findPropertyByName(columnName).columnName;
			}

			@Override
			public String onColumnName(String columnName) {
				return currentSchema.findColumnNameByPropertyName(method, columnName);
			}

			@Override
			public String onBindParameter(String bindParameterName, boolean inStatement) {
				return "?";
			}

		});

		if (method.jql.dynamicReplace.containsKey(JQLDynamicStatementType.DYNAMIC_WHERE)) {
			methodBuilder.addStatement("String _sql=String.format($S, $L)",
					sql.replace(method.jql.dynamicReplace.get(JQLDynamicStatementType.DYNAMIC_WHERE), "%s"),
					"StringUtils.ifNotEmptyAppend(_sqlDynamicWhere,\" AND \")");
		} else {
			methodBuilder.addStatement("String _sql=$S", sql);
		}
	}
61086
private void generateJavaDoc(final SQLiteModelMethod method, MethodSpec.Builder methodBuilder, boolean updateMode, String whereCondition, Pair<String, List<Pair<String, TypeName>>> where,
			List<Pair<String, TypeName>> methodParams) {

		final List<SQLProperty> updatedProperties = new ArrayList<>();
		final One<Boolean> onWhereStatement = new One<Boolean>(false);

		String sqlModify = JQLChecker.getInstance().replace(method, method.jql, new JQLReplacerListenerImpl(method) {

			@Override
			public void onWhereStatementBegin(Where_stmtContext ctx) {
				onWhereStatement.value0 = true;
			}

			@Override
			public void onWhereStatementEnd(Where_stmtContext ctx) {
				onWhereStatement.value0 = false;
			}

			@Override
			public String onColumnNameToUpdate(String columnName) {
				SQLProperty tempProperty = currentEntity.get(columnName);

				AssertKripton.assertTrueOrUnknownPropertyInJQLException(tempProperty != null, method, columnName);

				updatedProperties.add(tempProperty);

				return tempProperty.columnName;
			}

			@Override
			public String onColumnName(String columnName) {
				SQLProperty tempProperty = currentEntity.get(columnName);

				AssertKripton.assertTrueOrUnknownPropertyInJQLException(tempProperty != null, method, columnName);

				return tempProperty.columnName;
			}

			@Override
			public String onBindParameter(String bindParameterName, boolean inStatement) {
				String resolvedParamName = method.findParameterNameByAlias(bindParameterName);
				AssertKripton.assertTrueOrUnknownParamInJQLException(resolvedParamName != null, method, bindParameterName);

				if (onWhereStatement.value0) {
					return SqlAnalyzer.PARAM_PREFIX + bindParameterName + SqlAnalyzer.PARAM_SUFFIX;
				} else {
					return SqlAnalyzer.PARAM_PREFIX + bindParameterName + SqlAnalyzer.PARAM_SUFFIX;
				}

			}

		});

		if (updateMode) {
			methodBuilder.addJavadoc("<h2>SQL update</h2>\n");
			methodBuilder.addJavadoc("<pre>$L</pre>\n", sqlModify);
			methodBuilder.addJavadoc("\n");

			// list of updated fields
			methodBuilder.addJavadoc("<h2>Updated columns:</h2>\n");
			methodBuilder.addJavadoc("<ul>\n");
			for (SQLProperty property : updatedProperties) {
				methodBuilder.addJavadoc("\t<li>$L</li>\n", property.columnName);
			}
			methodBuilder.addJavadoc("</ul>");
			methodBuilder.addJavadoc("\n\n");

		} else {
			methodBuilder.addJavadoc("<h2>SQL delete</h2>\n");
			methodBuilder.addJavadoc("<pre>$L</pre>", sqlModify);
			methodBuilder.addJavadoc("\n\n");
		}

		// list of where parameter
		if (where.value1.size() > 0) {
			methodBuilder.addJavadoc("<h2>Where parameters:</h2>\n");
			methodBuilder.addJavadoc("<dl>\n");
			for (Pair<String, TypeName> property : where.value1) {
				String rawName = method.findParameterNameByAlias(property.value0);
				methodBuilder.addJavadoc("\t<dt>$L</dt>", SqlAnalyzer.PARAM_PREFIX + property.value0 + SqlAnalyzer.PARAM_SUFFIX);
				methodBuilder.addJavadoc("<dd>is mapped to method's parameter <strong>$L</strong></dd>\n", rawName);
			}
			methodBuilder.addJavadoc("</dl>");
		} else {
			methodBuilder.addJavadoc("<p>No where parameters were found.</p>");
		}
		methodBuilder.addJavadoc("\n\n");

		if (method.hasDynamicWhereConditions()) {
			methodBuilder.addJavadoc("<dl>\n");
			methodBuilder.addJavadoc("<dt>$L</dt><dd>is part of where conditions resolved at runtime. In above SQL it is displayed as #{$L}</dd>", method.dynamicWhereParameterName,
					JQLDynamicStatementType.DYNAMIC_WHERE);
			methodBuilder.addJavadoc("\n</dl>");
			methodBuilder.addJavadoc("\n\n");
		}

		// dynamic conditions
		if (method.hasDynamicWhereConditions()) {
			methodBuilder.addJavadoc("<h2>Method's parameters and associated dynamic parts:</h2>\n");
			methodBuilder.addJavadoc("<dl>\n");

			if (method.hasDynamicWhereConditions()) {
				methodBuilder.addJavadoc("<dt>$L</dt><dd>is part of where conditions resolved at runtime. In above SQL it is displayed as #{$L}</dd>", method.dynamicWhereParameterName,
						JQLDynamicStatementType.DYNAMIC_WHERE);
			}

			methodBuilder.addJavadoc("</dl>");
			methodBuilder.addJavadoc("\n\n");
		}

		// method parameters
		if (methodParams.size() > 0) {
			for (Pair<String, TypeName> param : methodParams) {
				String resolvedName = method.findParameterAliasByName(param.value0);
				methodBuilder.addJavadoc("@param $L", param.value0);
				if (method.isThisDynamicWhereConditionsName(param.value0)) {
					methodBuilder.addJavadoc("\n\tis used as dynamic where conditions\n");
				} else if (where.value1.contains(new Pair<>(resolvedName, param.value1))) {
					methodBuilder.addJavadoc("\n\tis used as where parameter <strong>$L</strong>\n", SqlAnalyzer.PARAM_PREFIX + resolvedName + SqlAnalyzer.PARAM_SUFFIX);
				} else {
					methodBuilder.addJavadoc("\n\tis used as updated field <strong>$L</strong>\n", resolvedName);
				}
			}
		}

		// if true, field must be associate to ben attributes
		TypeName returnType = method.getReturnClass();
		// define return value
		if (returnType == TypeName.VOID) {

		} else {
			methodBuilder.addJavadoc("\n");
			if (isIn(returnType, Boolean.TYPE, Boolean.class)) {
				if (updateMode) {
					methodBuilder.addJavadoc("@return <code>true</code> if record is updated, <code>false</code> otherwise");
				} else {
					methodBuilder.addJavadoc("@return <code>true</code> if record is deleted, <code>false</code> otherwise");
				}
				// methodBuilder.addCode("return result!=0;\n");
			} else if (isIn(returnType, Long.TYPE, Long.class, Integer.TYPE, Integer.class, Short.TYPE, Short.class)) {
				if (updateMode) {
					methodBuilder.addJavadoc("@return number of updated records");
				} else {
					methodBuilder.addJavadoc("@return number of deleted records");
				}

				// methodBuilder.addCode("return result;\n");
			} else {
				// more than one listener found
				throw (new InvalidMethodSignException(method, "invalid return type"));
			}
			methodBuilder.addJavadoc("\n");
		}

	}
800178
private MethodDeclaration generateToBuilderMethod(String builderClassName, String builderImplClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source) {
		int pS = source.sourceStart, pE = source.sourceEnd;
		long p = (long) pS << 32 | pE;
		
		MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
		out.selector = TO_BUILDER_METHOD_NAME;
		out.modifiers = ClassFileConstants.AccPublic;
		out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
		
		TypeReference[] wildcards = new TypeReference[] {new Wildcard(Wildcard.UNBOUND), new Wildcard(Wildcard.UNBOUND) };
		out.returnType = new ParameterizedSingleTypeReference(builderClassName.toCharArray(), mergeToTypeReferences(typeParams, wildcards), 0, p);
		
		AllocationExpression newClass = new AllocationExpression();
		newClass.type = namePlusTypeParamsToTypeReference(builderImplClassName.toCharArray(), typeParams, p);
		MessageSend invokeFillMethod = new MessageSend();
		invokeFillMethod.receiver = newClass;
		invokeFillMethod.selector = FILL_VALUES_METHOD_NAME;
		invokeFillMethod.arguments = new Expression[] {new ThisReference(0, 0)};
		out.statements = new Statement[] {new ReturnStatement(invokeFillMethod, pS, pE)};
		
		out.traverse(new SetGeneratedByVisitor(source), ((TypeDeclaration) type.get()).scope);
		return out;
	}
1374995
private MethodMetaData<? extends Annotation> getMethodMetaData(Method method) {
      MethodMetaData<? extends Annotation> methodMetaData = methodMetaDataCache.get(method);

      if (methodMetaData == null) {
         final String cacheName;
         final Annotation cacheAnnotation;
         final AggregatedParameterMetaData aggregatedParameterMetaData;
         final CacheKeyGenerator cacheKeyGenerator;
         final CacheDefaults cacheDefaultsAnnotation = method.getDeclaringClass().getAnnotation(CacheDefaults.class);

         if (method.isAnnotationPresent(CacheResult.class)) {
            final CacheResult cacheResultAnnotation = method.getAnnotation(CacheResult.class);
            cacheKeyGenerator = getCacheKeyGenerator(beanManager, cacheResultAnnotation.cacheKeyGenerator(), cacheDefaultsAnnotation);
            cacheName = getCacheName(method, cacheResultAnnotation.cacheName(), cacheDefaultsAnnotation, true);
            aggregatedParameterMetaData = getAggregatedParameterMetaData(method, false);
            cacheAnnotation = cacheResultAnnotation;

         } else if (method.isAnnotationPresent(CacheRemove.class)) {
            final CacheRemove cacheRemoveEntryAnnotation = method.getAnnotation(CacheRemove.class);
            cacheKeyGenerator = getCacheKeyGenerator(beanManager, cacheRemoveEntryAnnotation.cacheKeyGenerator(), cacheDefaultsAnnotation);
            cacheName = getCacheName(method, cacheRemoveEntryAnnotation.cacheName(), cacheDefaultsAnnotation, false);
            aggregatedParameterMetaData = getAggregatedParameterMetaData(method, false);
            cacheAnnotation = cacheRemoveEntryAnnotation;

            if (cacheName.isEmpty()) {
               throw log.cacheRemoveEntryMethodWithoutCacheName(method.getName());
            }

         } else if (method.isAnnotationPresent(CacheRemoveAll.class)) {
            final CacheRemoveAll cacheRemoveAllAnnotation = method.getAnnotation(CacheRemoveAll.class);
            cacheKeyGenerator = null;
            cacheName = getCacheName(method, cacheRemoveAllAnnotation.cacheName(), cacheDefaultsAnnotation, false);
            aggregatedParameterMetaData = getAggregatedParameterMetaData(method, false);
            cacheAnnotation = cacheRemoveAllAnnotation;

            if (cacheName.isEmpty()) {
               throw log.cacheRemoveAllMethodWithoutCacheName(method.getName());
            }

         } else if (method.isAnnotationPresent(CachePut.class)) {
            final CachePut cachePutAnnotation = method.getAnnotation(CachePut.class);
            cacheKeyGenerator = getCacheKeyGenerator(beanManager, cachePutAnnotation.cacheKeyGenerator(), cacheDefaultsAnnotation);
            cacheName = getCacheName(method, cachePutAnnotation.cacheName(), cacheDefaultsAnnotation, true);
            aggregatedParameterMetaData = getAggregatedParameterMetaData(method, true);
            cacheAnnotation = cachePutAnnotation;

         } else {
            throw log.methodWithoutCacheAnnotation(method.getName());
         }

         final MethodMetaData<? extends Annotation> newCacheMethodMetaData = new MethodMetaData<Annotation>(
               method,
               aggregatedParameterMetaData,
               asSet(method.getAnnotations()),
               cacheKeyGenerator,
               cacheAnnotation,
               cacheName
         );

         methodMetaData = methodMetaDataCache.putIfAbsent(method, newCacheMethodMetaData);
         if (methodMetaData == null) {
            methodMetaData = newCacheMethodMetaData;
         }
      }

      return methodMetaData;
   }
995174
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 <code>true</code> if record is updated, <code>false</code> otherwise");
			else
				methodBuilder.addJavadoc("@return <code>true</code> if record is deleted, <code>false</code> 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"));
		}
	}