Used to convert a generic parameter to where conditions.

@param methodBuilder
the method builder
@param method
the method
@param methodParamName
name of the parameter in the method
@param paramName
the param name
@param paramType
the param type
182884
public static void javaMethodParam2WhereConditions(MethodSpec.Builder methodBuilder, SQLiteModelMethod method,
			String methodParamName, String paramName, TypeName paramType) {
		if (method.hasAdapterForParam(methodParamName)) {
			
			checkTypeAdapterForParam(method, methodParamName, BindSqlParam.class);
			
			methodBuilder.addCode(
					AbstractSQLTransform.PRE_TYPE_ADAPTER_TO_STRING + "$L" + AbstractSQLTransform.POST_TYPE_ADAPTER,
					SQLTypeAdapterUtils.class, method.getAdapterForParam(methodParamName), paramName);
		} else {
			SQLTransform transform = lookup(paramType);

			AssertKripton.assertTrueOrUnsupportedFieldTypeException(transform != null, paramType);
			transform.generateWriteParam2WhereCondition(methodBuilder, method, paramName, paramType);
		}
	}
1210845
public static Map<Integer, List<AnnotationInstance>> createParameterAnnotationMap(final MethodInfo method) {
        final Map<Integer, List<AnnotationInstance>> result = new HashMap<>();
        for (AnnotationInstance ai : method.annotations()) {
            final AnnotationTarget at = ai.target();
            if (at.kind() == AnnotationTarget.Kind.METHOD_PARAMETER) {
                final MethodParameterInfo mp = at.asMethodParameter();
                final int pos = (int) mp.position();
                List<AnnotationInstance> list = result.get(pos);
                if (list == null) {
                    list = new ArrayList<>();
                    result.put(pos, list);
                }
                list.add(ai);
            }
        }
        return result;
    }
699221
private CodeBlock methodCallCodeWithClassParameters( MapperInstance instance, ImmutableList<? extends JType> parameters ) {
        CodeBlock.Builder builder = initMethodCallCode( instance );
        return methodCallParametersCode( builder, Lists.transform( parameters, new Function<JType, CodeBlock>() {

            @Override
            public CodeBlock apply( JType jType ) {
                return CodeBlock.builder().add( "$T.class", typeName( jType ) ).build();
            }
        } ) );
    }
671898
public List<ValidationData> findByParamTypeAndMethodAndUrlAndName(ParamType paramType, String method, String url, String name) {
        return this.findByMethodAndUrlAndName(method, url, name).stream().filter(vd -> vd.getParamType().equals(paramType)).collect(Collectors.toList());
    }
1357659
public AnnotatedTypeBuilder<X> addToMethod(Method method, Annotation annotation) {
       if (methods.get(method) == null) {
           methods.put(method, new AnnotationBuilder());
       }
       methods.get(method).add(annotation);
       return this;
   }
