Compare commits
No commits in common. "83977e060c2a055e64fc065c633a2c1be2bdba31" and "b0d565b0144ae009719f2433c3ef19ef1e5c02e1" have entirely different histories.
83977e060c
...
b0d565b014
23
pom.xml
23
pom.xml
@ -188,29 +188,6 @@
|
|||||||
<version>4.8.6</version>
|
<version>4.8.6</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- Morphia -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>dev.morphia.morphia</groupId>
|
|
||||||
<artifactId>morphia-core</artifactId>
|
|
||||||
<version>2.3.0</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- MongoDB Java Driver -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mongodb</groupId>
|
|
||||||
<artifactId>mongodb-driver-sync</artifactId>
|
|
||||||
<version>4.3.0</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- Bean Validation (JSR 303 / 380) -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.hibernate.validator</groupId>
|
|
||||||
<artifactId>hibernate-validator</artifactId>
|
|
||||||
<version>7.0.0.Final</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.validation</groupId>
|
|
||||||
<artifactId>validation-api</artifactId>
|
|
||||||
<version>2.0.1.Final</version>
|
|
||||||
</dependency>
|
|
||||||
<!--
|
<!--
|
||||||
************************************************************
|
************************************************************
|
||||||
** TEST dependency **
|
** TEST dependency **
|
||||||
|
@ -84,19 +84,27 @@ public class AnnotationTools {
|
|||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean getSchemaReadOnly(final Field element) {
|
public static boolean getSchemaReadOnly(final Field element) throws DataAccessException {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (annotation.length > 1) {
|
||||||
|
throw new DataAccessException(
|
||||||
|
"Must not have more than 1 element @Schema on " + element.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
return ((Schema) annotation[0]).readOnly();
|
return ((Schema) annotation[0]).readOnly();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getSchemaExample(final Class<?> element) {
|
public static String getSchemaExample(final Class<?> element) throws DataAccessException {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (annotation.length > 1) {
|
||||||
|
throw new DataAccessException(
|
||||||
|
"Must not have more than 1 element @Schema on " + element.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
return ((Schema) annotation[0]).example();
|
return ((Schema) annotation[0]).example();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,27 +116,51 @@ public class AnnotationTools {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getSchemaDescription(final Class<?> element) {
|
public static String getSchemaDescription(final Class<?> element) throws DataAccessException {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return ((Schema) annotation[0]).description();
|
if (annotation.length > 1) {
|
||||||
}
|
throw new DataAccessException(
|
||||||
|
"Must not have more than 1 element @Schema on " + element.getClass().getCanonicalName());
|
||||||
public static String getSchemaDescription(final Field element) {
|
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
|
|
||||||
if (annotation.length == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
return ((Schema) annotation[0]).description();
|
return ((Schema) annotation[0]).description();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getDefault(final Field element) {
|
public static String getSchemaDescription(final Field element) throws DataAccessException {
|
||||||
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
|
||||||
|
if (annotation.length == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (annotation.length > 1) {
|
||||||
|
throw new DataAccessException(
|
||||||
|
"Must not have more than 1 element @Schema on " + element.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
|
return ((Schema) annotation[0]).description();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getComment(final Field element) throws DataAccessException {
|
||||||
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(DataComment.class);
|
||||||
|
if (annotation.length == 0) {
|
||||||
|
return getSchemaDescription(element);
|
||||||
|
}
|
||||||
|
if (annotation.length > 1) {
|
||||||
|
throw new DataAccessException(
|
||||||
|
"Must not have more than 1 element @DataComment on " + element.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
|
return ((DataComment) annotation[0]).value();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDefault(final Field element) throws DataAccessException {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(DefaultValue.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(DefaultValue.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (annotation.length > 1) {
|
||||||
|
throw new DataAccessException(
|
||||||
|
"Must not have more than 1 element @DataDefault on " + element.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
return ((DefaultValue) annotation[0]).value();
|
return ((DefaultValue) annotation[0]).value();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,56 +188,80 @@ public class AnnotationTools {
|
|||||||
return (OneToMany) annotation[0];
|
return (OneToMany) annotation[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DataJson getDataJson(final Field element) {
|
public static DataJson getDataJson(final Field element) throws DataAccessException {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(DataJson.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(DataJson.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (annotation.length > 1) {
|
||||||
|
throw new DataAccessException(
|
||||||
|
"Must not have more than 1 element @ManyToOne on " + element.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
return (DataJson) annotation[0];
|
return (DataJson) annotation[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Long getConstraintsMax(final Field element) {
|
public static Long getConstraintsMax(final Field element) throws DataAccessException {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Max.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Max.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (annotation.length > 1) {
|
||||||
|
throw new DataAccessException(
|
||||||
|
"Must not have more than 1 element @Size on " + element.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
return ((Max) annotation[0]).value();
|
return ((Max) annotation[0]).value();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Long getConstraintsMin(final Field element) {
|
public static Long getConstraintsMin(final Field element) throws DataAccessException {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Min.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Min.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (annotation.length > 1) {
|
||||||
|
throw new DataAccessException(
|
||||||
|
"Must not have more than 1 element @Size on " + element.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
return ((Min) annotation[0]).value();
|
return ((Min) annotation[0]).value();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getLimitSize(final Field element) {
|
public static int getLimitSize(final Field element) throws DataAccessException {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return 255;
|
return 255;
|
||||||
}
|
}
|
||||||
|
if (annotation.length > 1) {
|
||||||
|
throw new DataAccessException(
|
||||||
|
"Must not have more than 1 element @Column on " + element.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
final int length = ((Column) annotation[0]).length();
|
final int length = ((Column) annotation[0]).length();
|
||||||
return length <= 0 ? 0 : length;
|
return length <= 0 ? 0 : length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Size getConstraintsSize(final Field element) {
|
public static Size getConstraintsSize(final Field element) throws DataAccessException {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Size.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Size.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (annotation.length > 1) {
|
||||||
|
throw new DataAccessException(
|
||||||
|
"Must not have more than 1 element @Size on " + element.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
return (Size) annotation[0];
|
return (Size) annotation[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getConstraintsPattern(final Field element) {
|
public static String getConstraintsPattern(final Field element) throws DataAccessException {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Pattern.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Pattern.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (annotation.length > 1) {
|
||||||
|
throw new DataAccessException(
|
||||||
|
"Must not have more than 1 element @Pattern on " + element.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
return ((Pattern) annotation[0]).regexp();
|
return ((Pattern) annotation[0]).regexp();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean getConstraintsEmail(final Field element) {
|
public static boolean getConstraintsEmail(final Field element) throws DataAccessException {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Email.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Email.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -248,15 +304,19 @@ public class AnnotationTools {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean getColumnNotNull(final Field element) {
|
public static boolean getColumnNotNull(final Field element) throws DataAccessException {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (annotation.length > 1) {
|
||||||
|
throw new DataAccessException(
|
||||||
|
"Must not have more than 1 element @Column on " + element.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
return !((Column) annotation[0]).nullable();
|
return !((Column) annotation[0]).nullable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean getNullable(final Field element) {
|
public static boolean getNullable(final Field element) throws DataAccessException {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Nullable.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Nullable.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -264,15 +324,19 @@ public class AnnotationTools {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean getConstraintsNotNull(final Field element) {
|
public static boolean getConstraintsNotNull(final Field element) throws DataAccessException {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(NotNull.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(NotNull.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (annotation.length > 1) {
|
||||||
|
throw new DataAccessException(
|
||||||
|
"Must not have more than 1 element @NotNull on " + element.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Field getPrimaryKeyField(final Class<?> clazz) {
|
public static Field getPrimaryKeyField(final Class<?> clazz) throws DataAccessException {
|
||||||
for (final Field field : clazz.getFields()) {
|
for (final Field field : clazz.getFields()) {
|
||||||
// static field is only for internal global declaration ==> remove it ..
|
// static field is only for internal global declaration ==> remove it ..
|
||||||
if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
|
if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
|
||||||
@ -285,7 +349,7 @@ public class AnnotationTools {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isPrimaryKey(final Field element) {
|
public static boolean isPrimaryKey(final Field element) throws DataAccessException {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Id.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Id.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -293,43 +357,51 @@ public class AnnotationTools {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isUnique(final Field element) {
|
public static boolean isUnique(final Field element) throws DataAccessException {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (annotation.length > 1) {
|
||||||
|
throw new DataAccessException(
|
||||||
|
"Must not have more than 1 element @Column on " + element.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
return ((Column) annotation[0]).unique();
|
return ((Column) annotation[0]).unique();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GenerationType getStrategy(final Field element) {
|
public static GenerationType getStrategy(final Field element) throws DataAccessException {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(GeneratedValue.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(GeneratedValue.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (annotation.length > 1) {
|
||||||
|
throw new DataAccessException(
|
||||||
|
"Must not have more than 1 element @Column on " + element.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
return ((GeneratedValue) annotation[0]).strategy();
|
return ((GeneratedValue) annotation[0]).strategy();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isDeletedField(final Field element) {
|
public static boolean isDeletedField(final Field element) throws DataAccessException {
|
||||||
return element.getDeclaredAnnotationsByType(DataDeleted.class).length != 0;
|
return element.getDeclaredAnnotationsByType(DataDeleted.class).length != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isCreatedAtField(final Field element) {
|
public static boolean isCreatedAtField(final Field element) throws DataAccessException {
|
||||||
return element.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0;
|
return element.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isUpdateAtField(final Field element) {
|
public static boolean isUpdateAtField(final Field element) throws DataAccessException {
|
||||||
return element.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0;
|
return element.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isdefaultNotRead(final Field element) {
|
public static boolean isdefaultNotRead(final Field element) throws DataAccessException {
|
||||||
return element.getDeclaredAnnotationsByType(DataNotRead.class).length != 0;
|
return element.getDeclaredAnnotationsByType(DataNotRead.class).length != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isIdField(final Field element) {
|
public static boolean isIdField(final Field element) throws DataAccessException {
|
||||||
return element.getDeclaredAnnotationsByType(Id.class).length != 0;
|
return element.getDeclaredAnnotationsByType(Id.class).length != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getDeletedFieldName(final Class<?> clazz) {
|
public static String getDeletedFieldName(final Class<?> clazz) throws DataAccessException {
|
||||||
try {
|
try {
|
||||||
for (final Field elem : clazz.getFields()) {
|
for (final Field elem : clazz.getFields()) {
|
||||||
// static field is only for internal global declaration ==> remove it ..
|
// static field is only for internal global declaration ==> remove it ..
|
||||||
@ -346,7 +418,7 @@ public class AnnotationTools {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getUpdatedFieldName(final Class<?> clazz) {
|
public static String getUpdatedFieldName(final Class<?> clazz) throws DataAccessException {
|
||||||
try {
|
try {
|
||||||
for (final Field elem : clazz.getFields()) {
|
for (final Field elem : clazz.getFields()) {
|
||||||
// static field is only for internal global declaration ==> remove it ..
|
// static field is only for internal global declaration ==> remove it ..
|
||||||
@ -380,15 +452,16 @@ public class AnnotationTools {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> getFieldsNames(final Class<?> clazz) {
|
public static List<String> getFieldsNames(final Class<?> clazz) throws DataAccessException {
|
||||||
return getFieldsNamesFilter(clazz, false);
|
return getFieldsNamesFilter(clazz, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> getAllFieldsNames(final Class<?> clazz) {
|
public static List<String> getAllFieldsNames(final Class<?> clazz) throws DataAccessException {
|
||||||
return getFieldsNamesFilter(clazz, true);
|
return getFieldsNamesFilter(clazz, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> getFieldsNamesFilter(final Class<?> clazz, final boolean full) {
|
private static List<String> getFieldsNamesFilter(final Class<?> clazz, final boolean full)
|
||||||
|
throws DataAccessException {
|
||||||
final List<String> out = new ArrayList<>();
|
final List<String> out = new ArrayList<>();
|
||||||
for (final Field field : clazz.getFields()) {
|
for (final Field field : clazz.getFields()) {
|
||||||
// static field is only for internal global declaration ==> remove it ..
|
// static field is only for internal global declaration ==> remove it ..
|
||||||
@ -403,12 +476,12 @@ public class AnnotationTools {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isGenericField(final Field elem) {
|
public static boolean isGenericField(final Field elem) throws DataAccessException {
|
||||||
return AnnotationTools.isPrimaryKey(elem) || AnnotationTools.isCreatedAtField(elem)
|
return AnnotationTools.isPrimaryKey(elem) || AnnotationTools.isCreatedAtField(elem)
|
||||||
|| AnnotationTools.isUpdateAtField(elem) || AnnotationTools.isDeletedField(elem);
|
|| AnnotationTools.isUpdateAtField(elem) || AnnotationTools.isDeletedField(elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Field getFieldOfId(final Class<?> clazz) {
|
public static Field getFieldOfId(final Class<?> clazz) throws DataAccessException {
|
||||||
for (final Field field : clazz.getFields()) {
|
for (final Field field : clazz.getFields()) {
|
||||||
// static field is only for internal global declaration ==> remove it ..
|
// static field is only for internal global declaration ==> remove it ..
|
||||||
if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
|
if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
|
||||||
@ -421,7 +494,7 @@ public class AnnotationTools {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Field getFieldNamed(final Class<?> clazz, final String name) {
|
public static Field getFieldNamed(final Class<?> clazz, final String name) throws DataAccessException {
|
||||||
for (final Field field : clazz.getFields()) {
|
for (final Field field : clazz.getFields()) {
|
||||||
// static field is only for internal global declaration ==> remove it ..
|
// static field is only for internal global declaration ==> remove it ..
|
||||||
if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
|
if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user