Java Code Examples for org.springframework.core.ResolvableType#resolve()

The following examples show how to use org.springframework.core.ResolvableType#resolve() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ReturnTypeParser.java    From springdoc-openapi with Apache License 2.0 6 votes vote down vote up
/**
 * Resolve variable resolvable type.
 *
 * @param typeVariable the type variable
 * @param contextType the context type
 * @return the resolvable type
 */
static ResolvableType resolveVariable(TypeVariable<?> typeVariable, ResolvableType contextType) {
	ResolvableType resolvedType;
	if (contextType.hasGenerics()) {
		resolvedType = ResolvableType.forType(typeVariable, contextType);
		if (resolvedType.resolve() != null) {
			return resolvedType;
		}
	}

	ResolvableType superType = contextType.getSuperType();
	if (superType != ResolvableType.NONE) {
		resolvedType = resolveVariable(typeVariable, superType);
		if (resolvedType.resolve() != null) {
			return resolvedType;
		}
	}
	for (ResolvableType ifc : contextType.getInterfaces()) {
		resolvedType = resolveVariable(typeVariable, ifc);
		if (resolvedType.resolve() != null) {
			return resolvedType;
		}
	}
	return ResolvableType.NONE;
}
 
Example 2
Source File: GenericTypeAwareAutowireCandidateResolver.java    From java-technology-stack with MIT License 6 votes vote down vote up
@Nullable
protected ResolvableType getReturnTypeForFactoryMethod(RootBeanDefinition rbd, DependencyDescriptor descriptor) {
	// Should typically be set for any kind of factory method, since the BeanFactory
	// pre-resolves them before reaching out to the AutowireCandidateResolver...
	ResolvableType returnType = rbd.factoryMethodReturnType;
	if (returnType == null) {
		Method factoryMethod = rbd.getResolvedFactoryMethod();
		if (factoryMethod != null) {
			returnType = ResolvableType.forMethodReturnType(factoryMethod);
		}
	}
	if (returnType != null) {
		Class<?> resolvedClass = returnType.resolve();
		if (resolvedClass != null && descriptor.getDependencyType().isAssignableFrom(resolvedClass)) {
			// Only use factory method metadata if the return type is actually expressive enough
			// for our dependency. Otherwise, the returned instance type may have matched instead
			// in case of a singleton instance having been registered with the container already.
			return returnType;
		}
	}
	return null;
}
 
Example 3
Source File: AbstractJackson2HttpMessageConverter.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
private ResolvableType resolveVariable(TypeVariable<?> typeVariable, ResolvableType contextType) {
	ResolvableType resolvedType;
	if (contextType.hasGenerics()) {
		resolvedType = ResolvableType.forType(typeVariable, contextType);
		if (resolvedType.resolve() != null) {
			return resolvedType;
		}
	}

	ResolvableType superType = contextType.getSuperType();
	if (superType != ResolvableType.NONE) {
		resolvedType = resolveVariable(typeVariable, superType);
		if (resolvedType.resolve() != null) {
			return resolvedType;
		}
	}
	for (ResolvableType ifc : contextType.getInterfaces()) {
		resolvedType = resolveVariable(typeVariable, ifc);
		if (resolvedType.resolve() != null) {
			return resolvedType;
		}
	}
	return ResolvableType.NONE;
}
 
Example 4
Source File: StaticListableBeanFactory.java    From java-technology-stack with MIT License 5 votes vote down vote up
@Override
public String[] getBeanNamesForType(@Nullable ResolvableType type) {
	boolean isFactoryType = false;
	if (type != null) {
		Class<?> resolved = type.resolve();
		if (resolved != null && FactoryBean.class.isAssignableFrom(resolved)) {
			isFactoryType = true;
		}
	}
	List<String> matches = new ArrayList<>();
	for (Map.Entry<String, Object> entry : this.beans.entrySet()) {
		String name = entry.getKey();
		Object beanInstance = entry.getValue();
		if (beanInstance instanceof FactoryBean && !isFactoryType) {
			Class<?> objectType = ((FactoryBean<?>) beanInstance).getObjectType();
			if (objectType != null && (type == null || type.isAssignableFrom(objectType))) {
				matches.add(name);
			}
		}
		else {
			if (type == null || type.isInstance(beanInstance)) {
				matches.add(name);
			}
		}
	}
	return StringUtils.toStringArray(matches);
}
 