313312
public static int match(Method[] methods, String name, Type... params) {
        int paramCount = params.length;
        int matchCount = methods.length;
        Method m;

        int[] costs = new int[matchCount];

        // Filter the available methods down to a smaller set, tossing
        // out candidates that could not possibly match because the name
        // differs, and the number of parameters differ. Also eliminate
        // ones in which the parameter types are not compatible at all
        // because no known conversion could be applied.

        int lowestTotalCost = Integer.MAX_VALUE;
        int length = matchCount;
        matchCount = 0;
        for (int i=0; i < length; i++) {
            m = methods[i];
            if (m.isBridge()) { continue; }
            
            if (name == null || m.getName().equals(name)) {
                Class<?>[] methodParams = m.getParameterTypes();
                
                int cnt = methodParams.length;
                if ((cnt == paramCount) || 
                    (m.isVarArgs() && paramCount >= cnt - 1)) {
                    
                    int j = 0;
                    int total = 0;
                    for (; j < paramCount; j++) {
                        MethodParam result = getMethodParameter(m, j, params[j]);
                        Type methodParam = result.type;
                        int cost = methodParam.convertableFrom(params[j], result.vararg);
                        if (cost < 0) { break; }
                        
                        // update total cost
                        total += cost;
                    }

                    if (j == paramCount) {
                        // increase cost for non-use of var args
                        if (m.isVarArgs() && j < methodParams.length) {
                            total++;
                        }
                        
                        costs[matchCount] = total;
                        methods[matchCount++] = m;
                        if (total < lowestTotalCost) {
                            lowestTotalCost = total;
                        }
                    }
                }
            }
        }

        if (matchCount <= 1) {
            return matchCount;
        }

        // Filter out those that have a cost higher than lowestTotalCost.
        length = matchCount;
        matchCount = 0;
        for (int i=0; i < length; i++) {
            if (costs[i] <= lowestTotalCost) {
                costs[matchCount] = costs[i];
                methods[matchCount++] = methods[i];
            }
        }

        if (matchCount <= 1) {
            return matchCount;
        }

        // If one match is non-varargs and remaining are varargs, always choose
        // the non-varargs.
        Method last = null;
        for (int i = 0; i < matchCount; i++) {
            m = methods[i];
            if (!m.isVarArgs()) {
                if (last == null) {
                    last = m;
                }
                else {
                    // multiple non-vararg methods found, so still ambiguous
                    last = null;
                    break;
                }
            }
        }
        
        if (last != null) {
            // ensure first result is set to match
            methods[0] = last;
            
            // return single result
            return 1;
        }
        
        // Filter further by matching parameters with the shortest distance
        // in the hierarchy. This matches each parameter to each matching method
        // to either find the best possible match where the method parameter is
        // the shortest. If multiple matches exist, the parameter is considered
        // ambiguous. If all parameters are ambiguous, then this will return -1
        // as a failiure. If multiple methods match for different parmaters,
        // then the result is also considered ambiguous and -1 returned. For
        // example, the methods:
        //     void doX(String a, Object b)
        //     void doX(Object a, String b)
        // with the method: 
        //     doX("string1", "string2")
        // will best match the first method as String is closer than object but
        // will best match the second method as again String is closer. Thus,
        // the result is ambiguous.

        // maintain the best matching method per parameter
        Method[] paramResults = new Method[paramCount];
        
        // search each parameter separately to find best matching method
        for (int j=0; j<paramCount; j++) {
            Class<?> lastMatch = null;
            Method bestFit = null;
            
            length = matchCount;
            int bestFits = 0;
            
            // search each matching method for the best match. If we have not
            // yet marked a best fit, then we mark the first method. Otherwise,
            // if the next method is closer (ie: the last match is assignable)
            // then we update the best fit. If the last match ever matches
            // the current match, then it is considered ambiguous and the best
            // fit is reset.
            
            for (int i = 0; i < length; i++) {
                m = methods[i];
                if (m.isBridge()) { continue; }
                
                MethodParam result = getMethodParameter(m, j, params[j]);
                Type methodType = result.type;
                Class<?> methodParam = methodType.getNaturalClass();
                
                // TODO: match against generics?
                //java.lang.reflect.Type methodType = methodType.getGeneric();

                Class<?> param = params[j].getNaturalClass();
                if (methodParam.isAssignableFrom(param)) {
                	
                	// check for ambiguity by determining if multiple methods
                	// have same type
                	
                    if (lastMatch != null) {
                        if (lastMatch.equals(methodParam)) {
                            bestFits++;
                        }
                        else { bestFits = 0; }
                    }

                    // if first time through or last match is assignable (ie:
                    // farther away), then update best fit
                    
                    if (lastMatch == null ||
                        lastMatch.isAssignableFrom(methodParam)) {
                        
                        bestFit = m;
                        lastMatch = methodParam;
                    }
                }
            }

            // set best fitting method if single match...otherwise, leave null
            // to denote ambiguous result
            
            if (bestFits == 0) {
            	paramResults[j] = bestFit;
            }
        }
        
        // check if multiple matching methods (ambiguous) or if all params are
        // ambiguous
        
        for (int i = 0; i < paramCount; i++) {
        	// update last match if not yet determined
        	if (last == null) {
        		last = paramResults[i];
        	}
        	
    		// check if non-match (ie: multiple matching methods), and return
        	// ambiguous (-1)
        	else if (!last.equals(paramResults[i])) {
        		return AMBIGUOUS;
        	}
        }
        
        // check if all ambiguous..no matches
        if (last == null) {
        	return AMBIGUOUS;
        }
        
        // ensure first result is set to match
        methods[0] = last;
        
        // return single result
        return 1;
    }
323590
@Override
    public <E> DynamicType.Builder<E> processMethod(final DynamicType.Builder<E> builder, final Method method, final Annotation annotation)
    {
        String methodName = method.getName();
        if (ReflectionUtility.isGetMethod(method))
            return createInterceptor(builder, method);
        else if (ReflectionUtility.isSetMethod(method))
            return createInterceptor(builder, method);
        else if (methodName.startsWith("addAll"))
            return createInterceptor(builder, method);
        else if (methodName.startsWith("add"))
            return createInterceptor(builder, method);
        else
            throw new WindupException("Only get*, set*, add*, and addAll* method names are supported for @"
                        + SetInProperties.class.getSimpleName() + ", found at: " + method.getName());
    }
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");
		}
	}
