Detect select type

@param method
@return
@throws ClassNotFoundException
188031
public static SelectType detectSelectType(final SQLiteModelMethod method) {
		SQLiteEntity entity = method.getEntity();

		SelectBuilderUtility.SelectType selectResultType = null;

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

		ParameterizedTypeName readBeanListener = ParameterizedTypeName.get(ClassName.get(OnReadBeanListener.class),
				ClassName.get(entity.getElement()));
		ClassName readCursorListener = ClassName.get(OnReadCursorListener.class);

		ModelAnnotation annotation = method.getAnnotation(BindSqlSelect.class);
		int pageSize = annotation.getAttributeAsInt(AnnotationAttributeType.PAGE_SIZE);

		AssertKripton.failWithInvalidMethodSignException(pageSize < 0, method,
				"@%s#%s must be set with positive number", BindSqlSelect.class.getSimpleName(),
				AnnotationAttributeType.PAGE_SIZE.getValue());
		AssertKripton.failWithInvalidMethodSignException(pageSize > 0 && method.hasDynamicPageSizeConditions(), method,
				"can not define @%s#%s and mark a method parameter with @%s ", BindSqlSelect.class.getSimpleName(),
				BindSqlPageSize.class.getSimpleName(), AnnotationAttributeType.PAGE_SIZE.getValue());

		if (TypeUtility.isTypeIncludedIn(returnTypeName, Void.class, Void.TYPE)) {
			// return VOID (in the parameters must be a listener)
			if (SqlBuilderHelper.hasParameterOfType(method, readCursorListener)) {
				selectResultType = SelectBuilderUtility.SelectType.LISTENER_CURSOR;
			} else if (SqlBuilderHelper.hasParameterOfType(method, readBeanListener)) {
				selectResultType = SelectBuilderUtility.SelectType.LISTENER_BEAN;
			}
		} else if (TypeUtility.isTypeIncludedIn(returnTypeName, Cursor.class)) {
			// return Cursor (no listener)
			selectResultType = SelectBuilderUtility.SelectType.CURSOR;
		} else if (returnTypeName instanceof ParameterizedTypeName) {
			ParameterizedTypeName returnParameterizedTypeName = (ParameterizedTypeName) returnTypeName;
			ClassName returnParameterizedClassName = returnParameterizedTypeName.rawType;

			// return List (no listener)
			AssertKripton.assertTrueOrInvalidMethodSignException(returnParameterizedTypeName.typeArguments.size() == 1,
					method, "return type %s is not supported", returnTypeName);
			TypeName elementName = returnParameterizedTypeName.typeArguments.get(0);

			Class<?> wrapperClazz = null;
			try {
				wrapperClazz = Class.forName(returnParameterizedClassName.toString());
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
				throw (new KriptonClassNotFoundException(e));
			}
			if (PagedResultImpl.class.isAssignableFrom(wrapperClazz)) {
				// method must have pageSize, statically or dynamically
				// defined
				AssertKripton.assertTrueOrInvalidMethodSignException(
						method.hasDynamicPageSizeConditions() || pageSize > 0, method,
						"use of PaginatedResult requires 'pageSize' attribute or a @%s annotated parameter",
						returnTypeName, BindSqlPageSize.class.getSimpleName());

				// paged result
				AssertKripton.assertTrueOrInvalidMethodSignException(
						TypeUtility.isEquals(elementName, entity.getName().toString()), method,
						"return type %s is not supported", returnTypeName);
				selectResultType = SelectBuilderUtility.SelectType.PAGED_RESULT;
				// set typeName of paginatedResult
				method.paginatedResultName = "paginatedResult";
			} else if (Collection.class.isAssignableFrom(wrapperClazz)) {
				if (TypeUtility.isEquals(elementName, entity.getName().toString())) {
					// entity list
					selectResultType = SelectBuilderUtility.SelectType.LIST_BEAN;
				} else if (SQLTransformer.isSupportedJDKType(elementName) || TypeUtility.isByteArray(elementName)) {
					// scalar list
					selectResultType = SelectBuilderUtility.SelectType.LIST_SCALAR;
				} else {
					AssertKripton.failWithInvalidMethodSignException(true, method, "%s is an invalid return type",
							method.getReturnClass());
				}

			}
		} else if (TypeUtility.isEquals(returnTypeName, entity)) {
			// return one element (no listener)
			selectResultType = SelectBuilderUtility.SelectType.BEAN;
		} else if (SQLTransformer.isSupportedJDKType(returnTypeName) || TypeUtility.isByteArray(returnTypeName)) {
			// return single value string, int, long, short, double, float,
			// String (no listener)
			selectResultType = SelectBuilderUtility.SelectType.SCALAR;
		}

		AssertKripton.assertTrueOrInvalidMethodSignException(selectResultType != null, method,
				"'%s' as return type is not supported", returnTypeName);

		return selectResultType;
	}
