Compare commits
15 Commits
c43e283b57
...
e4c56a4da5
Author | SHA1 | Date | |
---|---|---|---|
e4c56a4da5 | |||
22614aee98 | |||
5bbcf63c42 | |||
1c02d333a3 | |||
1c41ea4273 | |||
274767d89b | |||
4236dc38bd | |||
7d4b246d4a | |||
f6f256c006 | |||
d46b84c741 | |||
3e6b9bf77c | |||
007003394a | |||
54d4c420f9 | |||
0a307f3f6e | |||
d968a2c48f |
@ -93,7 +93,12 @@ Enable the pre-commit checker
|
||||
|
||||
> **_Note_**: You can change the code in `.git/hooks/pre-commit` by replacing `formatter:verify` with `formatter:format` to auto format the code @ every commit
|
||||
|
||||
Run Spot-bug:
|
||||
------------
|
||||
|
||||
```bash
|
||||
mvn spotbugs:check
|
||||
```
|
||||
|
||||
Add Gitea in the dependency for the registry:
|
||||
=============================================
|
||||
|
15
pom.xml
15
pom.xml
@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>kangaroo-and-rabbit</groupId>
|
||||
<artifactId>archidata</artifactId>
|
||||
<version>0.10.3</version>
|
||||
<version>0.11.0</version>
|
||||
<properties>
|
||||
<java.version>21</java.version>
|
||||
<maven.compiler.version>3.1</maven.compiler.version>
|
||||
@ -135,13 +135,13 @@
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.45.3.0</version>
|
||||
<version>3.46.0.0</version>
|
||||
</dependency>
|
||||
<!-- Interface for JWT token -->
|
||||
<dependency>
|
||||
<groupId>com.nimbusds</groupId>
|
||||
<artifactId>nimbus-jose-jwt</artifactId>
|
||||
<version>9.39.1</version>
|
||||
<version>9.39.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.persistence</groupId>
|
||||
@ -154,6 +154,13 @@
|
||||
<artifactId>swagger-jaxrs2-jakarta</artifactId>
|
||||
<version>2.2.22</version>
|
||||
</dependency>
|
||||
<!-- spotbug tooling -->
|
||||
<dependency>
|
||||
<groupId>com.github.spotbugs</groupId>
|
||||
<artifactId>spotbugs-annotations</artifactId>
|
||||
<version>4.8.5</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!--
|
||||
************************************************************
|
||||
** TEST dependency **
|
||||
@ -174,7 +181,7 @@
|
||||
<dependency>
|
||||
<groupId>net.revelc.code.formatter</groupId>
|
||||
<artifactId>formatter-maven-plugin</artifactId>
|
||||
<version>2.23.0</version>
|
||||
<version>2.24.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
5
spotbugs-security-exclude.xml
Normal file
5
spotbugs-security-exclude.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<FindBugsFilter>
|
||||
<Match>
|
||||
<Bug category="SECURITY"/>
|
||||
</Match>
|
||||
</FindBugsFilter>
|
2
spotbugs-security-include.xml
Normal file
2
spotbugs-security-include.xml
Normal file
@ -0,0 +1,2 @@
|
||||
<FindBugsFilter>
|
||||
</FindBugsFilter>
|
@ -7,6 +7,7 @@ import java.util.List;
|
||||
|
||||
import org.kar.archidata.dataAccess.QueryOptions;
|
||||
import org.kar.archidata.dataAccess.options.OverrideTableName;
|
||||
import org.kar.archidata.exception.DataAccessException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -28,7 +29,7 @@ import jakarta.ws.rs.DefaultValue;
|
||||
public class AnnotationTools {
|
||||
static final Logger LOGGER = LoggerFactory.getLogger(AnnotationTools.class);
|
||||
|
||||
public static String getTableName(final Class<?> clazz, final QueryOptions options) throws Exception {
|
||||
public static String getTableName(final Class<?> clazz, final QueryOptions options) throws DataAccessException {
|
||||
if (options != null) {
|
||||
final List<OverrideTableName> data = options.get(OverrideTableName.class);
|
||||
if (data.size() == 1) {
|
||||
@ -38,14 +39,15 @@ public class AnnotationTools {
|
||||
return AnnotationTools.getTableName(clazz);
|
||||
}
|
||||
|
||||
public static String getTableName(final Class<?> element) throws Exception {
|
||||
public static String getTableName(final Class<?> element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Table.class);
|
||||
if (annotation.length == 0) {
|
||||
// when no annotation is detected, then the table name is the class name
|
||||
return element.getSimpleName();
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception("Must not have more than 1 element @Table on " + element.getClass().getCanonicalName());
|
||||
throw new DataAccessException(
|
||||
"Must not have more than 1 element @Table on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
final String tmp = ((Table) annotation[0]).name();
|
||||
if (tmp == null) {
|
||||
@ -54,155 +56,158 @@ public class AnnotationTools {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
public static boolean getSchemaReadOnly(final Field element) throws Exception {
|
||||
public static boolean getSchemaReadOnly(final Field element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
|
||||
if (annotation.length == 0) {
|
||||
return false;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception(
|
||||
throw new DataAccessException(
|
||||
"Must not have more than 1 element @Schema on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
return ((Schema) annotation[0]).readOnly();
|
||||
}
|
||||
|
||||
public static String getSchemaExample(final Class<?> element) throws Exception {
|
||||
public static String getSchemaExample(final Class<?> element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
|
||||
if (annotation.length == 0) {
|
||||
return null;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception(
|
||||
throw new DataAccessException(
|
||||
"Must not have more than 1 element @Schema on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
return ((Schema) annotation[0]).example();
|
||||
}
|
||||
|
||||
public static String getSchemaDescription(final Class<?> element) throws Exception {
|
||||
public static String getSchemaDescription(final Class<?> element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Schema.class);
|
||||
if (annotation.length == 0) {
|
||||
return null;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception(
|
||||
throw new DataAccessException(
|
||||
"Must not have more than 1 element @Schema on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
return ((Schema) annotation[0]).description();
|
||||
}
|
||||
|
||||
public static String getSchemaDescription(final Field element) throws Exception {
|
||||
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 Exception(
|
||||
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 Exception {
|
||||
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 Exception(
|
||||
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 Exception {
|
||||
public static String getDefault(final Field element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(DefaultValue.class);
|
||||
if (annotation.length == 0) {
|
||||
return null;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception(
|
||||
throw new DataAccessException(
|
||||
"Must not have more than 1 element @DataDefault on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
return ((DefaultValue) annotation[0]).value();
|
||||
}
|
||||
|
||||
public static ManyToOne getManyToOne(final Field element) throws Exception {
|
||||
public static ManyToOne getManyToOne(final Field element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(ManyToOne.class);
|
||||
if (annotation.length == 0) {
|
||||
return null;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception(
|
||||
throw new DataAccessException(
|
||||
"Must not have more than 1 element @ManyToOne on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
return (ManyToOne) annotation[0];
|
||||
}
|
||||
|
||||
public static DataJson getDataJson(final Field element) throws Exception {
|
||||
public static DataJson getDataJson(final Field element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(DataJson.class);
|
||||
if (annotation.length == 0) {
|
||||
return null;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception(
|
||||
throw new DataAccessException(
|
||||
"Must not have more than 1 element @ManyToOne on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
return (DataJson) annotation[0];
|
||||
}
|
||||
|
||||
public static Long getConstraintsMax(final Field element) throws Exception {
|
||||
public static Long getConstraintsMax(final Field element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Max.class);
|
||||
if (annotation.length == 0) {
|
||||
return null;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception("Must not have more than 1 element @Size on " + element.getClass().getCanonicalName());
|
||||
throw new DataAccessException(
|
||||
"Must not have more than 1 element @Size on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
return ((Max) annotation[0]).value();
|
||||
}
|
||||
|
||||
public static Long getConstraintsMin(final Field element) throws Exception {
|
||||
public static Long getConstraintsMin(final Field element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Min.class);
|
||||
if (annotation.length == 0) {
|
||||
return null;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception("Must not have more than 1 element @Size on " + element.getClass().getCanonicalName());
|
||||
throw new DataAccessException(
|
||||
"Must not have more than 1 element @Size on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
return ((Min) annotation[0]).value();
|
||||
}
|
||||
|
||||
public static int getLimitSize(final Field element) throws Exception {
|
||||
public static int getLimitSize(final Field element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class);
|
||||
if (annotation.length == 0) {
|
||||
return 255;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception(
|
||||
throw new DataAccessException(
|
||||
"Must not have more than 1 element @Column on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
final int length = ((Column) annotation[0]).length();
|
||||
return length <= 0 ? 0 : length;
|
||||
}
|
||||
|
||||
public static Size getConstraintsSize(final Field element) throws Exception {
|
||||
public static Size getConstraintsSize(final Field element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Size.class);
|
||||
if (annotation.length == 0) {
|
||||
return null;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception("Must not have more than 1 element @Size on " + element.getClass().getCanonicalName());
|
||||
throw new DataAccessException(
|
||||
"Must not have more than 1 element @Size on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
return (Size) annotation[0];
|
||||
}
|
||||
|
||||
public static String getConstraintsPattern(final Field element) throws Exception {
|
||||
public static String getConstraintsPattern(final Field element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Pattern.class);
|
||||
if (annotation.length == 0) {
|
||||
return null;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception(
|
||||
throw new DataAccessException(
|
||||
"Must not have more than 1 element @Pattern on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
return ((Pattern) annotation[0]).regexp();
|
||||
@ -231,13 +236,13 @@ public class AnnotationTools {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String getFieldName(final Field element) throws Exception {
|
||||
public static String getFieldName(final Field element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class);
|
||||
if (annotation.length == 0) {
|
||||
return element.getName();
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception(
|
||||
throw new DataAccessException(
|
||||
"Must not have more than 1 element @Column on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
final String name = ((Column) annotation[0]).name();
|
||||
@ -247,19 +252,19 @@ public class AnnotationTools {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static boolean getColumnNotNull(final Field element) throws Exception {
|
||||
public static boolean getColumnNotNull(final Field element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class);
|
||||
if (annotation.length == 0) {
|
||||
return false;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception(
|
||||
throw new DataAccessException(
|
||||
"Must not have more than 1 element @Column on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
return !((Column) annotation[0]).nullable();
|
||||
}
|
||||
|
||||
public static boolean getNullable(final Field element) throws Exception {
|
||||
public static boolean getNullable(final Field element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Nullable.class);
|
||||
if (annotation.length == 0) {
|
||||
return false;
|
||||
@ -267,19 +272,19 @@ public class AnnotationTools {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean getConstraintsNotNull(final Field element) throws Exception {
|
||||
public static boolean getConstraintsNotNull(final Field element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(NotNull.class);
|
||||
if (annotation.length == 0) {
|
||||
return false;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception(
|
||||
throw new DataAccessException(
|
||||
"Must not have more than 1 element @NotNull on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Field getPrimaryKeyField(final Class<?> clazz) throws Exception {
|
||||
public static Field getPrimaryKeyField(final Class<?> clazz) throws DataAccessException {
|
||||
for (final Field field : clazz.getFields()) {
|
||||
// static field is only for internal global declaration ==> remove it ..
|
||||
if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
|
||||
@ -292,7 +297,7 @@ public class AnnotationTools {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isPrimaryKey(final Field element) throws Exception {
|
||||
public static boolean isPrimaryKey(final Field element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Id.class);
|
||||
if (annotation.length == 0) {
|
||||
return false;
|
||||
@ -300,51 +305,51 @@ public class AnnotationTools {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isUnique(final Field element) throws Exception {
|
||||
public static boolean isUnique(final Field element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class);
|
||||
if (annotation.length == 0) {
|
||||
return false;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception(
|
||||
throw new DataAccessException(
|
||||
"Must not have more than 1 element @Column on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
return ((Column) annotation[0]).unique();
|
||||
}
|
||||
|
||||
public static GenerationType getStrategy(final Field element) throws Exception {
|
||||
public static GenerationType getStrategy(final Field element) throws DataAccessException {
|
||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(GeneratedValue.class);
|
||||
if (annotation.length == 0) {
|
||||
return null;
|
||||
}
|
||||
if (annotation.length > 1) {
|
||||
throw new Exception(
|
||||
throw new DataAccessException(
|
||||
"Must not have more than 1 element @Column on " + element.getClass().getCanonicalName());
|
||||
}
|
||||
return ((GeneratedValue) annotation[0]).strategy();
|
||||
}
|
||||
|
||||
public static boolean isDeletedField(final Field element) throws Exception {
|
||||
public static boolean isDeletedField(final Field element) throws DataAccessException {
|
||||
return element.getDeclaredAnnotationsByType(DataDeleted.class).length != 0;
|
||||
}
|
||||
|
||||
public static boolean isCreatedAtField(final Field element) throws Exception {
|
||||
public static boolean isCreatedAtField(final Field element) throws DataAccessException {
|
||||
return element.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0;
|
||||
}
|
||||
|
||||
public static boolean isUpdateAtField(final Field element) throws Exception {
|
||||
public static boolean isUpdateAtField(final Field element) throws DataAccessException {
|
||||
return element.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0;
|
||||
}
|
||||
|
||||
public static boolean isdefaultNotRead(final Field element) throws Exception {
|
||||
public static boolean isdefaultNotRead(final Field element) throws DataAccessException {
|
||||
return element.getDeclaredAnnotationsByType(DataNotRead.class).length != 0;
|
||||
}
|
||||
|
||||
public static boolean isIdField(final Field element) throws Exception {
|
||||
public static boolean isIdField(final Field element) throws DataAccessException {
|
||||
return element.getDeclaredAnnotationsByType(Id.class).length != 0;
|
||||
}
|
||||
|
||||
public static String getDeletedFieldName(final Class<?> clazz) throws Exception {
|
||||
public static String getDeletedFieldName(final Class<?> clazz) throws DataAccessException {
|
||||
try {
|
||||
for (final Field elem : clazz.getFields()) {
|
||||
// static field is only for internal global declaration ==> remove it ..
|
||||
@ -361,7 +366,7 @@ public class AnnotationTools {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getUpdatedFieldName(final Class<?> clazz) throws Exception {
|
||||
public static String getUpdatedFieldName(final Class<?> clazz) throws DataAccessException {
|
||||
try {
|
||||
for (final Field elem : clazz.getFields()) {
|
||||
// static field is only for internal global declaration ==> remove it ..
|
||||
@ -395,15 +400,16 @@ public class AnnotationTools {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<String> getFieldsNames(final Class<?> clazz) throws Exception {
|
||||
public static List<String> getFieldsNames(final Class<?> clazz) throws DataAccessException {
|
||||
return getFieldsNamesFilter(clazz, false);
|
||||
}
|
||||
|
||||
public static List<String> getAllFieldsNames(final Class<?> clazz) throws Exception {
|
||||
public static List<String> getAllFieldsNames(final Class<?> clazz) throws DataAccessException {
|
||||
return getFieldsNamesFilter(clazz, true);
|
||||
}
|
||||
|
||||
private static List<String> getFieldsNamesFilter(final Class<?> clazz, final boolean full) throws Exception {
|
||||
private static List<String> getFieldsNamesFilter(final Class<?> clazz, final boolean full)
|
||||
throws DataAccessException {
|
||||
final List<String> out = new ArrayList<>();
|
||||
for (final Field field : clazz.getFields()) {
|
||||
// static field is only for internal global declaration ==> remove it ..
|
||||
@ -418,12 +424,12 @@ public class AnnotationTools {
|
||||
return out;
|
||||
}
|
||||
|
||||
public static boolean isGenericField(final Field elem) throws Exception {
|
||||
public static boolean isGenericField(final Field elem) throws DataAccessException {
|
||||
return AnnotationTools.isPrimaryKey(elem) || AnnotationTools.isCreatedAtField(elem)
|
||||
|| AnnotationTools.isUpdateAtField(elem) || AnnotationTools.isDeletedField(elem);
|
||||
}
|
||||
|
||||
public static Field getFieldOfId(final Class<?> clazz) throws Exception {
|
||||
public static Field getFieldOfId(final Class<?> clazz) throws DataAccessException {
|
||||
for (final Field field : clazz.getFields()) {
|
||||
// static field is only for internal global declaration ==> remove it ..
|
||||
if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
|
||||
@ -436,7 +442,7 @@ public class AnnotationTools {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Field getFieldNamed(final Class<?> clazz, final String name) throws Exception {
|
||||
public static Field getFieldNamed(final Class<?> clazz, final String name) throws DataAccessException {
|
||||
for (final Field field : clazz.getFields()) {
|
||||
// static field is only for internal global declaration ==> remove it ..
|
||||
if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
|
||||
|
@ -5,6 +5,7 @@ import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -26,6 +27,7 @@ import org.kar.archidata.annotation.security.PermitTokenInURI;
|
||||
import org.kar.archidata.dataAccess.DataAccess;
|
||||
import org.kar.archidata.dataAccess.QueryCondition;
|
||||
import org.kar.archidata.dataAccess.options.Condition;
|
||||
import org.kar.archidata.exception.FailException;
|
||||
import org.kar.archidata.filter.GenericContext;
|
||||
import org.kar.archidata.model.Data;
|
||||
import org.kar.archidata.tools.ConfigBaseVariable;
|
||||
@ -191,7 +193,8 @@ public class DataResource {
|
||||
LOGGER.info("Move done");
|
||||
}
|
||||
|
||||
public static String saveTemporaryFile(final InputStream uploadedInputStream, final long idData) {
|
||||
public static String saveTemporaryFile(final InputStream uploadedInputStream, final long idData)
|
||||
throws FailException {
|
||||
return saveFile(uploadedInputStream, DataResource.getTmpFileInData(idData));
|
||||
}
|
||||
|
||||
@ -208,35 +211,35 @@ public class DataResource {
|
||||
}
|
||||
|
||||
// save uploaded file to a defined location on the server
|
||||
static String saveFile(final InputStream uploadedInputStream, final String serverLocation) {
|
||||
static String saveFile(final InputStream uploadedInputStream, final String serverLocation) throws FailException {
|
||||
String out = "";
|
||||
try {
|
||||
OutputStream outpuStream = new FileOutputStream(new File(serverLocation));
|
||||
int read = 0;
|
||||
final byte[] bytes = new byte[CHUNK_SIZE_IN];
|
||||
final MessageDigest md = MessageDigest.getInstance("SHA-512");
|
||||
|
||||
outpuStream = new FileOutputStream(new File(serverLocation));
|
||||
while ((read = uploadedInputStream.read(bytes)) != -1) {
|
||||
// logger.info("write {}", read);
|
||||
md.update(bytes, 0, read);
|
||||
outpuStream.write(bytes, 0, read);
|
||||
}
|
||||
LOGGER.info("Flush input stream ... {}", serverLocation);
|
||||
System.out.flush();
|
||||
outpuStream.flush();
|
||||
outpuStream.close();
|
||||
// create the end of sha512
|
||||
final byte[] sha512Digest = md.digest();
|
||||
// convert in hexadecimal
|
||||
out = bytesToHex(sha512Digest);
|
||||
uploadedInputStream.close();
|
||||
MessageDigest md = null;
|
||||
try (OutputStream outpuStream = new FileOutputStream(new File(serverLocation))) {
|
||||
md = MessageDigest.getInstance("SHA-512");
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.info("Can not write in temporary file ... ");
|
||||
ex.printStackTrace();
|
||||
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Can not write in temporary file", ex);
|
||||
} catch (final NoSuchAlgorithmException ex) {
|
||||
LOGGER.info("Can not find sha512 algorithms");
|
||||
ex.printStackTrace();
|
||||
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Can not find sha512 algorithms", ex);
|
||||
}
|
||||
if (md != null) {
|
||||
try (OutputStream outpuStream = new FileOutputStream(new File(serverLocation))) {
|
||||
int read = 0;
|
||||
final byte[] bytes = new byte[CHUNK_SIZE_IN];
|
||||
while ((read = uploadedInputStream.read(bytes)) != -1) {
|
||||
// logger.info("write {}", read);
|
||||
md.update(bytes, 0, read);
|
||||
outpuStream.write(bytes, 0, read);
|
||||
}
|
||||
LOGGER.info("Flush input stream ... {}", serverLocation);
|
||||
outpuStream.flush();
|
||||
// create the end of sha512
|
||||
final byte[] sha512Digest = md.digest();
|
||||
// convert in hexadecimal
|
||||
out = bytesToHex(sha512Digest);
|
||||
uploadedInputStream.close();
|
||||
} catch (final IOException ex) {
|
||||
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Can not write in temporary file", ex);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@ -267,7 +270,7 @@ public class DataResource {
|
||||
public void uploadFile(
|
||||
@Context final SecurityContext sc,
|
||||
@FormDataParam("file") final InputStream fileInputStream,
|
||||
@FormDataParam("file") final FormDataContentDisposition fileMetaData) {
|
||||
@FormDataParam("file") final FormDataContentDisposition fileMetaData) throws FailException {
|
||||
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
LOGGER.info("===================================================");
|
||||
LOGGER.info("== DATA uploadFile {}", (gc == null ? "null" : gc.userByToken));
|
||||
@ -277,8 +280,9 @@ public class DataResource {
|
||||
final String filePath = ConfigBaseVariable.getTmpDataFolder() + File.separator + tmpFolderId++;
|
||||
try {
|
||||
createFolder(ConfigBaseVariable.getTmpDataFolder() + File.separator);
|
||||
} catch (final IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (final IOException ex) {
|
||||
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR,
|
||||
"Impossible to create the folder in the server", ex);
|
||||
}
|
||||
saveFile(fileInputStream, filePath);
|
||||
}
|
||||
@ -293,7 +297,7 @@ public class DataResource {
|
||||
@Context final SecurityContext sc,
|
||||
@QueryParam(HttpHeaders.AUTHORIZATION) final String token,
|
||||
@HeaderParam("Range") final String range,
|
||||
@PathParam("uuid") final UUID uuid) throws Exception {
|
||||
@PathParam("uuid") final UUID uuid) throws FailException {
|
||||
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
// logger.info("===================================================");
|
||||
LOGGER.info("== DATA retrieveDataId ? id={} user={}", uuid, (gc == null ? "null" : gc.userByToken));
|
||||
@ -302,8 +306,12 @@ public class DataResource {
|
||||
if (value == null) {
|
||||
return Response.status(404).entity("media NOT FOUND: " + uuid).type("text/plain").build();
|
||||
}
|
||||
return buildStream(getFileData(uuid), range,
|
||||
value.mimeType == null ? "application/octet-stream" : value.mimeType);
|
||||
try {
|
||||
return buildStream(getFileData(uuid), range,
|
||||
value.mimeType == null ? "application/octet-stream" : value.mimeType);
|
||||
} catch (final Exception ex) {
|
||||
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to build output stream", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@ -317,7 +325,7 @@ public class DataResource {
|
||||
@Context final SecurityContext sc,
|
||||
@QueryParam(HttpHeaders.AUTHORIZATION) final String token,
|
||||
@HeaderParam("Range") final String range,
|
||||
@PathParam("uuid") final UUID uuid) throws Exception {
|
||||
@PathParam("uuid") final UUID uuid) throws FailException {
|
||||
// GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||
// logger.info("===================================================");
|
||||
// logger.info("== DATA retrieveDataThumbnailId ? {}", (gc==null?"null":gc.user));
|
||||
@ -336,7 +344,12 @@ public class DataResource {
|
||||
// || value.mimeType.contentEquals("image/webp")
|
||||
) {
|
||||
// reads input image
|
||||
final BufferedImage inputImage = ImageIO.read(inputFile);
|
||||
BufferedImage inputImage;
|
||||
try {
|
||||
inputImage = ImageIO.read(inputFile);
|
||||
} catch (final IOException ex) {
|
||||
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to READ the image", ex);
|
||||
}
|
||||
final int scaledWidth = 250;
|
||||
final int scaledHeight = (int) ((float) inputImage.getHeight() / (float) inputImage.getWidth()
|
||||
* scaledWidth);
|
||||
@ -369,7 +382,11 @@ public class DataResource {
|
||||
out.cacheControl(cc);
|
||||
return out.build();
|
||||
}
|
||||
return buildStream(filePathName, range, value.mimeType);
|
||||
try {
|
||||
return buildStream(filePathName, range, value.mimeType);
|
||||
} catch (final Exception ex) {
|
||||
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to build output stream", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@ -400,8 +417,10 @@ public class DataResource {
|
||||
*
|
||||
* @param range range header
|
||||
* @return Streaming output
|
||||
* @throws FileNotFoundException
|
||||
* @throws Exception IOException if an error occurs in streaming. */
|
||||
private Response buildStream(final String filename, final String range, final String mimeType) throws Exception {
|
||||
private Response buildStream(final String filename, final String range, final String mimeType)
|
||||
throws FailException {
|
||||
final File file = new File(filename);
|
||||
// logger.info("request range : {}", range);
|
||||
// range not requested : Firefox does not send range headers
|
||||
@ -448,19 +467,24 @@ public class DataResource {
|
||||
}
|
||||
final String responseRange = String.format("bytes %d-%d/%d", from, to, file.length());
|
||||
// logger.info("responseRange: {}", responseRange);
|
||||
final RandomAccessFile raf = new RandomAccessFile(file, "r");
|
||||
raf.seek(from);
|
||||
try (final RandomAccessFile raf = new RandomAccessFile(file, "r")) {
|
||||
raf.seek(from);
|
||||
|
||||
final long len = to - from + 1;
|
||||
final MediaStreamer streamer = new MediaStreamer(len, raf);
|
||||
final Response.ResponseBuilder out = Response.ok(streamer).status(Response.Status.PARTIAL_CONTENT)
|
||||
.header("Accept-Ranges", "bytes").header("Content-Range", responseRange)
|
||||
.header(HttpHeaders.CONTENT_LENGTH, streamer.getLenth())
|
||||
.header(HttpHeaders.LAST_MODIFIED, new Date(file.lastModified()));
|
||||
if (mimeType != null) {
|
||||
out.type(mimeType);
|
||||
final long len = to - from + 1;
|
||||
final MediaStreamer streamer = new MediaStreamer(len, raf);
|
||||
final Response.ResponseBuilder out = Response.ok(streamer).status(Response.Status.PARTIAL_CONTENT)
|
||||
.header("Accept-Ranges", "bytes").header("Content-Range", responseRange)
|
||||
.header(HttpHeaders.CONTENT_LENGTH, streamer.getLenth())
|
||||
.header(HttpHeaders.LAST_MODIFIED, new Date(file.lastModified()));
|
||||
if (mimeType != null) {
|
||||
out.type(mimeType);
|
||||
}
|
||||
return out.build();
|
||||
} catch (final FileNotFoundException ex) {
|
||||
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to find the required file.", ex);
|
||||
} catch (final IOException ex) {
|
||||
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to access to the required file.", ex);
|
||||
}
|
||||
return out.build();
|
||||
}
|
||||
|
||||
public static void undelete(final Long id) throws Exception {
|
||||
|
@ -13,11 +13,12 @@ public class FailExceptionCatcher implements ExceptionMapper<FailException> {
|
||||
|
||||
@Override
|
||||
public Response toResponse(final FailException exception) {
|
||||
LOGGER.warn("Catch FailException:");
|
||||
LOGGER.warn("Catch FailException: {}", exception.getLocalizedMessage());
|
||||
final RestErrorResponse ret = build(exception);
|
||||
LOGGER.error("Error UUID={}", ret.uuid);
|
||||
// Not display backtrace ==> this may be a normal case ...
|
||||
// exception.printStackTrace();
|
||||
if (exception.exception != null) {
|
||||
exception.exception.printStackTrace();
|
||||
}
|
||||
return Response.status(exception.status).entity(ret).type(MediaType.APPLICATION_JSON).build();
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ import org.slf4j.LoggerFactory;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import jakarta.ws.rs.DefaultValue;
|
||||
import jakarta.ws.rs.InternalServerErrorException;
|
||||
|
||||
@ -797,6 +798,7 @@ public class DataAccess {
|
||||
return out;
|
||||
}
|
||||
|
||||
@SuppressFBWarnings("SQL_PREPARED_STATEMENT_GENERATED_FROM_NONCONSTANT_STRING")
|
||||
public static <T> T insert(final T data, final QueryOption... option) throws Exception {
|
||||
final Class<?> clazz = data.getClass();
|
||||
final QueryOptions options = new QueryOptions(option);
|
||||
@ -903,7 +905,7 @@ public class DataAccess {
|
||||
for (final OrderBy order : orders) {
|
||||
order.generateQuery(query, tableName);
|
||||
}
|
||||
LOGGER.warn("generate the query: '{}'", query.toString());
|
||||
LOGGER.debug("generate the query: '{}'", query.toString());
|
||||
// prepare the request:
|
||||
final PreparedStatement ps = entry.connection.prepareStatement(query.toString(),
|
||||
Statement.RETURN_GENERATED_KEYS);
|
||||
@ -1028,7 +1030,7 @@ public class DataAccess {
|
||||
}
|
||||
|
||||
public static <ID_TYPE> QueryCondition getTableIdCondition(final Class<?> clazz, final ID_TYPE idKey)
|
||||
throws Exception {
|
||||
throws DataAccessException {
|
||||
// Find the ID field type ....
|
||||
final Field idField = AnnotationTools.getIdField(clazz);
|
||||
if (idField == null) {
|
||||
@ -1115,6 +1117,7 @@ public class DataAccess {
|
||||
return updateWhere(data, options);
|
||||
}
|
||||
|
||||
@SuppressFBWarnings("SQL_PREPARED_STATEMENT_GENERATED_FROM_NONCONSTANT_STRING")
|
||||
public static <T> int updateWhere(final T data, QueryOptions options) throws Exception {
|
||||
final Class<?> clazz = data.getClass();
|
||||
if (options == null) {
|
||||
@ -1196,41 +1199,41 @@ public class DataAccess {
|
||||
if (!firstField) {
|
||||
LOGGER.debug("generate update query: '{}'", query.toString());
|
||||
// prepare the request:
|
||||
final PreparedStatement ps = entry.connection.prepareStatement(query.toString(),
|
||||
Statement.RETURN_GENERATED_KEYS);
|
||||
final CountInOut iii = new CountInOut(1);
|
||||
for (final Field field : clazz.getFields()) {
|
||||
// static field is only for internal global declaration ==> remove it ..
|
||||
if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
final String name = AnnotationTools.getFieldName(field);
|
||||
if (!filter.getValues().contains(name)) {
|
||||
continue;
|
||||
} else if (AnnotationTools.isGenericField(field)) {
|
||||
continue;
|
||||
}
|
||||
final DataAccessAddOn addOn = findAddOnforField(field);
|
||||
if (addOn != null && !addOn.canInsert(field)) {
|
||||
continue;
|
||||
}
|
||||
if (addOn == null) {
|
||||
final Class<?> type = field.getType();
|
||||
if (!type.isPrimitive()) {
|
||||
final Object tmp = field.get(data);
|
||||
if (tmp == null && field.getDeclaredAnnotationsByType(DefaultValue.class).length != 0) {
|
||||
continue;
|
||||
}
|
||||
try (final PreparedStatement ps = entry.connection.prepareStatement(query.toString(),
|
||||
Statement.RETURN_GENERATED_KEYS)) {
|
||||
final CountInOut iii = new CountInOut(1);
|
||||
for (final Field field : clazz.getFields()) {
|
||||
// static field is only for internal global declaration ==> remove it ..
|
||||
if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
final String name = AnnotationTools.getFieldName(field);
|
||||
if (!filter.getValues().contains(name)) {
|
||||
continue;
|
||||
} else if (AnnotationTools.isGenericField(field)) {
|
||||
continue;
|
||||
}
|
||||
final DataAccessAddOn addOn = findAddOnforField(field);
|
||||
if (addOn != null && !addOn.canInsert(field)) {
|
||||
continue;
|
||||
}
|
||||
if (addOn == null) {
|
||||
final Class<?> type = field.getType();
|
||||
if (!type.isPrimitive()) {
|
||||
final Object tmp = field.get(data);
|
||||
if (tmp == null && field.getDeclaredAnnotationsByType(DefaultValue.class).length != 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
setValuedb(type, data, iii, field, ps);
|
||||
} else {
|
||||
addOn.insertData(ps, field, data, iii);
|
||||
}
|
||||
setValuedb(type, data, iii, field, ps);
|
||||
} else {
|
||||
addOn.insertData(ps, field, data, iii);
|
||||
}
|
||||
condition.injectQuery(ps, iii);
|
||||
final int out = ps.executeUpdate();
|
||||
return out;
|
||||
}
|
||||
condition.injectQuery(ps, iii);
|
||||
final int out = ps.executeUpdate();
|
||||
ps.close();
|
||||
return out;
|
||||
}
|
||||
} catch (final SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
@ -1294,16 +1297,18 @@ public class DataAccess {
|
||||
throws SQLException, IOException {
|
||||
final QueryOptions options = new QueryOptions(option);
|
||||
final DBEntry entry = DBInterfaceOption.getAutoEntry(options);
|
||||
final Statement stmt = entry.connection.createStatement();
|
||||
return stmt.executeUpdate(query);
|
||||
try (final Statement stmt = entry.connection.createStatement()) {
|
||||
return stmt.executeUpdate(query);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean executeQuery(final String query, final QueryOption... option)
|
||||
throws SQLException, IOException {
|
||||
final QueryOptions options = new QueryOptions(option);
|
||||
final DBEntry entry = DBInterfaceOption.getAutoEntry(options);
|
||||
final Statement stmt = entry.connection.createStatement();
|
||||
return stmt.execute(query);
|
||||
try (final Statement stmt = entry.connection.createStatement()) {
|
||||
return stmt.execute(query);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T getWhere(final Class<T> clazz, final QueryOptions options) throws Exception {
|
||||
@ -1395,14 +1400,13 @@ public class DataAccess {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> List<T> getsWhere(final Class<T> clazz, final QueryOptions options) throws Exception {
|
||||
public static <T> List<T> getsWhere(final Class<T> clazz, final QueryOptions options)
|
||||
throws DataAccessException, IOException {
|
||||
final Condition condition = conditionFusionOrEmpty(options, false);
|
||||
final List<LazyGetter> lazyCall = new ArrayList<>();
|
||||
final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
|
||||
final DBEntry entry = DBInterfaceOption.getAutoEntry(options);
|
||||
final List<T> outs = new ArrayList<>();
|
||||
// real add in the BDD:
|
||||
try {
|
||||
try (final DBEntry entry = DBInterfaceOption.getAutoEntry(options)) {
|
||||
final CountInOut count = new CountInOut();
|
||||
final StringBuilder querySelect = new StringBuilder();
|
||||
StringBuilder query = new StringBuilder();
|
||||
@ -1430,35 +1434,35 @@ public class DataAccess {
|
||||
} else if (limits.size() > 1) {
|
||||
throw new DataAccessException("Request with multiple 'limit'...");
|
||||
}
|
||||
LOGGER.warn("generate the query: '{}'", query.toString());
|
||||
LOGGER.debug("generate the query: '{}'", query.toString());
|
||||
// prepare the request:
|
||||
final PreparedStatement ps = entry.connection.prepareStatement(query.toString(),
|
||||
Statement.RETURN_GENERATED_KEYS);
|
||||
final CountInOut iii = new CountInOut(1);
|
||||
condition.injectQuery(ps, iii);
|
||||
if (limits.size() == 1) {
|
||||
limits.get(0).injectQuery(ps, iii);
|
||||
}
|
||||
// execute the request
|
||||
final ResultSet rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
count.value = 1;
|
||||
final CountInOut countNotNull = new CountInOut(0);
|
||||
final Object data = createObjectFromSQLRequest(rs, clazz, count, countNotNull, options, lazyCall);
|
||||
final T out = (T) data;
|
||||
outs.add(out);
|
||||
}
|
||||
LOGGER.info("Async calls: {}", lazyCall.size());
|
||||
for (final LazyGetter elem : lazyCall) {
|
||||
elem.doRequest();
|
||||
try (final PreparedStatement ps = entry.connection.prepareStatement(query.toString(),
|
||||
Statement.RETURN_GENERATED_KEYS)) {
|
||||
final CountInOut iii = new CountInOut(1);
|
||||
condition.injectQuery(ps, iii);
|
||||
if (limits.size() == 1) {
|
||||
limits.get(0).injectQuery(ps, iii);
|
||||
}
|
||||
// execute the request
|
||||
final ResultSet rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
count.value = 1;
|
||||
final CountInOut countNotNull = new CountInOut(0);
|
||||
final Object data = createObjectFromSQLRequest(rs, clazz, count, countNotNull, options, lazyCall);
|
||||
final T out = (T) data;
|
||||
outs.add(out);
|
||||
}
|
||||
LOGGER.info("Async calls: {}", lazyCall.size());
|
||||
for (final LazyGetter elem : lazyCall) {
|
||||
elem.doRequest();
|
||||
}
|
||||
}
|
||||
} catch (final SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
throw ex;
|
||||
throw new DataAccessException("Catch a SQL Exception: " + ex.getMessage());
|
||||
} catch (final Exception ex) {
|
||||
ex.printStackTrace();
|
||||
} finally {
|
||||
entry.close();
|
||||
throw new DataAccessException("Catch an Exception: " + ex.getMessage());
|
||||
}
|
||||
return outs;
|
||||
}
|
||||
@ -1535,7 +1539,7 @@ public class DataAccess {
|
||||
} else if (limits.size() > 1) {
|
||||
throw new DataAccessException("Request with multiple 'limit'...");
|
||||
}
|
||||
LOGGER.warn("generate the query: '{}'", query.toString());
|
||||
LOGGER.debug("generate the query: '{}'", query.toString());
|
||||
// prepare the request:
|
||||
final PreparedStatement ps = entry.connection.prepareStatement(query.toString(),
|
||||
Statement.RETURN_GENERATED_KEYS);
|
||||
@ -1672,18 +1676,18 @@ public class DataAccess {
|
||||
}
|
||||
}
|
||||
|
||||
public static <ID_TYPE> int unsetDelete(final Class<?> clazz, final ID_TYPE id) throws Exception {
|
||||
public static <ID_TYPE> int unsetDelete(final Class<?> clazz, final ID_TYPE id) throws DataAccessException {
|
||||
return unsetDeleteWhere(clazz, new Condition(getTableIdCondition(clazz, id)));
|
||||
}
|
||||
|
||||
public static <ID_TYPE> int unsetDelete(final Class<?> clazz, final ID_TYPE id, final QueryOption... option)
|
||||
throws Exception {
|
||||
throws DataAccessException {
|
||||
final QueryOptions options = new QueryOptions(option);
|
||||
options.add(new Condition(getTableIdCondition(clazz, id)));
|
||||
return unsetDeleteWhere(clazz, options.getAllArray());
|
||||
}
|
||||
|
||||
public static int unsetDeleteWhere(final Class<?> clazz, final QueryOption... option) throws Exception {
|
||||
public static int unsetDeleteWhere(final Class<?> clazz, final QueryOption... option) throws DataAccessException {
|
||||
final QueryOptions options = new QueryOptions(option);
|
||||
final Condition condition = conditionFusionOrEmpty(options, true);
|
||||
final String tableName = AnnotationTools.getTableName(clazz, options);
|
||||
@ -1691,7 +1695,12 @@ public class DataAccess {
|
||||
if (deletedFieldName == null) {
|
||||
throw new DataAccessException("The class " + clazz.getCanonicalName() + " has no deleted field");
|
||||
}
|
||||
final DBEntry entry = DBInterfaceOption.getAutoEntry(options);
|
||||
DBEntry entry;
|
||||
try {
|
||||
entry = DBInterfaceOption.getAutoEntry(options);
|
||||
} catch (final IOException ex) {
|
||||
throw new DataAccessException("Fail to connect the DB: " + ex.getMessage());
|
||||
}
|
||||
final StringBuilder query = new StringBuilder();
|
||||
query.append("UPDATE `");
|
||||
query.append(tableName);
|
||||
@ -1701,13 +1710,14 @@ public class DataAccess {
|
||||
// need to disable the deleted false because the model must be unselected to be updated.
|
||||
options.add(QueryOptions.ACCESS_DELETED_ITEMS);
|
||||
condition.whereAppendQuery(query, tableName, options, deletedFieldName);
|
||||
try {
|
||||
final PreparedStatement ps = entry.connection.prepareStatement(query.toString());
|
||||
try (final PreparedStatement ps = entry.connection.prepareStatement(query.toString())) {
|
||||
final CountInOut iii = new CountInOut(1);
|
||||
condition.injectQuery(ps, iii);
|
||||
return ps.executeUpdate();
|
||||
} finally {
|
||||
entry.close();
|
||||
} catch (final SQLException ex) {
|
||||
throw new DataAccessException("Catch SQL error:" + ex.getMessage());
|
||||
} catch (final Exception ex) {
|
||||
throw new DataAccessException("Fail to excute the SQL query:" + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1824,7 +1834,7 @@ public class DataAccess {
|
||||
} else if (limits.size() > 1) {
|
||||
throw new DataAccessException("Request with multiple 'limit'...");
|
||||
}
|
||||
LOGGER.warn("generate the query: '{}'", query.toString());
|
||||
LOGGER.debug("generate the query: '{}'", query.toString());
|
||||
// prepare the request:
|
||||
final PreparedStatement ps = entry.connection.prepareStatement(query.toString(),
|
||||
Statement.RETURN_GENERATED_KEYS);
|
||||
|
@ -4,6 +4,7 @@ import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -26,6 +27,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
@ -53,7 +55,7 @@ public class AddOnDataJson implements DataAccessAddOn {
|
||||
|
||||
@Override
|
||||
public void insertData(final PreparedStatement ps, final Field field, final Object rootObject, final CountInOut iii)
|
||||
throws Exception {
|
||||
throws IllegalArgumentException, IllegalAccessException, SQLException, JsonProcessingException {
|
||||
final Object data = field.get(rootObject);
|
||||
if (data == null) {
|
||||
ps.setNull(iii.value, Types.VARCHAR);
|
||||
@ -70,7 +72,7 @@ public class AddOnDataJson implements DataAccessAddOn {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsertAsync(final Field field) throws Exception {
|
||||
public boolean isInsertAsync(final Field field) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,34 @@
|
||||
package org.kar.archidata.exception;
|
||||
|
||||
import org.kar.archidata.api.DataResource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
public class FailException extends Exception {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DataResource.class);
|
||||
private static final long serialVersionUID = 1L;
|
||||
public final Response.Status status;
|
||||
public final Exception exception;
|
||||
|
||||
public FailException(final Response.Status status, final String message) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
this.exception = null;
|
||||
}
|
||||
|
||||
public FailException(final Response.Status status, final String message, final Exception ex) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
this.exception = ex;
|
||||
ex.printStackTrace();
|
||||
LOGGER.error("Generate Fail exception with exceptionData: {}", ex.getMessage());
|
||||
}
|
||||
|
||||
public FailException(final String message) {
|
||||
super(message);
|
||||
this.status = Response.Status.BAD_REQUEST;
|
||||
|
||||
this.exception = null;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ import org.kar.archidata.migration.model.Migration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
public class MigrationEngine {
|
||||
final static Logger LOGGER = LoggerFactory.getLogger(MigrationEngine.class);
|
||||
|
||||
@ -103,6 +105,8 @@ public class MigrationEngine {
|
||||
/** Process the automatic migration of the system
|
||||
* @param config SQL connection for the migration
|
||||
* @throws IOException Error if access on the DB */
|
||||
@SuppressFBWarnings({ "SQL_PREPARED_STATEMENT_GENERATED_FROM_NONCONSTANT_STRING",
|
||||
"SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE" })
|
||||
public void migrateErrorThrow(final DBConfig config) throws MigrationException {
|
||||
LOGGER.info("Execute migration ... [BEGIN]");
|
||||
// check the integrity of the migrations:
|
||||
|
@ -16,7 +16,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
|
||||
|
||||
@ -56,7 +55,9 @@ public class RESTApi {
|
||||
"Fail to get the data [" + httpResponse.statusCode() + "] " + httpResponse.body());
|
||||
}
|
||||
}
|
||||
return this.mapper.readValue(httpResponse.body(), new TypeReference<List<T>>() {});
|
||||
//return this.mapper.readValue(httpResponse.body(), new TypeReference<List<T>>() {});
|
||||
return this.mapper.readValue(httpResponse.body(),
|
||||
this.mapper.getTypeFactory().constructCollectionType(List.class, clazz));
|
||||
}
|
||||
|
||||
public <T> T get(final Class<T> clazz, final String urlOffset)
|
||||
@ -153,6 +154,9 @@ public class RESTApi {
|
||||
"Fail to get the ERROR data [" + httpResponse.statusCode() + "] " + httpResponse.body());
|
||||
}
|
||||
}
|
||||
if (clazz == Void.class || clazz == void.class) {
|
||||
return null;
|
||||
}
|
||||
if (clazz.equals(String.class)) {
|
||||
return (T) httpResponse.body();
|
||||
}
|
||||
@ -190,14 +194,31 @@ public class RESTApi {
|
||||
"Fail to get the data [" + httpResponse.statusCode() + "] " + httpResponse.body());
|
||||
}
|
||||
}
|
||||
if (clazz == Void.class || clazz == void.class) {
|
||||
return null;
|
||||
}
|
||||
if (clazz.equals(String.class)) {
|
||||
return (T) httpResponse.body();
|
||||
}
|
||||
return this.mapper.readValue(httpResponse.body(), clazz);
|
||||
}
|
||||
|
||||
// TODO: add an API that permit to return a value
|
||||
public <T, U> void delete(final Class<T> clazz, final String urlOffset)
|
||||
/**
|
||||
* Call a DELETE on a REST API
|
||||
* @param urlOffset Offset to call the API
|
||||
*/
|
||||
public void delete(final String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException {
|
||||
delete(Void.class, urlOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a DELETE on a REST API with retrieving some data
|
||||
* @param <T> Type of data that might be received.
|
||||
* @param clazz Class model of the data that might be parsed.
|
||||
* @param urlOffset Offset to call the API
|
||||
* @return The parsed object received.
|
||||
*/
|
||||
public <T> T delete(final Class<T> clazz, final String urlOffset)
|
||||
throws RESTErrorResponseExeption, IOException, InterruptedException {
|
||||
final HttpClient client = HttpClient.newHttpClient();
|
||||
Builder requestBuilding = HttpRequest.newBuilder().version(Version.HTTP_1_1)
|
||||
@ -217,5 +238,12 @@ public class RESTApi {
|
||||
"Fail to get the data [" + httpResponse.statusCode() + "] " + httpResponse.body());
|
||||
}
|
||||
}
|
||||
if (clazz == Void.class || clazz == void.class) {
|
||||
return null;
|
||||
}
|
||||
if (clazz.equals(String.class)) {
|
||||
return (T) httpResponse.body();
|
||||
}
|
||||
return this.mapper.readValue(httpResponse.body(), clazz);
|
||||
}
|
||||
}
|
||||
|
14
src/org/kar/archidata/tools/StringTools.java
Normal file
14
src/org/kar/archidata/tools/StringTools.java
Normal file
@ -0,0 +1,14 @@
|
||||
package org.kar.archidata.tools;
|
||||
|
||||
public class StringTools {
|
||||
public static String RandGeneratedStr(final int length) {
|
||||
final String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvxyz0123456789éàê_- '()";
|
||||
final StringBuilder out = new StringBuilder(length);
|
||||
for (int iii = 0; iii < length; iii++) {
|
||||
final int chId = (int) (base.length() * Math.random());
|
||||
out.append(base.charAt(chId));
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
}
|
@ -1 +1 @@
|
||||
0.10.3
|
||||
0.11.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user