Example 5
Source File: GenericApplicationListenerAdapter.java    From java-technology-stack with MIT License 5 votes vote down vote up
@Override
@SuppressWarnings("unchecked")
public boolean supportsEventType(ResolvableType eventType) {
	if (this.delegate instanceof SmartApplicationListener) {
		Class<? extends ApplicationEvent> eventClass = (Class<? extends ApplicationEvent>) eventType.resolve();
		return (eventClass != null && ((SmartApplicationListener) this.delegate).supportsEventType(eventClass));
	}
	else {
		return (this.declaredEventType == null || this.declaredEventType.isAssignableFrom(eventType));
	}
}
 
Example 6
Source File: MicronautBeanFactory.java    From micronaut-spring with Apache License 2.0 5 votes vote down vote up
@Override
public @Nonnull
String[] getBeanNamesForType(@Nonnull ResolvableType type) {
    final Class<?> resolved = type.resolve();
    if (resolved != null) {
        return getBeanNamesForType(resolved);
    }
    return StringUtils.EMPTY_STRING_ARRAY;
}
 
Example 7
Source File: VaadinControlInitializer.java    From jdal with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 */
public void initialize(Object control, String property, InitializationConfig config) {
	if (this.dao == null) {
		log.warn("Nothing to do without persistent service");
		return;
	}
	Class<?> clazz = config.getType();
	PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(clazz, property);

	if (pd == null) {
		log.error("Not found property descriptor for property [" + property + "]") ;
		return;
	}
		
	ResolvableType propertyType = ResolvableType.forMethodReturnType(pd.getReadMethod());
	Annotation[] annotations = getAnnotations(property, clazz);
	for (Annotation a : annotations) {
		List<Object> items = null;
		
		if (ManyToOne.class.equals(a.annotationType()) || ManyToMany.class.equals(a.annotationType()) ) {
			items = getEntityList(propertyType, config.getSortPropertyName());
			
		}
		else if (Reference.class.equals(a.annotationType())) {
			Reference r = (Reference) a;
			Class<?> type = void.class.equals(r.target()) ? propertyType.resolve() : r.target();
			List<Object> entities = getEntityList(type, config.getSortPropertyName());
			items = StringUtils.isEmpty(r.property()) ?  entities : 
				getValueList(entities, r.property());	
		}
		
		if (items != null) {
			if (control instanceof AbstractSelect) {
				for (Object item : items) 
					((AbstractSelect) control).addItem(item);
			}
			break;
		}
	}
}
 
Example 8
Source File: SolaceJmsAutoConfigurationTestBase.java    From solace-jms-spring-boot with Apache License 2.0 5 votes vote down vote up
static Set<Object[]> getTestParameters(Set<ResolvableType> testClasses) {
    Set<Object[]> parameters = new HashSet<>();
    for (ResolvableType resolvableRawClass : testClasses) {
        Class<?> rawClass = resolvableRawClass.resolve();
        StringBuilder testName = new StringBuilder(rawClass.getSimpleName());
        for (ResolvableType resolvableGeneric : resolvableRawClass.getGenerics()) {
            Class<?> genericClass = resolvableGeneric.getRawClass();
            if (genericClass != null) testName = testName.append('—').append(genericClass.getSimpleName());
        }

        parameters.add(new Object[]{testName.toString(), rawClass});
    }
    return parameters;
}
 
Example 9
Source File: StaticListableBeanFactory.java    From spring-analysis-note with MIT License 5 votes vote down vote up
@Override
public String[] getBeanNamesForType(@Nullable ResolvableType type) {
	boolean isFactoryType = false;
	if (type != null) {
		Class<?> resolved = type.resolve();
		if (resolved != null && FactoryBean.class.isAssignableFrom(resolved)) {
			isFactoryType = true;
		}
	}
	List<String> matches = new ArrayList<>();
	for (Map.Entry<String, Object> entry : this.beans.entrySet()) {
		String name = entry.getKey();
		Object beanInstance = entry.getValue();
		if (beanInstance instanceof FactoryBean && !isFactoryType) {
			Class<?> objectType = ((FactoryBean<?>) beanInstance).getObjectType();
			if (objectType != null && (type == null || type.isAssignableFrom(objectType))) {
				matches.add(name);
			}
		}
		else {
			if (type == null || type.isInstance(beanInstance)) {
				matches.add(name);
			}
		}
	}
	return StringUtils.toStringArray(matches);
}
 