346201
@Nullable
	@Override
	public String getMapping(Method method) {

		String key = key(method.getDeclaringClass(), method);

		return MAPPINGS.computeIfAbsent(key, __ -> delegate.getMapping(method));
	}
1201290
@Override
	@Nullable
	public String getMapping(Class<?> type, Method method) {

		Assert.notNull(type, "Type must not be null!");
		Assert.notNull(method, "Method must not be null!");

		String[] mapping = getMappingFrom(findMergedAnnotation(method, annotationType));
		String typeMapping = getMapping(type);

		if (mapping.length == 0) {
			return typeMapping;
		}

		return typeMapping == null || "/".equals(typeMapping) ? mapping[0] : join(typeMapping, mapping[0]);
	}
726109
public TypeMirror overriddenType(ExecutableElement method) {
        if (utils.isStatic(method)) {
            return null;
        }
        MethodSymbol sym = (MethodSymbol)method;
        ClassSymbol origin = (ClassSymbol) sym.owner;
        for (com.sun.tools.javac.code.Type t = toolEnv.getTypes().supertype(origin.type);
                t.hasTag(com.sun.tools.javac.code.TypeTag.CLASS);
                t = toolEnv.getTypes().supertype(t)) {
            ClassSymbol c = (ClassSymbol) t.tsym;
            for (com.sun.tools.javac.code.Symbol sym2 : c.members().getSymbolsByName(sym.name)) {
                if (sym.overrides(sym2, origin, toolEnv.getTypes(), true)) {
                    return t;
                }
            }
        }
        return null;
    }
564490
public GenericMetadataSupport resolveGenericReturnType(Method method) {
        Type genericReturnType = method.getGenericReturnType();
        // logger.log("Method '" + method.toGenericString() + "' has return type : " + genericReturnType.getClass().getInterfaces()[0].getSimpleName() + " : " + genericReturnType);

        int arity = 0;
        while (genericReturnType instanceof GenericArrayType) {
            arity++;
            genericReturnType = ((GenericArrayType) genericReturnType).getGenericComponentType();
        }

        GenericMetadataSupport genericMetadataSupport = resolveGenericType(genericReturnType, method);
        if (arity == 0) {
            return genericMetadataSupport;
        } else {
            return new GenericArrayReturnType(genericMetadataSupport, arity);
        }
    }
1088275
protected void checkNonGenericParameter(Method executeMethod, Parameter parameter) {
        if (isNonGenericCheckTargetType(parameter.getType())) { // e.g. List
            final Type paramedType = parameter.getParameterizedType();
            if (paramedType == null) { // no way? no check just in case
                return;
            }
            if (paramedType instanceof ParameterizedType) {
                final Type[] typeArgs = ((ParameterizedType) paramedType).getActualTypeArguments();
                if (typeArgs != null && typeArgs.length > 0 && "?".equals(typeArgs[0].getTypeName())) { // e.g. List<?>
                    throwActionFormWildcardOnlyListParameterException(executeMethod, parameter);
                }
            } else {
                throwActionFormNonGenericListParameterException(executeMethod, parameter);
            }
        }
    }
1197896
private static boolean isResolvedTypeMatch(
			Method genericMethod, Method candidateMethod, Class<?> declaringClass) {
		Type[] genericParameters = genericMethod.getGenericParameterTypes();
		Class<?>[] candidateParameters = candidateMethod.getParameterTypes();
		if (genericParameters.length != candidateParameters.length) {
			return false;
		}
		for (int i = 0; i < candidateParameters.length; i++) {
			ResolvableType genericParameter = ResolvableType.forMethodParameter(genericMethod, i, declaringClass);
			Class<?> candidateParameter = candidateParameters[i];
			if (candidateParameter.isArray()) {
				// An array type: compare the component type.
				if (!candidateParameter.getComponentType().equals(genericParameter.getComponentType().resolve(Object.class))) {
					return false;
				}
			}
			// A non-array type: compare the type itself.
			if (!candidateParameter.equals(genericParameter.resolve(Object.class))) {
				return false;
			}
		}
		return true;
	}
