-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Better
@CustomValueType
that is applicable at column level
- Loading branch information
1 parent
dcb8e30
commit f6c3f86
Showing
27 changed files
with
334 additions
and
133 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
75 changes: 75 additions & 0 deletions
75
databind/src/main/java/tech/ydb/yoj/databind/CustomValueTypes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package tech.ydb.yoj.databind; | ||
|
||
import com.google.common.base.Preconditions; | ||
import com.google.common.reflect.TypeToken; | ||
import lombok.NonNull; | ||
import tech.ydb.yoj.ExperimentalApi; | ||
import tech.ydb.yoj.databind.schema.Column; | ||
import tech.ydb.yoj.databind.schema.CustomConverterException; | ||
|
||
import javax.annotation.Nullable; | ||
import java.lang.reflect.InvocationTargetException; | ||
import java.lang.reflect.Type; | ||
|
||
import static java.lang.reflect.Modifier.isAbstract; | ||
import static java.lang.reflect.Modifier.isStatic; | ||
|
||
@ExperimentalApi(issue = "https://github.com/ydb-platform/yoj-project/issues/24") | ||
public final class CustomValueTypes { | ||
private CustomValueTypes() { | ||
} | ||
|
||
public static Object preconvert(@Nullable CustomValueType cvt, Object value) { | ||
if (cvt != null) { | ||
value = createCustomValueTypeConverter(cvt).toColumn(value); | ||
|
||
Preconditions.checkArgument(cvt.columnClass().isInstance(value), | ||
"Custom value type converter %s must produce a non-null value of type columnClass()=%s but got value of type %s", | ||
cvt.converter().getCanonicalName(), cvt.columnClass().getCanonicalName(), value.getClass().getCanonicalName()); | ||
} | ||
return value; | ||
} | ||
|
||
public static Object postconvert(@Nullable CustomValueType cvt, Object value) { | ||
if (cvt != null) { | ||
value = createCustomValueTypeConverter(cvt).toJava(value); | ||
} | ||
return value; | ||
} | ||
|
||
private static <V, C> ValueConverter<V, C> createCustomValueTypeConverter(CustomValueType cvt) { | ||
try { | ||
var ctor = cvt.converter().getDeclaredConstructor(); | ||
ctor.setAccessible(true); | ||
@SuppressWarnings("unchecked") var converter = (ValueConverter<V, C>) ctor.newInstance(); | ||
return converter; | ||
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | InvocationTargetException e) { | ||
throw new CustomConverterException(e, "Could not return custom value type converter " + cvt.converter()); | ||
} | ||
} | ||
|
||
|
||
@Nullable | ||
@ExperimentalApi(issue = "https://github.com/ydb-platform/yoj-project/issues/24") | ||
public static CustomValueType getCustomValueType(@NonNull Type type, @Nullable Column columnAnnotation) { | ||
var rawType = type instanceof Class<?> ? (Class<?>) type : TypeToken.of(type).getRawType(); | ||
|
||
var cvtAnnotation = columnAnnotation == null ? null : columnAnnotation.customValueType(); | ||
|
||
var columnCvt = cvtAnnotation == null || cvtAnnotation.converter().equals(ValueConverter.NoConverter.class) ? null : cvtAnnotation; | ||
var cvt = columnCvt == null ? rawType.getAnnotation(CustomValueType.class) : columnCvt; | ||
if (cvt != null) { | ||
Preconditions.checkArgument(!cvt.columnValueType().isComposite(), "@CustomValueType.columnValueType must be != COMPOSITE"); | ||
Preconditions.checkArgument(!cvt.columnValueType().isUnknown(), "@CustomValueType.columnValueType must be != UNKNOWN"); | ||
Preconditions.checkArgument( | ||
!cvt.converter().equals(ValueConverter.NoConverter.class) | ||
&& !cvt.converter().isInterface() | ||
&& !isAbstract(cvt.converter().getModifiers()) | ||
&& (cvt.converter().getDeclaringClass() == null || isStatic(cvt.converter().getModifiers())), | ||
"@CustomValueType.converter must not be an interface, abstract class, non-static inner class, or NoConverter.class, but got: %s", | ||
cvt); | ||
} | ||
|
||
return cvt; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.