155562
private void generateJavaDoc(final SQLiteModelMethod method, Builder methodBuilder, boolean updateMode) {
		List<Pair<String, TypeName>> methodParams = method.getParameters();

		final List<SQLProperty> updatedProperties = new ArrayList<>();
		final List<Pair<String, TypeName>> methodParamsUsedAsParameter = new ArrayList<>();

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

			@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);

				methodParamsUsedAsParameter.add(new Pair<>(resolvedParamName, method.findParameterType(resolvedParamName)));

				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>\n", sqlModify);
			methodBuilder.addJavadoc("\n\n");
		}

		// list of where parameter
		methodBuilder.addJavadoc("<h2>Parameters:</h2>\n");
		methodBuilder.addJavadoc("<dl>\n");
		for (Pair<String, TypeName> property : methodParamsUsedAsParameter) {
			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>");
		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 {
					methodBuilder.addJavadoc("\n\tis used as for parameter <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");
		}

	}
187865
private void registerMethod(Method method) {
    Type genericType = method.getGenericParameterTypes()[0];
    Class<?> argumentType = resolveArgument(genericType);
    if (argumentType != null && Operation.class.isAssignableFrom(argumentType)) {
      registerMethod(argumentType, method);
    }
  }
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);

		}

	}
156724
@SuppressWarnings("all")
    public static Method findMethodOrThrowException(Class<?> type, String methodName, Class<?>... parameterTypes) {
        Method methodToMock = findMethod(type, methodName, parameterTypes);
        throwExceptionIfMethodWasNotFound(type, methodName, methodToMock, (Object[]) parameterTypes);
        return methodToMock;
    }
510780
protected void generateMethodSignature(SQLiteModelMethod method, MethodSpec.Builder methodBuilder, TypeName returnTypeName, ParameterSpec... additionalParameterSpec) {
		boolean finalParameter = false;
		if (method.hasLiveData() && returnTypeName.equals(method.liveDataReturnClass)) {
			finalParameter = true;
		}

		// add parameter for method
		for (Pair<String, TypeName> item : method.getParameters()) {
			ParameterSpec.Builder builder = ParameterSpec.builder(item.value1, item.value0);

			if (finalParameter) {
				builder.addModifiers(Modifier.FINAL);
			}

			methodBuilder.addParameter(builder.build());
		}

		// add additional params
		for (ParameterSpec item : additionalParameterSpec) {
			methodBuilder.addParameter(item);
		}

		// add return type
		methodBuilder.returns(returnTypeName);
	}
563889
final public void MethodParameters() throws ParseException {
                                             /*@bgen(jjtree) MethodParameters */
  AstMethodParameters jjtn000 = new AstMethodParameters(JJTMETHODPARAMETERS);
  boolean jjtc000 = true;
  jjtree.openNodeScope(jjtn000);
    try {
      jj_consume_token(LPAREN);
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case START_SET_OR_MAP:
      case INTEGER_LITERAL:
      case FLOATING_POINT_LITERAL:
      case STRING_LITERAL:
      case TRUE:
      case FALSE:
      case NULL:
      case LPAREN:
      case LBRACK:
      case NOT0:
      case NOT1:
      case EMPTY:
      case MINUS:
      case IDENTIFIER:
        Expression();
        label_15:
        while (true) {
          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
          case COMMA:
            ;
            break;
          default:
            jj_la1[37] = jj_gen;
            break label_15;
          }
          jj_consume_token(COMMA);
          Expression();
        }
        break;
      default:
        jj_la1[38] = jj_gen;
        ;
      }
      jj_consume_token(RPAREN);
    } catch (Throwable jjte000) {
      if (jjtc000) {
        jjtree.clearNodeScope(jjtn000);
        jjtc000 = false;
      } else {
        jjtree.popNode();
      }
      if (jjte000 instanceof RuntimeException) {
        {if (true) throw (RuntimeException)jjte000;}
      }
      if (jjte000 instanceof ParseException) {
        {if (true) throw (ParseException)jjte000;}
      }
      {if (true) throw (Error)jjte000;}
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
  }
174240
public static boolean isMatch(Method javaMethod,
                                String name, Class<?> []param)
  {
    if (! javaMethod.getName().equals(name))
      return false;

    Class<?> []mparam = javaMethod.getParameterTypes();

    return isMatch(mparam, param);
  }
451180
public static void validateArgument(Method method, Class<? extends Annotation> annotationType,
                                        Class<?> expectedParameterType) {
        if (method.getParameterTypes().length != 1 || !method.getParameterTypes()[0].equals(expectedParameterType)) {
            throw new BeanCreationException(String.format(
                  "Method %s with @%s MUST take a single argument of type %s",
                  method,
                  annotationType.getName(),
                  expectedParameterType.getName()
            ));
        }
    }
686214
protected void writeArrayOutParamsToProxy(VariableElement param, MethodSpec.Builder methodBuilder) {
        methodBuilder.beginControlFlow("if (" + param.getSimpleName() + " == null)");
        methodBuilder.addStatement("data.writeInt(-1)");
        methodBuilder.endControlFlow();
        methodBuilder.beginControlFlow("else");
        methodBuilder.addStatement("data.writeInt(" + param.getSimpleName() + ".length)");
        methodBuilder.endControlFlow();
    }