693477
public static <S> TypeInformation<S> fromMethodParameter(Method method, int index) {

        LettuceAssert.notNull(method, "Method must not be null!");
        return new ClassTypeInformation(method.getDeclaringClass()).createInfo(method.getGenericParameterTypes()[index]);
    }
409815
public static Method findMethod(Class<?> type, String methodName) {
        try {
            return type.getDeclaredMethod(methodName);
        } catch (NoSuchMethodException e) {
            if (type.equals(Object.class) || type.isInterface()) {
                throw new RuntimeException(e);
            }
            return findMethod(type.getSuperclass(), methodName);
        }
    }
568247
private boolean isBoxingMethod(ExecutableElement method) {
    TypeElement declaringClass = ElementUtil.getDeclaringClass(method);
    // Autoboxing methods.
    if (typeUtil.isBoxedType(declaringClass.asType())) {
      String name = ElementUtil.getName(method);
      TypeMirror returnType = method.getReturnType();
      List<? extends VariableElement> params = method.getParameters();
      if (name.equals("valueOf") && params.size() == 1
          && params.get(0).asType().getKind().isPrimitive()) {
        return true;
      }
      if (params.isEmpty() && returnType.getKind().isPrimitive()
          && name.equals(TypeUtil.getName(returnType) + "Value")) {
        return true;
      }
    }
    return false;
  }
337976
public static InsertType detectInsertType(SQLiteModelMethod method) {
		SQLiteDaoDefinition daoDefinition = method.getParent();
		SQLiteEntity entity = method.getEntity();
		TypeName beanTypeName = typeName(entity.getElement());

		InsertType insertResultType = null;

		// check type of arguments
		int beanCounter = 0;
		int beanCollectionCounter = 0;
		for (Pair<String, TypeName> param : method.getParameters()) {
			if (TypeUtility.isEquals(param.value1, beanTypeName)) {
				beanCounter++;
			} else if (TypeUtility.isCollectionOfType(param.value1, beanTypeName)) {
				beanCollectionCounter++;
			}
		}

		AssertKripton.failWithInvalidMethodSignException(method.getParameters().size() == 0, method,
				" INSERT operations require at least one parameter");

		if (beanCounter == 0 && beanCollectionCounter == 0) {
			// method to insert raw data: no bean is used
			insertResultType = InsertType.INSERT_RAW;

			ModelAnnotation annotation = method.getAnnotation(BindSqlInsert.class);

			// check value attribute
			AssertKripton.failWithInvalidMethodSignException(
					AnnotationUtility.extractAsStringArray(method, annotation, AnnotationAttributeType.FIELDS)
							.size() > 0,
					method, " can not use attribute %s in this kind of query definition",
					AnnotationAttributeType.FIELDS.getValue());

			// check excludeFields attribute
			AssertKripton.failWithInvalidMethodSignException(
					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());

			// check if there is only one parameter
			AssertKripton.failWithInvalidMethodSignException(method.getParameters().size() != 1
					&& TypeUtility.isEquals(method.getParameters().get(0).value1, daoDefinition.getEntityClassName()),
					method);

			// check no
			AssertKripton.failWithInvalidMethodSignException(
					annotation.getAttributeAsBoolean(AnnotationAttributeType.INCLUDE_PRIMARY_KEY), method,
					"attribute '%s' can not be used here", AnnotationAttributeType.INCLUDE_PRIMARY_KEY.getValue());

		} else if (beanCounter == 1) {
			insertResultType = InsertType.INSERT_BEAN;

			AssertKripton.failWithInvalidMethodSignException(method.getParameters().size() > 1, method,
					" aspected only one parameter of %s type", daoDefinition.getEntityClassName());
		} else if (beanCollectionCounter == 1) {
			insertResultType = InsertType.INSERT_LIST_BEAN;
			AssertKripton.failWithInvalidMethodSignException(method.getParameters().size() > 1, method,
					" aspected only one collection of %s type as parameter", daoDefinition.getEntityClassName());

			AssertKripton.assertTrueOrInvalidMethodSignException(
					TypeUtility.isCollectionOfType(method.getReturnClass(), beanTypeName)
							|| TypeUtility.isEquals(method.getReturnClass(), typeName(Void.TYPE)),
					method, " invalid return type for multiple insert method",
					daoDefinition.getEntityClassName());
		} else {
			throw (new InvalidMethodSignException(method,
					"only one parameter of type " + typeName(entity.getElement()) + " can be used"));
		}

		return insertResultType;
	}
