<p>
Generate log for INSERT operations
</p>
.

@param method
the method
@param methodBuilder
the method builder
17225
public static void generateSQLForInsertDynamic(final SQLiteModelMethod method, MethodSpec.Builder methodBuilder) {
		methodBuilder.addComment("generate SQL for insert");
		JQLChecker checker = JQLChecker.getInstance();

		// replace the table name, other pieces will be removed
		String sql = checker.replace(method, method.jql, new JQLReplacerListenerImpl(method) {

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

		final One<Integer> counter = new One<Integer>(0);
		sql = checker.replaceVariableStatements(method, sql, new JQLReplaceVariableStatementListenerImpl() {

			@Override
			public String onColumnNameSet(String statement) {
				counter.value0++;
				return "%s";
			}

			@Override
			public String onColumnValueSet(String statement) {
				counter.value0++;
				return "%s";
			}

		});

		if (counter.value0 == 2) {
			methodBuilder.addStatement("String _sql=String.format($S, _contentValues.keyList(), _contentValues.keyValueList())", sql);
		} else {
			methodBuilder.addStatement("String _sql=String.format($S, _contentValues.keyList())", sql);
		}
	}
1090616
public static void warn(Logger log, String methodName) {
        if (log.isWarnEnabled())
            log.warn(buildMethodLogString(methodName));
    }
1302730
public static void generateGenericExecSQL(MethodSpec.Builder methodBuilder, final SQLiteModelMethod method) {

		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, boolean inStatement) {
				String propertyName = method.findParameterAliasByName(bindParameterName);

				if (columnsToUpdate.value0) {
					contentValueList.add(propertyName);
				} else {
					paramsList.add(propertyName);
				}
				return "?";
			}
		});

		// update/insert columns
		final SQLiteEntity entity = method.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);
			// check nullabliity
			// nullable = TypeUtility.isNullable(method, methodParam, property);
			//
			// if (nullable) {
			// // it use raw method param's typeName
			// methodBuilder.beginControlFlow("if ($L!=null)", methodParam.value0);
			// }

			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);
	}
1202730
public static void generate(TypeSpec.Builder classBuilder, SQLiteModelMethod method) {

		ModifyType updateResultType = detectModifyType(method, method.jql.operationType);

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

		if (updateResultType == null) {
			throw (new InvalidMethodSignException(method));
		}

		// generate method code
		MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(method.getName()).addAnnotation(Override.class)
				.addModifiers(Modifier.PUBLIC);
		ParameterSpec parameterSpec;
		for (Pair<String, TypeName> item : method.getParameters()) {
			parameterSpec = ParameterSpec.builder(item.value1, item.value0).build();
			methodBuilder.addParameter(parameterSpec);
		}
		methodBuilder.returns(returnType);

		// generate inner code
		updateResultType.generate(classBuilder, methodBuilder, method, returnType);

		MethodSpec methodSpec = methodBuilder.build();
		classBuilder.addMethod(methodSpec);

		if (method.contentProviderEntryPathEnabled) {
			// delete-select, update-select can be used with content provider
			// insert-select no

			// if (method.jql.containsSelectOperation && updateResultType==) {
			// AssertKripton.failWithInvalidMethodSignException(true, method, "
			// SQL with inner SELECT can not be used in content provider");
			// }

			generateModifierForContentProvider(BaseProcessor.elementUtils, classBuilder, method, updateResultType);

		}

	}
331966
@Override
    public void setMethod(byte[] method) throws UnsupportedMethodException {
        MethodValues val = MethodValues.match(method, 0, method.length);
        if (null == val) {
            throw new UnsupportedMethodException("Illegal method " + GenericUtils.getEnglishString(method));
        }
        setMethod(val);
    }
