-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement ModelToSchemeCollectionConverter
Signed-off-by: sepgh <13250403+sepgh@users.noreply.github.com>
- Loading branch information
Showing
8 changed files
with
222 additions
and
8 deletions.
There are no files selected for viewing
112 changes: 112 additions & 0 deletions
112
src/main/java/com/github/sepgh/testudo/scheme/ModelToSchemeCollectionConverter.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,112 @@ | ||
package com.github.sepgh.testudo.scheme; | ||
|
||
import com.github.sepgh.testudo.scheme.annotation.AutoIncrement; | ||
import com.github.sepgh.testudo.scheme.annotation.Collection; | ||
import com.github.sepgh.testudo.scheme.annotation.Field; | ||
import com.github.sepgh.testudo.scheme.annotation.Index; | ||
import com.github.sepgh.testudo.serialization.SerializerRegistry; | ||
|
||
import java.lang.annotation.Annotation; | ||
import java.lang.reflect.Modifier; | ||
import java.util.*; | ||
import java.util.stream.Stream; | ||
|
||
public class ModelToSchemeCollectionConverter { | ||
|
||
private final Class<?> modelClass; | ||
|
||
public ModelToSchemeCollectionConverter(Class<?> modelClass) { | ||
this.modelClass = modelClass; | ||
} | ||
|
||
public Scheme.Collection toCollection() { | ||
Scheme.Collection collection = this.extractCollection(); | ||
List<Scheme.Field> fields = this.extractFields(); | ||
fields.sort(Comparator.comparingInt(Scheme.Field::getId)); | ||
collection.setFields(fields); | ||
return collection; | ||
} | ||
|
||
private List<Scheme.Field> extractFields() { | ||
Stream<java.lang.reflect.Field> stream = Arrays.stream(this.modelClass.getDeclaredFields()) | ||
.filter(field -> Modifier.isPrivate(field.getModifiers())) | ||
.filter(f -> f.isAnnotationPresent(Field.class)); | ||
|
||
List<Scheme.Field> fields = new ArrayList<>(); | ||
stream.forEach(field -> { | ||
Optional<Scheme.Field> optional = this.getSchemeField(field); | ||
optional.ifPresent(fields::add); | ||
}); | ||
|
||
return fields; | ||
} | ||
|
||
private Scheme.Collection extractCollection() { | ||
Optional<Annotation> collectionOptional = Arrays.stream(modelClass.getAnnotations()) | ||
.filter(annotation -> annotation.annotationType().equals(Collection.class)) | ||
.findFirst(); | ||
|
||
if (collectionOptional.isEmpty()) { | ||
// Todo: err | ||
} | ||
|
||
Collection collection = (Collection) collectionOptional.get(); | ||
return Scheme.Collection.builder() | ||
.id(collection.id()) | ||
.name(collection.name()) | ||
.build(); | ||
} | ||
|
||
private Optional<Scheme.Field> getSchemeField(final java.lang.reflect.Field field) { | ||
Field fieldAnnotation = field.getAnnotation(Field.class); | ||
Scheme.Field schemeField = Scheme.Field.builder() | ||
.id(fieldAnnotation.id()) | ||
.type(getFieldType(field, fieldAnnotation)) | ||
.name(fieldAnnotation.name()) | ||
.nullable(fieldAnnotation.nullable()) | ||
.defaultValue(fieldAnnotation.defaultValue()) | ||
.meta(Scheme.Meta.builder() | ||
.charset(fieldAnnotation.charset()) | ||
.comment(fieldAnnotation.comment()) | ||
.maxLength(fieldAnnotation.maxLength()) | ||
.build()) | ||
.build(); | ||
|
||
List<Annotation> objFieldAnnotations = Arrays.asList(field.getAnnotations()); | ||
|
||
Optional<Annotation> indexAnnotationOptional = objFieldAnnotations.stream().filter(annotation -> annotation.annotationType().equals(Index.class)).findFirst(); | ||
if (indexAnnotationOptional.isEmpty()) | ||
return Optional.of(schemeField); | ||
|
||
Index index = (Index) indexAnnotationOptional.get(); | ||
|
||
schemeField.setIndex(index.enable()); | ||
schemeField.setIndexUnique(index.unique()); | ||
schemeField.setPrimary(index.primary()); | ||
schemeField.setLowCardinality(index.lowCardinality()); | ||
schemeField.setAutoIncrement(objFieldAnnotations.stream().anyMatch(annotation -> annotation.annotationType().equals(AutoIncrement.class))); | ||
|
||
return Optional.of(schemeField); | ||
} | ||
|
||
private String getFieldType(final java.lang.reflect.Field field, Field fieldAnnotation) { | ||
if (fieldAnnotation.type().isEmpty()) { | ||
Optional<String> optional = SerializerRegistry.getInstance().getTypeOfClass(field.getType()); | ||
if (optional.isPresent()) { | ||
return optional.get(); | ||
} | ||
throw new RuntimeException("Can't find a default field type for class " + field.getType().getTypeName()); // todo | ||
} | ||
|
||
final String annotatedType = fieldAnnotation.type(); | ||
Class<?> type = SerializerRegistry.getInstance().getSerializer(annotatedType).getType(); | ||
|
||
if (type.equals(field.getType())) { | ||
return annotatedType; | ||
} else { | ||
throw new RuntimeException("Annotated type '%s' is not compatible with field type '%s'".formatted(annotatedType, field.getType().getTypeName())); // Todo | ||
} | ||
} | ||
|
||
|
||
} |
7 changes: 7 additions & 0 deletions
7
src/main/java/com/github/sepgh/testudo/scheme/annotation/AutoIncrement.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 |
---|---|---|
@@ -1,4 +1,11 @@ | ||
package com.github.sepgh.testudo.scheme.annotation; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.FIELD) | ||
public @interface AutoIncrement { | ||
} |
7 changes: 7 additions & 0 deletions
7
src/main/java/com/github/sepgh/testudo/scheme/annotation/Collection.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
9 changes: 8 additions & 1 deletion
9
src/main/java/com/github/sepgh/testudo/scheme/annotation/Field.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 |
---|---|---|
@@ -1,14 +1,21 @@ | ||
package com.github.sepgh.testudo.scheme.annotation; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.FIELD) | ||
public @interface Field { | ||
int id(); | ||
String name() default ""; | ||
String type() default ""; | ||
boolean nullable() default false; | ||
String defaultValue() default ""; | ||
|
||
// Meta | ||
String comment() default ""; | ||
String defaultValue() default ""; | ||
int maxLength() default -1; | ||
String charset() default "UTF-8"; | ||
} |
7 changes: 7 additions & 0 deletions
7
src/main/java/com/github/sepgh/testudo/scheme/annotation/Index.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
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
68 changes: 68 additions & 0 deletions
68
src/test/java/com/github/sepgh/test/scheme/ModelToSchemeCollectionConverterTestCase.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,68 @@ | ||
package com.github.sepgh.test.scheme; | ||
|
||
import com.github.sepgh.testudo.scheme.ModelToSchemeCollectionConverter; | ||
import com.github.sepgh.testudo.scheme.Scheme; | ||
import com.github.sepgh.testudo.scheme.annotation.AutoIncrement; | ||
import com.github.sepgh.testudo.scheme.annotation.Collection; | ||
import com.github.sepgh.testudo.scheme.annotation.Field; | ||
import com.github.sepgh.testudo.scheme.annotation.Index; | ||
import lombok.Getter; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.util.List; | ||
|
||
public class ModelToSchemeCollectionConverterTestCase { | ||
|
||
@Getter | ||
@Collection(id = 1, name = "test") | ||
public static class TestModel { | ||
@Field(id = 1) | ||
@AutoIncrement | ||
@Index(primary = true) | ||
private int id; | ||
|
||
@Field(id = 2) | ||
private String name; | ||
|
||
@Field(id = 3) | ||
@Index() | ||
private long age; | ||
|
||
@Field(id = 4) | ||
@Index(lowCardinality = true) | ||
private String country; | ||
} | ||
|
||
|
||
@Test | ||
public void convert() { | ||
ModelToSchemeCollectionConverter converter = new ModelToSchemeCollectionConverter(TestModel.class); | ||
Scheme.Collection collection = converter.toCollection(); | ||
|
||
Assertions.assertEquals(1, collection.getId()); | ||
Assertions.assertEquals("test", collection.getName()); | ||
|
||
List<Scheme.Field> fields = collection.getFields(); | ||
Assertions.assertEquals(4, fields.size()); | ||
|
||
Scheme.Field field = fields.getFirst(); | ||
Assertions.assertEquals(1, field.getId()); | ||
Assertions.assertEquals("int", field.getType()); | ||
|
||
field = fields.get(1); | ||
Assertions.assertEquals(2, field.getId()); | ||
Assertions.assertEquals("char", field.getType()); | ||
|
||
field = fields.get(2); | ||
Assertions.assertEquals(3, field.getId()); | ||
Assertions.assertEquals("long", field.getType()); | ||
|
||
field = fields.get(3); | ||
Assertions.assertEquals(4, field.getId()); | ||
Assertions.assertEquals("char", field.getType()); | ||
|
||
|
||
} | ||
|
||
} |