407211
Class getMethodMapClass(Method method) {

        Class origMapClass = method.getDeclaringClass();
        Class mapClass = origMapClass;
        while (mapClass != null && !isValidMapClass(mapClass)) {
            mapClass = mapClass.getDeclaringClass();
        }
        if (mapClass == null) {
            mapClass = origMapClass;
        }
        return mapClass;
    }
146733
public static <S> TypeInformation<S> fromReturnTypeOf(Method method) {

        LettuceAssert.notNull(method, "Method must not be null!");
        return new ClassTypeInformation(method.getDeclaringClass()).createInfo(method.getGenericReturnType());
    }
533616
private static Optional<StandardMethod> maybeStandardMethod(ExecutableElement method) {
    String methodName = method.getSimpleName().toString();
    if (methodName.equals("equals")) {
      if (method.getParameters().size() == 1
          && method.getParameters().get(0).asType().toString().equals("java.lang.Object")) {
        return Optional.of(StandardMethod.EQUALS);
      } else {
        return Optional.empty();
      }
    } else if (methodName.equals("hashCode")) {
      if (method.getParameters().isEmpty()) {
        return Optional.of(StandardMethod.HASH_CODE);
      } else {
        return Optional.empty();
      }
    } else if (methodName.equals("toString")) {
      if (method.getParameters().isEmpty()) {
        return Optional.of(StandardMethod.TO_STRING);
      } else {
        return Optional.empty();
      }
    } else {
      return Optional.empty();
    }
  }
1279800
private static String getClassMethod(Class clazz, Method method) {
		StringBuilder builder = new StringBuilder();
		builder.append(clazz.getName()).append(".").append(method.getName());
		builder.append("(");
		if (method.getParameterCount() > 0) {
			for (int i = 0; i < method.getParameterCount(); i++) {
				Parameter param = method.getParameters()[i];
				builder.append(param.getType().getSimpleName()).append(" ").append(param.getName());

				if (i + 1 < method.getParameterCount()) {
					builder.append(", ");
				}
			}
		}
		builder.append(")");
		return builder.toString();
	}