1325580
public void addStubMethods(TypeSpec.Builder classBuilder) {

        MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("onTransact")
                .addModifiers(Modifier.PUBLIC)
                .addAnnotation(Override.class)
                .returns(boolean.class)
                .addException(ClassName.get("android.os", "RemoteException"))
                .addParameter(int.class, "code")
                .addParameter(ClassName.get("android.os", "Parcel"), "data")
                .addParameter(ClassName.get("android.os", "Parcel"), "reply")
                .addParameter(int.class, "flags");

        methodBuilder.beginControlFlow("try");
        methodBuilder.beginControlFlow("switch (code)");

        methodBuilder.beginControlFlow("case INTERFACE_TRANSACTION:");
        methodBuilder.addStatement("reply.writeString(DESCRIPTOR)");
        methodBuilder.addStatement("return true");
        methodBuilder.endControlFlow();

        processRemoterElements(classBuilder, new ElementVisitor() {
            @Override
            public void visitElement(TypeSpec.Builder classBuilder, Element member, int methodIndex, MethodSpec.Builder methodBuilder) {
                addStubMethods(classBuilder, member, methodIndex, methodBuilder);
            }
        }, methodBuilder);


        methodBuilder.beginControlFlow("case TRANSACTION__getStubID:");
        methodBuilder.addStatement("data.enforceInterface(DESCRIPTOR)");
        methodBuilder.addStatement("reply.writeNoException()");
        methodBuilder.addStatement("reply.writeInt(serviceImpl.hashCode())");
        methodBuilder.addStatement("return true");
        methodBuilder.endControlFlow();


        //end switch
        methodBuilder.endControlFlow();
        //end of try
        methodBuilder.endControlFlow();
        //catch rethrow
        methodBuilder.beginControlFlow("catch ($T re)", Throwable.class);
        methodBuilder.beginControlFlow("if ((flags & FLAG_ONEWAY) == 0)");
        methodBuilder.addStatement("reply.setDataPosition(0)");
        methodBuilder.addStatement("reply.writeInt(REMOTER_EXCEPTION_CODE)");
        methodBuilder.addStatement("reply.writeString(re.getMessage())");
        methodBuilder.addStatement("reply.writeSerializable(re)");
        methodBuilder.endControlFlow();
        methodBuilder.beginControlFlow("else");
        methodBuilder.addStatement("$T.w(serviceImpl.getClass().getName(), \"Binder call failed.\", re)", ClassName.get("android.util", "Log"));
        methodBuilder.endControlFlow();
        methodBuilder.addStatement("return true");
        methodBuilder.endControlFlow();
        methodBuilder.addStatement("return super.onTransact(code, data, reply, flags)");
        classBuilder.addMethod(methodBuilder.build());
        addCommonExtras(classBuilder);

        addStubExtras(classBuilder);

    }
1026055
private void addMethodInfo(MethodDoc method, Content dl) {
        ClassDoc[] intfacs = method.containingClass().interfaces();
        MethodDoc overriddenMethod = method.overriddenMethod();
        // Check whether there is any implementation or overridden info to be
        // printed. If no overridden or implementation info needs to be
        // printed, do not print this section.
        if ((intfacs.length > 0 &&
                new ImplementedMethods(method, this.configuration).build().length > 0) ||
                overriddenMethod != null) {
            MethodWriterImpl.addImplementsInfo(this, method, dl);
            if (overriddenMethod != null) {
                MethodWriterImpl.addOverridden(this,
                        method.overriddenType(), overriddenMethod, dl);
            }
        }
    }
305415
@Override
	public void generateSpecializedPart(SQLiteModelMethod method, TypeSpec.Builder classBuilder, MethodSpec.Builder methodBuilder, Set<JQLProjection> fieldList, boolean mapFields) {
		//LiteralType listenerType=LiteralType.of(OnReadCursorListener.class);
		ClassName listenerType=ClassName.get(OnReadCursorListener.class);
		
		int counter = SqlBuilderHelper.countParameterOfType(method, listenerType);
		if (counter == 0) {
			// non listener found
			throw (new InvalidMethodSignException(method, "there is no parameter of type \"ReadCursorListener\""));
		}
		if (counter > 1) {
			// more than one listener found
			throw (new InvalidMethodSignException(method, "there are more than one parameter of type \"ReadCursorListener\""));
		}

		String listenerName = SqlSelectBuilder.getNameParameterOfType(method, listenerType);

		methodBuilder.addCode("\n");
		methodBuilder.beginControlFlow("if (_cursor.moveToFirst())");

		// generate index from columns
		methodBuilder.addCode("\n");

		methodBuilder.beginControlFlow("do\n");
		methodBuilder.addCode("$L.onRead(_cursor);\n", listenerName);
		methodBuilder.endControlFlow("while (_cursor.moveToNext())");

		// close cursor
		methodBuilder.endControlFlow();
		methodBuilder.endControlFlow();

	}
857416
public static void javaProperty2WhereCondition(MethodSpec.Builder methodBuilder, SQLiteModelMethod method,
			String paramName, TypeName paramType, ModelProperty property) {
		if (property != null && property.hasTypeAdapter()) {
			methodBuilder.addCode(
					AbstractSQLTransform.PRE_TYPE_ADAPTER_TO_STRING + "$L" + AbstractSQLTransform.POST_TYPE_ADAPTER,
					SQLTypeAdapterUtils.class, typeName(property.typeAdapter.adapterClazz),
					PropertyUtility.getter(paramName, paramType, property));
		} else if (property != null) {
			SQLTransform transform = lookup(property.getPropertyType().getTypeName());

			AssertKripton.assertTrueOrUnsupportedFieldTypeException(transform != null, paramType);
			transform.generateWriteProperty2WhereCondition(methodBuilder, paramName, paramType, property);
		} else {
			AssertKripton.assertTrueOrUnsupportedFieldTypeException(false, paramType);
		}
	}
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());
	}
