/** * Creates a new {@link MongoParameters} instance from the given {@link Method} and {@link MongoQueryMethod}. * * @param method must not be {@literal null}. * @param queryMethod must not be {@literal null}. */ public MongoParameters(Method method, boolean isGeoNearMethod) { super(method); List<Class<?>> parameterTypes = Arrays.asList(method.getParameterTypes()); this.fullTextIndex = parameterTypes.indexOf(TextCriteria.class); ClassTypeInformation<?> declaringClassInfo = ClassTypeInformation.from(method.getDeclaringClass()); List<TypeInformation<?>> parameterTypeInfo = declaringClassInfo.getParameterTypes(method); this.rangeIndex = getTypeIndex(parameterTypeInfo, Range.class, Distance.class); this.maxDistanceIndex = this.rangeIndex == -1 ? getTypeIndex(parameterTypeInfo, Distance.class, null) : -1; int index = findNearIndexInParameters(method); if (index == -1 && isGeoNearMethod) { index = getNearIndex(parameterTypes); } this.nearIndex = index; }
/** * Creates a new {@link MongoParameters} instance from the given {@link Method} and {@link MongoQueryMethod}. * * @param method must not be {@literal null}. * @param queryMethod must not be {@literal null}. */ public MongoParameters(Method method, boolean isGeoNearMethod) { super(method); List<Class<?>> parameterTypes = Arrays.asList(method.getParameterTypes()); this.fullTextIndex = parameterTypes.indexOf(TextCriteria.class); ClassTypeInformation<?> declaringClassInfo = ClassTypeInformation.from(method.getDeclaringClass()); List<TypeInformation<?>> parameterTypeInfo = declaringClassInfo.getParameterTypes(method); this.rangeIndex = getTypeIndex(parameterTypeInfo, Range.class, Distance.class); this.maxDistanceIndex = this.rangeIndex == -1 ? getTypeIndex(parameterTypeInfo, Distance.class, null) : -1; int index = findNearIndexInParameters(method); if (index == -1 && isGeoNearMethod) { index = getNearIndex(parameterTypes); } this.nearIndex = index; }
/** * @param invoker * @param request * @param method * @param pageable * @return */ private Optional<Object> executeQueryMethod(final RepositoryInvoker invoker, @RequestParam MultiValueMap<String, Object> parameters, Method method, DefaultedPageable pageable, Sort sort, PersistentEntityResourceAssembler assembler) { MultiValueMap<String, Object> result = new LinkedMultiValueMap<String, Object>(parameters); MethodParameters methodParameters = new MethodParameters(method, new AnnotationAttribute(Param.class)); List<MethodParameter> parameterList = methodParameters.getParameters(); List<TypeInformation<?>> parameterTypeInformations = ClassTypeInformation.from(method.getDeclaringClass()) .getParameterTypes(method); for (Entry<String, List<Object>> entry : parameters.entrySet()) { MethodParameter parameter = methodParameters.getParameter(entry.getKey()); if (parameter == null) { continue; } int parameterIndex = parameterList.indexOf(parameter); TypeInformation<?> domainType = parameterTypeInformations.get(parameterIndex).getActualType(); ResourceMetadata metadata = mappings.getMetadataFor(domainType.getType()); if (metadata != null && metadata.isExported()) { result.put(parameter.getParameterName(), prepareUris(entry.getValue())); } } return invoker.invokeQueryMethod(method, result, pageable.getPageable(), sort); }
/** * Returns whether the given {@link MethodParameter} is a dynamic projection parameter, which means it carries a * dynamic type parameter which is identical to the type parameter of the actually returned type. * <p> * <code> * <T> Collection<T> findBy…(…, Class<T> type); * </code> * * @param parameter must not be {@literal null}. * @return */ private static boolean isDynamicProjectionParameter(MethodParameter parameter) { Method method = parameter.getMethod(); if (method == null) { throw new IllegalStateException(String.format("Method parameter %s is not backed by a method!", parameter)); } ClassTypeInformation<?> ownerType = ClassTypeInformation.from(parameter.getDeclaringClass()); TypeInformation<?> parameterTypes = ownerType.getParameterTypes(method).get(parameter.getParameterIndex()); if (!parameterTypes.getType().equals(Class.class)) { return false; } TypeInformation<?> bound = parameterTypes.getTypeArguments().get(0); TypeInformation<Object> returnType = ClassTypeInformation.fromReturnTypeOf(method); return bound.equals(QueryExecutionConverters.unwrapWrapperTypes(returnType)); }
/** * @param invoker * @param request * @param method * @param pageable * @return */ private Optional<Object> executeQueryMethod(final RepositoryInvoker invoker, @RequestParam MultiValueMap<String, Object> parameters, Method method, DefaultedPageable pageable, Sort sort, PersistentEntityResourceAssembler assembler) { MultiValueMap<String, Object> result = new LinkedMultiValueMap<String, Object>(parameters); MethodParameters methodParameters = new MethodParameters(method, new AnnotationAttribute(Param.class)); List<MethodParameter> parameterList = methodParameters.getParameters(); List<TypeInformation<?>> parameterTypeInformations = ClassTypeInformation.from(method.getDeclaringClass()) .getParameterTypes(method); for (Entry<String, List<Object>> entry : parameters.entrySet()) { MethodParameter parameter = methodParameters.getParameter(entry.getKey()); if (parameter == null) { continue; } int parameterIndex = parameterList.indexOf(parameter); TypeInformation<?> domainType = parameterTypeInformations.get(parameterIndex).getActualType(); ResourceMetadata metadata = mappings.getMetadataFor(domainType.getType()); if (metadata != null && metadata.isExported()) { result.put(parameter.getParameterName(), prepareUris(entry.getValue())); } } return invoker.invokeQueryMethod(method, result, pageable.getPageable(), sort); }