663815
private void checkSQL(MethodDeclaration method, AnnotationProcessorEnvironment env) {

        final JdbcControl.SQL methodSQL = method.getAnnotation(JdbcControl.SQL.class);
        if (methodSQL == null) {
            return;
        }

        //
        // check for empty SQL statement member
        //
        if (methodSQL.statement() == null || methodSQL.statement().length() == 0) {
            env.getMessager().printError(method.getPosition(),
                                         getResourceString("jdbccontrol.empty.statement", method.getSimpleName()));
            return;
        }

        //
        // Make sure maxrows is not set to some negative number other than -1
        //
        int maxRows = methodSQL.maxRows();
        if (maxRows < JdbcControl.MAXROWS_ALL) {
            env.getMessager().printError(method.getPosition(),
                                         getResourceString("jdbccontrol.bad.maxrows", method.getSimpleName(),maxRows));
            return;
        }

        //
        //
        // parse the SQL
        //
        //
        SqlParser _p = new SqlParser();
        SqlStatement _statement;
        try {
            _statement = _p.parse(methodSQL.statement());
        } catch (ControlException ce) {
            env.getMessager().printError(method.getPosition(),  getResourceString("jdbccontrol.bad.parse",
                                                                                  method.getSimpleName(),
                                                                                  ce.toString()));
            return;
        }

        //
        // Check that the any statement element params (delimited by '{' and '}' can be
        // matched to method parameter names. NOTE: This check is only valid on non-compiled files,
        // once compiled to a class file method parameter names are replaced with 'arg0', 'arg1', etc.
        // and cannot be used for this check.
        //
        try {
            ParameterChecker.checkReflectionParameters(_statement, method);
        } catch (ControlException e) {
            env.getMessager().printError(method.getPosition(), e.getMessage());
            return;
        }

        //
        // check for case of generatedKeyColumns being set, when getGeneratedKeys is not set to true
        //
        final boolean getGeneratedKeys = methodSQL.getGeneratedKeys();
        final String[] generatedKeyColumnNames = methodSQL.generatedKeyColumnNames();
        final int[] generatedKeyIndexes = methodSQL.generatedKeyColumnIndexes();
        if (!getGeneratedKeys && (generatedKeyColumnNames.length != 0 || generatedKeyIndexes.length != 0)) {
            env.getMessager().printError(method.getPosition(),
                                         getResourceString("jdbccontrol.genkeys", method.getSimpleName()));
            return;
        }

        //
        // check that both generatedKeyColumnNames and generatedKeyColumnIndexes are not set
        //
        if (generatedKeyColumnNames.length > 0 && generatedKeyIndexes.length > 0) {
            env.getMessager().printError(method.getPosition(),
                                         getResourceString("jdbccontrol.genkeycolumns", method.getSimpleName()));

            return;
        }

        //
        // batch update methods must return int[]
        //
        final boolean batchUpdate = methodSQL.batchUpdate();
        final TypeMirror returnType = method.getReturnType();
        if (batchUpdate) {
            if (returnType instanceof ArrayType) {
                final TypeMirror aType = ((ArrayType) returnType).getComponentType();
                if (aType instanceof PrimitiveType == false
                        || ((PrimitiveType) aType).getKind() != PrimitiveType.Kind.INT) {
                    env.getMessager().printError(method.getPosition(),
                                                 getResourceString("jdbccontrol.batchupdate", method.getSimpleName()));
                    return;
                }
            } else if (returnType instanceof VoidType == false) {
                env.getMessager().printError(method.getPosition(),
                                             getResourceString("jdbccontrol.batchupdate", method.getSimpleName()));
                return;
            }

        }

        //
        // iterator type check match
        //
        if (returnType instanceof InterfaceType) {
            String iName = ((InterfaceType) returnType).getDeclaration().getQualifiedName();
            if ("java.util.Iterator".equals(iName)) {
                String iteratorClassName = null;
                try {
                    // this should always except
                    methodSQL.iteratorElementType();
                } catch (MirroredTypeException mte) {
                    iteratorClassName = mte.getQualifiedName();
                }

                if ("org.apache.beehive.controls.system.jdbc.JdbcControl.UndefinedIteratorType".equals(iteratorClassName)) {
                    env.getMessager().printError(method.getPosition(),
                                                 getResourceString("jdbccontrol.iterator.returntype",
                                                                   method.getSimpleName()));
                    return;
                }
            }
        }

        //
        // scrollable result set check
        //
        final JdbcControl.ScrollType scrollable = methodSQL.scrollableResultSet();
        switch (scrollable) {
            case SCROLL_INSENSITIVE:
            case SCROLL_SENSITIVE:
            case SCROLL_INSENSITIVE_UPDATABLE:
            case SCROLL_SENSITIVE_UPDATABLE:
            case FORWARD_ONLY_UPDATABLE:
                String typeName = null;
                if (returnType instanceof DeclaredType) {
                    typeName = ((DeclaredType) returnType).getDeclaration().getQualifiedName();
                }

                if (typeName == null || !"java.sql.ResultSet".equals(typeName)) {
                    env.getMessager().printError(method.getPosition(),
                                                 getResourceString("jdbccontrol.scrollresultset",
                                                                   method.getSimpleName()));
                    return;
                }
            case FORWARD_ONLY:
            default:
                break;
        }

        return;
    }
126518
static boolean isGetterMethod(final Method method) {
        return (method.getName().startsWith(GETTER_GET_METHOD_PREFIX)
                || method.getName().startsWith(GETTER_IS_METHOD_PREFIX))
                &&
                !Void.TYPE.isAssignableFrom(method.getReturnType())
                &&
                !method.isVarArgs()
                &&
                method.getParameterTypes().length == 0;
    }