Example 10
Source File: CarHandler.java    From tutorials with MIT License 5 votes vote down vote up
public List<Vehicle> getVehicles() throws NoSuchFieldException {
    ResolvableType vehiclesType = ResolvableType.forField(getClass().getDeclaredField("vehicles"));
    System.out.println(vehiclesType);
    ResolvableType type = vehiclesType.getGeneric();
    System.out.println(type);
    Class<?> aClass = type.resolve();
    System.out.println(aClass);
    return this.vehicles;
}
 
Example 11
Source File: RootBeanDefinition.java    From java-technology-stack with MIT License 5 votes vote down vote up
/**
 * Return the target type of this bean definition, if known
 * (either specified in advance or resolved on first instantiation).
 * @since 3.2.2
 */
@Nullable
public Class<?> getTargetType() {
	if (this.resolvedTargetType != null) {
		return this.resolvedTargetType;
	}
	ResolvableType targetType = this.targetType;
	return (targetType != null ? targetType.resolve() : null);
}
 
Example 12
Source File: ServerSentEventHttpMessageReader.java    From java-technology-stack with MIT License 5 votes vote down vote up
@Override
public Mono<Object> readMono(
		ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) {

	// We're ahead of String + "*/*"
	// Let's see if we can aggregate the output (lest we time out)...

	if (elementType.resolve() == String.class) {
		Flux<DataBuffer> body = message.getBody();
		return stringDecoder.decodeToMono(body, elementType, null, null).cast(Object.class);
	}

	return Mono.error(new UnsupportedOperationException(
			"ServerSentEventHttpMessageReader only supports reading stream of events as a Flux"));
}
 
Example 13
Source File: SpringMvcContract.java    From spring-cloud-openfeign with Apache License 2.0 5 votes vote down vote up
private static TypeDescriptor getElementTypeDescriptor(
		TypeDescriptor typeDescriptor) {
	TypeDescriptor elementTypeDescriptor = typeDescriptor.getElementTypeDescriptor();
	// that means it's not a collection but it is iterable, gh-135
	if (elementTypeDescriptor == null
			&& Iterable.class.isAssignableFrom(typeDescriptor.getType())) {
		ResolvableType type = typeDescriptor.getResolvableType().as(Iterable.class)
				.getGeneric(0);
		if (type.resolve() == null) {
			return null;
		}
		return new TypeDescriptor(type, null, typeDescriptor.getAnnotations());
	}
	return elementTypeDescriptor;
}
 
Example 14
Source File: AbstractEncoderMethodReturnValueHandler.java    From spring-analysis-note with MIT License 5 votes vote down vote up
@SuppressWarnings("unchecked")
private Flux<DataBuffer> encodeContent(
		@Nullable Object content, MethodParameter returnType, DataBufferFactory bufferFactory,
		@Nullable MimeType mimeType, Map<String, Object> hints) {

	ResolvableType returnValueType = ResolvableType.forMethodParameter(returnType);
	ReactiveAdapter adapter = getAdapterRegistry().getAdapter(returnValueType.resolve(), content);

	Publisher<?> publisher;
	ResolvableType elementType;
	if (adapter != null) {
		publisher = adapter.toPublisher(content);
		boolean isUnwrapped = KotlinDetector.isKotlinReflectPresent() &&
				KotlinDetector.isKotlinType(returnType.getContainingClass()) &&
				KotlinDelegate.isSuspend(returnType.getMethod()) &&
				!COROUTINES_FLOW_CLASS_NAME.equals(returnValueType.toClass().getName());
		ResolvableType genericType = isUnwrapped ? returnValueType : returnValueType.getGeneric();
		elementType = getElementType(adapter, genericType);
	}
	else {
		publisher = Mono.justOrEmpty(content);
		elementType = (returnValueType.toClass() == Object.class && content != null ?
				ResolvableType.forInstance(content) : returnValueType);
	}

	if (elementType.resolve() == void.class || elementType.resolve() == Void.class) {
		return Flux.from(publisher).cast(DataBuffer.class);
	}

	Encoder<?> encoder = getEncoder(elementType, mimeType);
	return Flux.from((Publisher) publisher).map(value ->
			encodeValue(value, elementType, encoder, bufferFactory, mimeType, hints));
}
 
Example 15
Source File: PayloadMethodArgumentResolver.java    From spring-analysis-note with MIT License 4 votes vote down vote up
private Mono<Object> decodeContent(MethodParameter parameter, Message<?> message,
		boolean isContentRequired, Flux<DataBuffer> content, MimeType mimeType) {

	ResolvableType targetType = ResolvableType.forMethodParameter(parameter);
	Class<?> resolvedType = targetType.resolve();
	ReactiveAdapter adapter = (resolvedType != null ? getAdapterRegistry().getAdapter(resolvedType) : null);
	ResolvableType elementType = (adapter != null ? targetType.getGeneric() : targetType);
	isContentRequired = isContentRequired || (adapter != null && !adapter.supportsEmpty());
	Consumer<Object> validator = getValidator(message, parameter);

	Map<String, Object> hints = Collections.emptyMap();

	for (Decoder<?> decoder : this.decoders) {
		if (decoder.canDecode(elementType, mimeType)) {
			if (adapter != null && adapter.isMultiValue()) {
				Flux<?> flux = content
						.map(buffer -> decoder.decode(buffer, elementType, mimeType, hints))
						.onErrorResume(ex -> Flux.error(handleReadError(parameter, message, ex)));
				if (isContentRequired) {
					flux = flux.switchIfEmpty(Flux.error(() -> handleMissingBody(parameter, message)));
				}
				if (validator != null) {
					flux = flux.doOnNext(validator);
				}
				return Mono.just(adapter.fromPublisher(flux));
			}
			else {
				// Single-value (with or without reactive type wrapper)
				Mono<?> mono = content.next()
						.map(buffer -> decoder.decode(buffer, elementType, mimeType, hints))
						.onErrorResume(ex -> Mono.error(handleReadError(parameter, message, ex)));
				if (isContentRequired) {
					mono = mono.switchIfEmpty(Mono.error(() -> handleMissingBody(parameter, message)));
				}
				if (validator != null) {
					mono = mono.doOnNext(validator);
				}
				return (adapter != null ? Mono.just(adapter.fromPublisher(mono)) : Mono.from(mono));
			}
		}
	}

	return Mono.error(new MethodArgumentResolutionException(
			message, parameter, "Cannot decode to [" + targetType + "]" + message));
}
 
Example 16
Source File: StringDecoder.java    From spring-analysis-note with MIT License 4 votes vote down vote up
@Override
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
	return (elementType.resolve() == String.class && super.canDecode(elementType, mimeType));
}
 
Example 17
Source File: GenericsUtils.java    From spring-cloud-stream with Apache License 2.0 4 votes vote down vote up
/**
 * For a specific class that implements or extends a parameterized type, return the
 * parameter of that interface at a given position. For example, for this class:
 *
 * <pre> {@code
 * class MessageChannelBinder implements Binder<MessageChannel, ?, ?>
 * } </pre>
 *
 * <pre> {@code
 * getParameterType(MessageChannelBinder.class, Binder.class, 0);
 * } </pre>
 *
 * will return {@code Binder}
 * @param evaluatedClass the evaluated class
 * @param interfaceClass the parametrized interface
 * @param position the position
 * @return the parameter type if any
 * @throws IllegalStateException if the evaluated class does not implement the
 * interface or
 */
public static Class<?> getParameterType(Class<?> evaluatedClass,
		Class<?> interfaceClass, int position) {
	Class<?> bindableType = null;
	Assert.isTrue(interfaceClass.isInterface(),
			"'interfaceClass' must be an interface");
	if (!interfaceClass.isAssignableFrom(evaluatedClass)) {
		throw new IllegalStateException(
				evaluatedClass + " does not implement " + interfaceClass);
	}
	ResolvableType currentType = ResolvableType.forType(evaluatedClass);
	while (!Object.class.equals(currentType.getRawClass()) && bindableType == null) {
		ResolvableType[] interfaces = currentType.getInterfaces();
		ResolvableType resolvableType = null;
		for (ResolvableType interfaceType : interfaces) {
			if (interfaceClass.equals(interfaceType.getRawClass())) {
				resolvableType = interfaceType;
				break;
			}
		}
		if (resolvableType == null) {
			currentType = currentType.getSuperType();
		}
		else {
			ResolvableType[] generics = resolvableType.getGenerics();
			ResolvableType generic = generics[position];
			Class<?> resolvedParameter = generic.resolve();
			if (resolvedParameter != null) {
				bindableType = resolvedParameter;
			}
			else {
				bindableType = Object.class;
			}
		}
	}
	if (bindableType == null) {
		throw new IllegalStateException(
				"Cannot find parameter of " + evaluatedClass.getName() + " for "
						+ interfaceClass + " at position " + position);
	}
	return bindableType;
}
 
Example 18
Source File: AbstractMessageReaderArgumentResolver.java    From spring-analysis-note with MIT License 4 votes vote down vote up
/**
 * Read the body from a method argument with {@link HttpMessageReader}.
 * @param bodyParam represents the element type for the body
 * @param actualParam the actual method argument type; possibly different
 * from {@code bodyParam}, e.g. for an {@code HttpEntity} argument
 * @param isBodyRequired true if the body is required
 * @param bindingContext the binding context to use
 * @param exchange the current exchange
 * @return a Mono with the value to use for the method argument
 * @since 5.0.2
 */
protected Mono<Object> readBody(MethodParameter bodyParam, @Nullable MethodParameter actualParam,
		boolean isBodyRequired, BindingContext bindingContext, ServerWebExchange exchange) {

	ResolvableType bodyType = ResolvableType.forMethodParameter(bodyParam);
	ResolvableType actualType = (actualParam != null ? ResolvableType.forMethodParameter(actualParam) : bodyType);
	Class<?> resolvedType = bodyType.resolve();
	ReactiveAdapter adapter = (resolvedType != null ? getAdapterRegistry().getAdapter(resolvedType) : null);
	ResolvableType elementType = (adapter != null ? bodyType.getGeneric() : bodyType);
	isBodyRequired = isBodyRequired || (adapter != null && !adapter.supportsEmpty());

	ServerHttpRequest request = exchange.getRequest();
	ServerHttpResponse response = exchange.getResponse();

	MediaType contentType = request.getHeaders().getContentType();
	MediaType mediaType = (contentType != null ? contentType : MediaType.APPLICATION_OCTET_STREAM);
	Object[] hints = extractValidationHints(bodyParam);

	if (mediaType.isCompatibleWith(MediaType.APPLICATION_FORM_URLENCODED)) {
		return Mono.error(new IllegalStateException(
				"In a WebFlux application, form data is accessed via ServerWebExchange.getFormData()."));
	}

	if (logger.isDebugEnabled()) {
		logger.debug(exchange.getLogPrefix() + (contentType != null ?
				"Content-Type:" + contentType :
				"No Content-Type, using " + MediaType.APPLICATION_OCTET_STREAM));
	}

	for (HttpMessageReader<?> reader : getMessageReaders()) {
		if (reader.canRead(elementType, mediaType)) {
			Map<String, Object> readHints = Hints.from(Hints.LOG_PREFIX_HINT, exchange.getLogPrefix());
			if (adapter != null && adapter.isMultiValue()) {
				if (logger.isDebugEnabled()) {
					logger.debug(exchange.getLogPrefix() + "0..N [" + elementType + "]");
				}
				Flux<?> flux = reader.read(actualType, elementType, request, response, readHints);
				flux = flux.onErrorResume(ex -> Flux.error(handleReadError(bodyParam, ex)));
				if (isBodyRequired) {
					flux = flux.switchIfEmpty(Flux.error(() -> handleMissingBody(bodyParam)));
				}
				if (hints != null) {
					flux = flux.doOnNext(target ->
							validate(target, hints, bodyParam, bindingContext, exchange));
				}
				return Mono.just(adapter.fromPublisher(flux));
			}
			else {
				// Single-value (with or without reactive type wrapper)
				if (logger.isDebugEnabled()) {
					logger.debug(exchange.getLogPrefix() + "0..1 [" + elementType + "]");
				}
				Mono<?> mono = reader.readMono(actualType, elementType, request, response, readHints);
				mono = mono.onErrorResume(ex -> Mono.error(handleReadError(bodyParam, ex)));
				if (isBodyRequired) {
					mono = mono.switchIfEmpty(Mono.error(() -> handleMissingBody(bodyParam)));
				}
				if (hints != null) {
					mono = mono.doOnNext(target ->
							validate(target, hints, bodyParam, bindingContext, exchange));
				}
				return (adapter != null ? Mono.just(adapter.fromPublisher(mono)) : Mono.from(mono));
			}
		}
	}

	// No compatible reader but body may be empty..

	HttpMethod method = request.getMethod();
	if (contentType == null && method != null && SUPPORTED_METHODS.contains(method)) {
		Flux<DataBuffer> body = request.getBody().doOnNext(buffer -> {
			DataBufferUtils.release(buffer);
			// Body not empty, back to 415..
			throw new UnsupportedMediaTypeStatusException(mediaType, this.supportedMediaTypes, elementType);
		});
		if (isBodyRequired) {
			body = body.switchIfEmpty(Mono.error(() -> handleMissingBody(bodyParam)));
		}
		return (adapter != null ? Mono.just(adapter.fromPublisher(body)) : Mono.from(body));
	}

	return Mono.error(new UnsupportedMediaTypeStatusException(mediaType, this.supportedMediaTypes, elementType));
}
 
Example 19
Source File: AbstractMessageReaderArgumentResolver.java    From java-technology-stack with MIT License 4 votes vote down vote up
/**
 * Read the body from a method argument with {@link HttpMessageReader}.
 * @param bodyParam represents the element type for the body
 * @param actualParam the actual method argument type; possibly different
 * from {@code bodyParam}, e.g. for an {@code HttpEntity} argument
 * @param isBodyRequired true if the body is required
 * @param bindingContext the binding context to use
 * @param exchange the current exchange
 * @return a Mono with the value to use for the method argument
 * @since 5.0.2
 */
protected Mono<Object> readBody(MethodParameter bodyParam, @Nullable MethodParameter actualParam,
		boolean isBodyRequired, BindingContext bindingContext, ServerWebExchange exchange) {

	ResolvableType bodyType = ResolvableType.forMethodParameter(bodyParam);
	ResolvableType actualType = (actualParam != null ? ResolvableType.forMethodParameter(actualParam) : bodyType);
	Class<?> resolvedType = bodyType.resolve();
	ReactiveAdapter adapter = (resolvedType != null ? getAdapterRegistry().getAdapter(resolvedType) : null);
	ResolvableType elementType = (adapter != null ? bodyType.getGeneric() : bodyType);
	isBodyRequired = isBodyRequired || (adapter != null && !adapter.supportsEmpty());

	ServerHttpRequest request = exchange.getRequest();
	ServerHttpResponse response = exchange.getResponse();

	MediaType contentType = request.getHeaders().getContentType();
	MediaType mediaType = (contentType != null ? contentType : MediaType.APPLICATION_OCTET_STREAM);
	Object[] hints = extractValidationHints(bodyParam);

	if (logger.isDebugEnabled()) {
		logger.debug(exchange.getLogPrefix() + (contentType != null ?
				"Content-Type:" + contentType :
				"No Content-Type, using " + MediaType.APPLICATION_OCTET_STREAM));
	}

	for (HttpMessageReader<?> reader : getMessageReaders()) {
		if (reader.canRead(elementType, mediaType)) {
			Map<String, Object> readHints = Hints.from(Hints.LOG_PREFIX_HINT, exchange.getLogPrefix());
			if (adapter != null && adapter.isMultiValue()) {
				if (logger.isDebugEnabled()) {
					logger.debug(exchange.getLogPrefix() + "0..N [" + elementType + "]");
				}
				Flux<?> flux = reader.read(actualType, elementType, request, response, readHints);
				flux = flux.onErrorResume(ex -> Flux.error(handleReadError(bodyParam, ex)));
				if (isBodyRequired) {
					flux = flux.switchIfEmpty(Flux.error(() -> handleMissingBody(bodyParam)));
				}
				if (hints != null) {
					flux = flux.doOnNext(target ->
							validate(target, hints, bodyParam, bindingContext, exchange));
				}
				return Mono.just(adapter.fromPublisher(flux));
			}
			else {
				// Single-value (with or without reactive type wrapper)
				if (logger.isDebugEnabled()) {
					logger.debug(exchange.getLogPrefix() + "0..1 [" + elementType + "]");
				}
				Mono<?> mono = reader.readMono(actualType, elementType, request, response, readHints);
				mono = mono.onErrorResume(ex -> Mono.error(handleReadError(bodyParam, ex)));
				if (isBodyRequired) {
					mono = mono.switchIfEmpty(Mono.error(() -> handleMissingBody(bodyParam)));
				}
				if (hints != null) {
					mono = mono.doOnNext(target ->
							validate(target, hints, bodyParam, bindingContext, exchange));
				}
				return (adapter != null ? Mono.just(adapter.fromPublisher(mono)) : Mono.from(mono));
			}
		}
	}

	// No compatible reader but body may be empty..

	HttpMethod method = request.getMethod();
	if (contentType == null && method != null && SUPPORTED_METHODS.contains(method)) {
		Flux<DataBuffer> body = request.getBody().doOnNext(o -> {
			// Body not empty, back to 415..
			throw new UnsupportedMediaTypeStatusException(mediaType, this.supportedMediaTypes, elementType);
		});
		if (isBodyRequired) {
			body = body.switchIfEmpty(Mono.error(() -> handleMissingBody(bodyParam)));
		}
		return (adapter != null ? Mono.just(adapter.fromPublisher(body)) : Mono.from(body));
	}

	return Mono.error(new UnsupportedMediaTypeStatusException(mediaType, this.supportedMediaTypes, elementType));
}
 
