Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.r2dbc.convert;
import io.r2dbc.spi.Row;
import io.r2dbc.spi.RowMetadata;
import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.ConversionService;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.mapping.MappingException;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.PreferredConstructor;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.*;
import org.springframework.data.r2dbc.mapping.OutboundRow;
import org.springframework.data.r2dbc.support.ArrayUtils;
import org.springframework.data.r2dbc.support.FastMethodInvoker;
import org.springframework.data.r2dbc.support.SqlField;
import org.springframework.data.relational.core.conversion.BasicRelationalConverter;
import org.springframework.data.relational.core.conversion.RelationalConverter;
import org.springframework.data.relational.core.dialect.ArrayColumns;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable;
import org.springframework.r2dbc.core.Parameter;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.function.BiFunction;
/**
* Converter for R2DBC.
*
* @author Mark Paluch
* @author Oliver Drotbohm
*/
public class MappingR2dbcConverter extends BasicRelationalConverter implements R2dbcConverter {
/**
* Creates a new {@link MappingR2dbcConverter} given {@link MappingContext}.
*
* @param context must not be {@literal null}.
*/
public MappingR2dbcConverter(
MappingContext extends RelationalPersistentEntity>, ? extends RelationalPersistentProperty> context) {
super(context, new R2dbcCustomConversions(R2dbcCustomConversions.STORE_CONVERSIONS, Collections.emptyList()));
}
/**
* Creates a new {@link MappingR2dbcConverter} given {@link MappingContext} and {@link CustomConversions}.
*
* @param context must not be {@literal null}.
*/
public MappingR2dbcConverter(
MappingContext extends RelationalPersistentEntity>, ? extends RelationalPersistentProperty> context,
CustomConversions conversions) {
super(context, conversions);
}
// ----------------------------------
// Entity reading
// ----------------------------------
/*
* (non-Javadoc)
* @see org.springframework.data.convert.EntityReader#read(java.lang.Class, S)
*/
@Override
public R read(Class type, Row row) {
return read(type, row, null);
}
/*
* (non-Javadoc)
* @see org.springframework.data.r2dbc.convert.R2dbcConverter#read(java.lang.Class, io.r2dbc.spi.Row, io.r2dbc.spi.RowMetadata)
*/
@Override
public R read(Class type, Row row, @Nullable RowMetadata metadata) {
TypeInformation extends R> typeInfo = ClassTypeInformation.from(type);
Class extends R> rawType = typeInfo.getType();
if (Row.class.isAssignableFrom(rawType)) {
return type.cast(row);
}
if (getConversions().hasCustomReadTarget(Row.class, rawType)
&& getConversionService().canConvert(Row.class, rawType)) {
return getConversionService().convert(row, rawType);
}
return read(getRequiredPersistentEntity(type), row, metadata);
}
private R read(RelationalPersistentEntity entity, Row row, @Nullable RowMetadata metadata) {
R result = createInstance(row, metadata, "", entity);
if (entity.requiresPropertyPopulation()) {
ConvertingPropertyAccessor propertyAccessor = new ConvertingPropertyAccessor<>(
entity.getPropertyAccessor(result), getConversionService());
for (RelationalPersistentProperty property : entity) {
if (entity.isConstructorArgument(property)) {
continue;
}
Object value = readFrom(row, metadata, property, "");
if (value != null) {
propertyAccessor.setProperty(property, value);
}
}
}
return result;
}
/**
* Read a single value or a complete Entity from the {@link Row} passed as an argument.
*
* @param row the {@link Row} to extract the value from. Must not be {@literal null}.
* @param metadata the {@link RowMetadata}. Can be {@literal null}.
* @param property the {@link RelationalPersistentProperty} for which the value is intended. Must not be
* {@literal null}.
* @param prefix to be used for all column names accessed by this method. Must not be {@literal null}.
* @return the value read from the {@link Row}. May be {@literal null}.
*/
@Nullable
private Object readFrom(Row row, @Nullable RowMetadata metadata, RelationalPersistentProperty property,
String prefix) {
String identifier = prefix + property.getColumnName().getReference();
try {
Object value = null;
if (metadata == null || metadata.getColumnNames().contains(identifier)) {
value = row.get(identifier);
}
if (value == null) {
return null;
}
if (getConversions().hasCustomReadTarget(value.getClass(), property.getType())) {
return readValue(value, property.getTypeInformation());
}
if (property.isEntity()) {
return readEntityFrom(row, metadata, property);
}
return readValue(value, property.getTypeInformation());
} catch (Exception o_O) {
throw new MappingException(String.format("Could not read property %s from column %s!", property, identifier),
o_O);
}
}
public Object readValue(@Nullable Object value, TypeInformation> type) {
if (null == value) {
return null;
}
if (getConversions().hasCustomReadTarget(value.getClass(), type.getType())) {
return getConversionService().convert(value, type.getType());
} else if (value instanceof Collection || value.getClass().isArray()) {
return readCollectionOrArray(asCollection(value), type);
} else {
return getPotentiallyConvertedSimpleRead(value, type.getType());
}
}
/**
* Reads the given value into a collection of the given {@link TypeInformation}.
*
* @param source must not be {@literal null}.
* @param targetType must not be {@literal null}.
* @return the converted {@link Collection} or array, will never be {@literal null}.
*/
@SuppressWarnings("unchecked")
private Object readCollectionOrArray(Collection> source, TypeInformation> targetType) {
Assert.notNull(targetType, "Target type must not be null!");
Class> collectionType = targetType.isSubTypeOf(Collection.class) //
? targetType.getType() //
: List.class;
TypeInformation> componentType = targetType.getComponentType() != null //
? targetType.getComponentType() //
: ClassTypeInformation.OBJECT;
Class> rawComponentType = componentType.getType();
Collection