use of org.jdbi.v3.core.mapper.reflect.ColumnNameMatcher in project jdbi by jdbi.
the class BeanMapper method specialize0.
private RowMapper<T> specialize0(ResultSet rs, StatementContext ctx, List<String> columnNames, List<ColumnNameMatcher> columnNameMatchers, List<String> unmatchedColumns) throws SQLException {
final List<RowMapper<?>> mappers = new ArrayList<>();
final List<PropertyDescriptor> properties = new ArrayList<>();
for (PropertyDescriptor descriptor : info.getPropertyDescriptors()) {
Nested anno = Stream.of(descriptor.getReadMethod(), descriptor.getWriteMethod()).filter(Objects::nonNull).map(m -> m.getAnnotation(Nested.class)).filter(Objects::nonNull).findFirst().orElse(null);
if (anno == null) {
String paramName = prefix + paramName(descriptor);
findColumnIndex(paramName, columnNames, columnNameMatchers, () -> debugName(descriptor)).ifPresent(index -> {
Type type = descriptor.getReadMethod().getGenericReturnType();
ColumnMapper<?> mapper = ctx.findColumnMapperFor(type).orElse((r, n, c) -> r.getObject(n));
mappers.add(new SingleColumnMapper<>(mapper, index + 1));
properties.add(descriptor);
unmatchedColumns.remove(columnNames.get(index));
});
} else {
String nestedPrefix = prefix + anno.value();
RowMapper<?> nestedMapper = nestedMappers.computeIfAbsent(descriptor, d -> new BeanMapper<>(d.getPropertyType(), nestedPrefix)).specialize0(rs, ctx, columnNames, columnNameMatchers, unmatchedColumns);
mappers.add(nestedMapper);
properties.add(descriptor);
}
}
if (mappers.isEmpty() && columnNames.size() > 0) {
throw new IllegalArgumentException(String.format("Mapping bean type %s " + "didn't find any matching columns in result set", type));
}
return (r, c) -> {
T bean = construct();
for (int i = 0; i < mappers.size(); i++) {
RowMapper<?> mapper = mappers.get(i);
PropertyDescriptor property = properties.get(i);
Object value = mapper.map(r, ctx);
writeProperty(bean, property, value);
}
return bean;
};
}
use of org.jdbi.v3.core.mapper.reflect.ColumnNameMatcher in project jdbi by jdbi.
the class PojoMapper method specialize0.
private Optional<RowMapper<T>> specialize0(StatementContext ctx, List<String> columnNames, List<ColumnNameMatcher> columnNameMatchers, List<String> unmatchedColumns) {
final List<PropertyData<T>> propList = new ArrayList<>();
for (PojoProperty<T> property : getProperties(ctx.getConfig()).getProperties().values()) {
Nested anno = property.getAnnotation(Nested.class).orElse(null);
if (property.getAnnotation(Unmappable.class).map(Unmappable::value).orElse(false)) {
continue;
}
if (anno == null) {
String paramName = prefix + getName(property);
findColumnIndex(paramName, columnNames, columnNameMatchers, () -> debugName(property)).ifPresent(index -> {
@SuppressWarnings({ "unchecked", "rawtypes" }) ColumnMapper<?> mapper = ctx.findColumnMapperFor(property.getQualifiedType().mapType(GenericTypes::box)).orElseGet(() -> (ColumnMapper) defaultColumnMapper(property));
propList.add(new PropertyData<>(property, new SingleColumnMapper<>(mapper, index + 1)));
unmatchedColumns.remove(columnNames.get(index));
});
} else {
String nestedPrefix = prefix + anno.value();
if (anyColumnsStartWithPrefix(columnNames, nestedPrefix, columnNameMatchers)) {
nestedMappers.computeIfAbsent(property, d -> createNestedMapper(ctx, d, nestedPrefix)).specialize0(ctx, columnNames, columnNameMatchers, unmatchedColumns).ifPresent(nestedMapper -> propList.add(new PropertyData<>(property, nestedMapper)));
}
}
}
if (propList.isEmpty() && !columnNames.isEmpty()) {
return Optional.empty();
}
propList.sort(Comparator.comparing(p -> p.propagateNull ? 1 : 0));
final Optional<String> nullMarkerColumn = Optional.ofNullable(GenericTypes.getErasedType(type).getAnnotation(PropagateNull.class)).map(PropagateNull::value);
return Optional.of((r, c) -> {
if (propagateNull(r, nullMarkerColumn)) {
return null;
}
final PojoBuilder<T> pojo = getProperties(c.getConfig()).create();
for (PropertyData<T> p : propList) {
Object value = p.mapper.map(r, ctx);
if (p.propagateNull && (value == null || (p.isPrimitive && r.wasNull()))) {
return null;
}
if (value != null) {
pojo.set(p.property, value);
}
}
return pojo.build();
});
}
use of org.jdbi.v3.core.mapper.reflect.ColumnNameMatcher in project jdbi by jdbi.
the class ConstructorMapper method specialize0.
private RowMapper<T> specialize0(ResultSet rs, StatementContext ctx, List<String> columnNames, List<ColumnNameMatcher> columnNameMatchers, List<String> unmatchedColumns) throws SQLException {
final int count = constructor.getParameterCount();
final Parameter[] parameters = constructor.getParameters();
final RowMapper<?>[] mappers = new RowMapper<?>[count];
for (int i = 0; i < count; i++) {
final Parameter parameter = parameters[i];
Nested anno = parameter.getAnnotation(Nested.class);
if (anno == null) {
final String paramName = prefix + paramName(parameters, i, constructorProperties);
final int columnIndex = findColumnIndex(paramName, columnNames, columnNameMatchers, () -> debugName(parameter)).orElseThrow(() -> new IllegalArgumentException(String.format("Constructor '%s' parameter '%s' has no column in the result set. " + "Verify that the Java compiler is configured to emit parameter names, " + "that your result set has the columns expected, or annotate the " + "parameter names explicitly with @ColumnName", constructor, paramName)));
final Type type = parameter.getParameterizedType();
mappers[i] = ctx.findColumnMapperFor(type).map(mapper -> new SingleColumnMapper(mapper, columnIndex + 1)).orElseThrow(() -> new IllegalArgumentException(String.format("Could not find column mapper for type '%s' of parameter '%s' for constructor '%s'", type, paramName, constructor)));
unmatchedColumns.remove(columnNames.get(columnIndex));
} else {
String nestedPrefix = prefix + anno.value();
mappers[i] = nestedMappers.computeIfAbsent(parameter, p -> new ConstructorMapper<>(findConstructorFor(p.getType()), nestedPrefix)).specialize0(rs, ctx, columnNames, columnNameMatchers, unmatchedColumns);
}
}
return (r, c) -> {
final Object[] params = new Object[count];
for (int i = 0; i < count; i++) {
params[i] = mappers[i].map(r, c);
}
return construct(params);
};
}
use of org.jdbi.v3.core.mapper.reflect.ColumnNameMatcher in project jdbi by jdbi.
the class FieldMapper method specialize0.
private RowMapper<T> specialize0(ResultSet rs, StatementContext ctx, List<String> columnNames, List<ColumnNameMatcher> columnNameMatchers, List<String> unmatchedColumns) throws SQLException {
final List<RowMapper<?>> mappers = new ArrayList<>();
final List<Field> fields = new ArrayList<>();
for (Class<?> aType = type; aType != null; aType = aType.getSuperclass()) {
for (Field field : aType.getDeclaredFields()) {
Nested anno = field.getAnnotation(Nested.class);
if (anno == null) {
String paramName = prefix + paramName(field);
findColumnIndex(paramName, columnNames, columnNameMatchers, () -> debugName(field)).ifPresent(index -> {
Type type = field.getGenericType();
ColumnMapper<?> mapper = ctx.findColumnMapperFor(type).orElse((r, n, c) -> rs.getObject(n));
mappers.add(new SingleColumnMapper(mapper, index + 1));
fields.add(field);
unmatchedColumns.remove(columnNames.get(index));
});
} else {
String nestedPrefix = prefix + anno.value().toLowerCase();
RowMapper<?> mapper = nestedMappers.computeIfAbsent(field, f -> new FieldMapper<>(field.getType(), nestedPrefix)).specialize0(rs, ctx, columnNames, columnNameMatchers, unmatchedColumns);
mappers.add(mapper);
fields.add(field);
}
}
}
if (mappers.isEmpty() && columnNames.size() > 0) {
throw new IllegalArgumentException(String.format("Mapping fields for type %s " + "didn't find any matching columns in result set", type));
}
return (r, c) -> {
T obj = construct();
for (int i = 0; i < mappers.size(); i++) {
RowMapper<?> mapper = mappers.get(i);
Field field = fields.get(i);
Object value = mapper.map(rs, ctx);
writeField(obj, field, value);
}
return obj;
};
}
use of org.jdbi.v3.core.mapper.reflect.ColumnNameMatcher in project jdbi by jdbi.
the class ConstructorMapper method specialize0.
private Optional<RowMapper<T>> specialize0(StatementContext ctx, List<String> columnNames, List<ColumnNameMatcher> columnNameMatchers, List<String> unmatchedColumns) {
final int count = factory.getParameterCount();
final Parameter[] parameters = factory.getParameters();
boolean matchedColumns = false;
final List<String> unmatchedParameters = new ArrayList<>();
final List<ParameterData> paramData = new ArrayList<>();
for (int i = 0; i < count; i++) {
final Parameter parameter = parameters[i];
boolean nullable = isNullable(parameter);
Nested anno = parameter.getAnnotation(Nested.class);
if (anno == null) {
final String paramName = prefix + paramName(parameters, i, constructorProperties);
final OptionalInt columnIndex = findColumnIndex(paramName, columnNames, columnNameMatchers, () -> debugName(parameter));
if (columnIndex.isPresent()) {
int colIndex = columnIndex.getAsInt();
final QualifiedType<?> type = QualifiedType.of(parameter.getParameterizedType()).withAnnotations(ctx.getConfig(Qualifiers.class).findFor(parameter));
paramData.add(new ParameterData(i, parameter, ctx.findColumnMapperFor(type).map(mapper -> new SingleColumnMapper<>(mapper, colIndex + 1)).orElseThrow(() -> new IllegalArgumentException(format("Could not find column mapper for type '%s' of parameter '%s' for instance factory '%s'", type, paramName, factory)))));
matchedColumns = true;
unmatchedColumns.remove(columnNames.get(colIndex));
} else if (nullable) {
paramData.add(new ParameterData(i, parameter, (r, c) -> null));
} else {
unmatchedParameters.add(paramName);
}
} else {
final String nestedPrefix = prefix + anno.value();
final Optional<? extends RowMapper<?>> nestedMapper = nestedMappers.computeIfAbsent(parameter, p -> new ConstructorMapper<>(findFactoryFor(p.getType()), nestedPrefix)).specialize0(ctx, columnNames, columnNameMatchers, unmatchedColumns);
if (nestedMapper.isPresent()) {
paramData.add(new ParameterData(i, parameter, nestedMapper.get()));
matchedColumns = true;
} else if (nullable) {
paramData.add(new ParameterData(i, parameter, (r, c) -> null));
} else {
unmatchedParameters.add(paramName(parameters, i, constructorProperties));
}
}
}
if (!matchedColumns) {
return Optional.empty();
}
paramData.sort(Comparator.comparing(p -> p.propagateNull ? 1 : 0));
if (!unmatchedParameters.isEmpty()) {
throw new IllegalArgumentException(format(UNMATCHED_CONSTRUCTOR_PARAMETER, factory, unmatchedParameters));
}
final Optional<String> nullMarkerColumn = Optional.ofNullable(factory.getAnnotationIncludingType(PropagateNull.class)).map(PropagateNull::value);
return Optional.of((r, c) -> {
if (PojoMapper.propagateNull(r, nullMarkerColumn)) {
return null;
}
final Object[] params = new Object[count];
for (ParameterData p : paramData) {
params[p.index] = p.mapper.map(r, c);
if (p.propagateNull && (params[p.index] == null || (p.isPrimitive && r.wasNull()))) {
return null;
}
}
return factory.newInstance(params);
});
}
Aggregations