Example 20
Source File: MultipartHttpMessageWriter.java    From java-technology-stack with MIT License 4 votes vote down vote up
@SuppressWarnings("unchecked")
private <T> Flux<DataBuffer> encodePart(byte[] boundary, String name, T value) {
	MultipartHttpOutputMessage outputMessage = new MultipartHttpOutputMessage(this.bufferFactory, getCharset());
	HttpHeaders outputHeaders = outputMessage.getHeaders();

	T body;
	ResolvableType resolvableType = null;
	if (value instanceof HttpEntity) {
		HttpEntity<T> httpEntity = (HttpEntity<T>) value;
		outputHeaders.putAll(httpEntity.getHeaders());
		body = httpEntity.getBody();
		Assert.state(body != null, "MultipartHttpMessageWriter only supports HttpEntity with body");

		if (httpEntity instanceof MultipartBodyBuilder.PublisherEntity<?, ?>) {
			MultipartBodyBuilder.PublisherEntity<?, ?> publisherEntity =
					(MultipartBodyBuilder.PublisherEntity<?, ?>) httpEntity;
			resolvableType = publisherEntity.getResolvableType();
		}
	}
	else {
		body = value;
	}
	if (resolvableType == null) {
		resolvableType = ResolvableType.forClass(body.getClass());
	}

	if (!outputHeaders.containsKey(HttpHeaders.CONTENT_DISPOSITION)) {
		if (body instanceof Resource) {
			outputHeaders.setContentDispositionFormData(name, ((Resource) body).getFilename());
		}
		else if (resolvableType.resolve() == Resource.class) {
			body = (T) Mono.from((Publisher<?>) body).doOnNext(o -> outputHeaders
					.setContentDispositionFormData(name, ((Resource) o).getFilename()));
		}
		else {
			outputHeaders.setContentDispositionFormData(name, null);
		}
	}

	MediaType contentType = outputHeaders.getContentType();

	final ResolvableType finalBodyType = resolvableType;
	Optional<HttpMessageWriter<?>> writer = this.partWriters.stream()
			.filter(partWriter -> partWriter.canWrite(finalBodyType, contentType))
			.findFirst();

	if (!writer.isPresent()) {
		return Flux.error(new CodecException("No suitable writer found for part: " + name));
	}

	Publisher<T> bodyPublisher =
			body instanceof Publisher ? (Publisher<T>) body : Mono.just(body);

	// The writer will call MultipartHttpOutputMessage#write which doesn't actually write
	// but only stores the body Flux and returns Mono.empty().

	Mono<Void> partContentReady = ((HttpMessageWriter<T>) writer.get())
			.write(bodyPublisher, resolvableType, contentType, outputMessage, DEFAULT_HINTS);

	// After partContentReady, we can access the part content from MultipartHttpOutputMessage
	// and use it for writing to the actual request body

	Flux<DataBuffer> partContent = partContentReady.thenMany(Flux.defer(outputMessage::getBody));

	return Flux.concat(Mono.just(generateBoundaryLine(boundary)), partContent, Mono.just(generateNewLine()));
}