167792
@Override
	public void generateSpecializedPart(SQLiteModelMethod method, TypeSpec.Builder classBuilder, MethodSpec.Builder methodBuilder, Set<JQLProjection> fieldList, boolean mapFields) {
		TypeName returnTypeName = method.getReturnClass();

		//ASSERT: returnType is a supported type
		
		// no column or too many columns
		AssertKripton.assertTrueOrInvalidMethodSignException(fieldList.size() == 1, method, "no way to understand which field is the result for this method");				

		SQLTransform t = SQLTransformer.lookup(returnTypeName);

		methodBuilder.addCode("$T result=", returnTypeName);
		t.generateDefaultValue(methodBuilder);
		methodBuilder.addCode(";\n");

		methodBuilder.addCode("\n");
		// methodBuilder.beginControlFlow("try");
		methodBuilder.beginControlFlow("if (_cursor.moveToFirst())");

		// generate index from columns
		methodBuilder.addCode("\n");

		if (TypeUtility.isNullable(returnTypeName)) {
			methodBuilder.addCode("if (_cursor.isNull(0)) { return null; }\n");
		} else {
			methodBuilder.addCode("if (_cursor.isNull(0)) { return ");
			t.generateDefaultValue(methodBuilder);
			methodBuilder.addCode("; }\n", t);
		}
		methodBuilder.addCode("result=");
		t.generateReadValueFromCursor(methodBuilder, method.getParent(), returnTypeName, "_cursor", "0");
		methodBuilder.addCode(";\n");

		// end cursor
		methodBuilder.endControlFlow();

		methodBuilder.addCode("return result;\n");
		// end method
		methodBuilder.endControlFlow();
	}
1364522
public static void generateWhereCondition(MethodSpec.Builder methodBuilder, SQLiteModelMethod method, Pair<String, List<Pair<String, TypeName>>> where) {
		boolean nullable;

		// methodBuilder.addStatement("$T<String>
		// _sqlWhereParams=getWhereParamsArray()", ArrayList.class);

		for (Pair<String, TypeName> item : where.value1) {
			String resolvedParamName = method.findParameterNameByAlias(item.value0);
			// methodBuilder.addCode("_sqlWhereParams.add(");
			methodBuilder.addCode("_contentValues.addWhereArgs(");

			nullable = isNullable(item.value1);

			if (nullable && !method.hasAdapterForParam(item.value0)) {
				// transform null in ""
				methodBuilder.addCode("($L==null?\"\":", resolvedParamName);
			}

			// check for string conversion
			TypeUtility.beginStringConversion(methodBuilder, item.value1);

			SQLTransformer.javaMethodParam2WhereConditions(methodBuilder, method, resolvedParamName, item.value1);
			// check for string conversion
			TypeUtility.endStringConversion(methodBuilder, item.value1);

			if (nullable && !method.hasAdapterForParam(item.value0)) {
				methodBuilder.addCode(")");
			}

			methodBuilder.addCode(");\n");
		}
	}
72158
private void doMethod(CtBehavior method) throws NotFoundException, CannotCompileException {

        String signature = JavassistHelper.getSignature(method);
        String returnValue = JavassistHelper.returnValue(method);

        if (addEntryExit) {
            String messagePattern = "if ({}.{}()) {}.{}(\">> {}\");";
            Object[] arg1 = new Object[] { loggerName, levelEnabled, loggerName, level, signature };
            String before = MessageFormatter.arrayFormat(messagePattern, arg1).getMessage();
            // System.out.println(before);
            method.insertBefore(before);

            String messagePattern2 = "if ({}.{}()) {}.{}(\"<< {}{}\");";
            Object[] arg2 = new Object[] { loggerName, levelEnabled, loggerName, level, signature, returnValue };
            String after = MessageFormatter.arrayFormat(messagePattern2, arg2).getMessage();
            // System.out.println(after);
            method.insertAfter(after);
        }
    }
561072
public static void validateMethodOrThrow(Method method) {
    Class<?> returnType = method.getReturnType();
    if (returnType.equals(Void.TYPE)) {
      return;
    } else if (!Publisher.class.isAssignableFrom(returnType)) {
      throw new UnsupportedOperationException("Service method return type can be Publisher only");
    }
    if (method.getParameterCount() > 1) {
      throw new UnsupportedOperationException("Service method can accept 0 or 1 parameters only");
    }
  }
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());
	}
328216
private void registerMethod(Class<?> type, Method method) {
    Class<?> returnType = method.getReturnType();
    if (returnType == void.class || returnType == Void.class) {
      registerVoidMethod(type, method);
    } else {
      registerValueMethod(type, method);
    }
  }
1130112
public void addProjectMethod(final ProjectMethod method) {
        readWriteLock.writeLock().lock();
        try {
            availableMethods.add(method);
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }