diff --git a/.checkstyle b/.checkstyle
new file mode 100644
index 0000000..5783bc0
--- /dev/null
+++ b/.checkstyle
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.classpath b/.classpath
index 6c8fcb3..ccfe345 100644
--- a/.classpath
+++ b/.classpath
@@ -8,36 +8,20 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
+
+
+
+
+
+
diff --git a/conditioningUnit b/conditioningUnit
new file mode 100644
index 0000000..0637a08
--- /dev/null
+++ b/conditioningUnit
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index b6f3a1b..9949de5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
4.0.0
kangaroo-and-rabbit
archidata
- 0.3.8
+ 0.4.0
3.1.1
2.3.1
@@ -130,6 +130,17 @@
nimbus-jose-jwt
9.30
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.7.2
+ test
+
+
+ jakarta.persistence
+ jakarta.persistence-api
+ 3.1.0
+
diff --git a/src/org/kar/archidata/GlobalConfiguration.java b/src/org/kar/archidata/GlobalConfiguration.java
index eb3bab0..44024cc 100644
--- a/src/org/kar/archidata/GlobalConfiguration.java
+++ b/src/org/kar/archidata/GlobalConfiguration.java
@@ -16,3 +16,4 @@ public class GlobalConfiguration {
ConfigBaseVariable.getDBKeepConnected());
}
}
+
\ No newline at end of file
diff --git a/src/org/kar/archidata/UpdateJwtPublicKey.java b/src/org/kar/archidata/UpdateJwtPublicKey.java
index d4efdb0..d77dee3 100644
--- a/src/org/kar/archidata/UpdateJwtPublicKey.java
+++ b/src/org/kar/archidata/UpdateJwtPublicKey.java
@@ -5,14 +5,15 @@ import org.kar.archidata.util.JWTWrapper;
public class UpdateJwtPublicKey extends Thread {
boolean kill = false;
+
public void run() {
if (ConfigBaseVariable.getSSOAddress() == null) {
System.out.println("SSO INTERFACE is not provided ==> work alone.");
// No SO provided, kill the thread.
return;
}
- while (this.kill == false) {
- // need to upgrade when server call us...
+ while (this.kill == false) {
+ // need to upgrade when server call us...
try {
JWTWrapper.initLocalTokenRemote(ConfigBaseVariable.getSSOAddress(), "archidata");
} catch (Exception e1) {
@@ -22,12 +23,13 @@ public class UpdateJwtPublicKey extends Thread {
}
try {
// update every 5 minutes the master token
- Thread.sleep(1000*60*5, 0);
+ Thread.sleep(1000 * 60 * 5, 0);
} catch (InterruptedException e) {
e.printStackTrace();
}
- }
+ }
}
+
public void kill() {
this.kill = true;
}
diff --git a/src/org/kar/archidata/UserDB.java b/src/org/kar/archidata/UserDB.java
index a082861..326ec0c 100755
--- a/src/org/kar/archidata/UserDB.java
+++ b/src/org/kar/archidata/UserDB.java
@@ -1,45 +1,43 @@
package org.kar.archidata;
-import org.kar.archidata.db.DBEntry;
-import org.kar.archidata.model.User;
-import org.kar.archidata.sqlWrapper.SqlWrapper;
-
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.SQLException;
+import org.kar.archidata.db.DBEntry;
+import org.kar.archidata.model.User;
+import org.kar.archidata.sqlWrapper.SqlWrapper;
+
public class UserDB {
-
- public UserDB() {
- }
-
- public static User getUsers(long userId) throws Exception {
- return SqlWrapper.get(User.class, userId);
- }
-
-
- public static User getUserOrCreate(long userId, String userLogin) throws Exception {
- User user = getUsers(userId);
- if (user != null) {
- return user;
- }
- createUsersInfoFromOAuth(userId, userLogin);
- return getUsers(userId);
- }
-
- private static void createUsersInfoFromOAuth(long userId, String login) throws IOException {
- DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
- String query = "INSERT INTO `user` (`id`, `login`, `lastConnection`, `admin`, `blocked`, `removed`) VALUE (?,?,now(3),'0','0','0')";
- try {
- PreparedStatement ps = entry.connection.prepareStatement(query);
- ps.setLong(1, userId);
- ps.setString(2, login);
- ps.executeUpdate();
- } catch (SQLException throwables) {
- throwables.printStackTrace();
- } finally {
- entry.close();
- }
- }
-
+
+ public UserDB() {}
+
+ public static User getUsers(long userId) throws Exception {
+ return SqlWrapper.get(User.class, userId);
+ }
+
+ public static User getUserOrCreate(long userId, String userLogin) throws Exception {
+ User user = getUsers(userId);
+ if (user != null) {
+ return user;
+ }
+ createUsersInfoFromOAuth(userId, userLogin);
+ return getUsers(userId);
+ }
+
+ private static void createUsersInfoFromOAuth(long userId, String login) throws IOException {
+ DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
+ String query = "INSERT INTO `user` (`id`, `login`, `lastConnection`, `admin`, `blocked`, `removed`) VALUE (?,?,now(3),'0','0','0')";
+ try {
+ PreparedStatement ps = entry.connection.prepareStatement(query);
+ ps.setLong(1, userId);
+ ps.setString(2, login);
+ ps.executeUpdate();
+ } catch (SQLException throwables) {
+ throwables.printStackTrace();
+ } finally {
+ entry.close();
+ }
+ }
+
}
diff --git a/src/org/kar/archidata/annotation/AnnotationTools.java b/src/org/kar/archidata/annotation/AnnotationTools.java
new file mode 100644
index 0000000..afc0b32
--- /dev/null
+++ b/src/org/kar/archidata/annotation/AnnotationTools.java
@@ -0,0 +1,129 @@
+package org.kar.archidata.annotation;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Table;
+
+public class AnnotationTools {
+ static final Logger LOGGER = LoggerFactory.getLogger(AnnotationTools.class);
+
+ public static String getTableName(final Class> element) throws Exception {
+ final Annotation[] annotation = element.getDeclaredAnnotationsByType(Table.class);
+ if (annotation.length == 0) {
+ return null;
+ }
+ if (annotation.length > 1) {
+ throw new Exception("Must not have more than 1 element @SQLTableName on " + element.getClass().getCanonicalName());
+ }
+ final String tmp = ((Table) annotation[0]).name();
+ if (tmp == null) {
+ return null;
+ }
+ return tmp;
+ }
+
+ public static String getComment(final Field element) throws Exception {
+ final Annotation[] annotation = element.getDeclaredAnnotationsByType(SQLComment.class);
+ if (annotation.length == 0) {
+ return null;
+ }
+ if (annotation.length > 1) {
+ throw new Exception("Must not have more than 1 element @SQLComment on " + element.getClass().getCanonicalName());
+ }
+ final String tmp = ((SQLComment) annotation[0]).value();
+ if (tmp == null) {
+ return null;
+ }
+ return tmp;
+ }
+
+ public static String getDefault(final Field element) throws Exception {
+ final Annotation[] annotation = element.getDeclaredAnnotationsByType(SQLDefault.class);
+ if (annotation.length == 0) {
+ return null;
+ }
+ if (annotation.length > 1) {
+ throw new Exception("Must not have more than 1 element @SQLDefault on " + element.getClass().getCanonicalName());
+ }
+ final String tmp = ((SQLDefault) annotation[0]).value();
+ if (tmp == null) {
+ return null;
+ }
+ return tmp;
+ }
+
+ public static Integer getLimitSize(final Field element) throws Exception {
+ final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class);
+ if (annotation.length == 0) {
+ return null;
+ }
+ if (annotation.length > 1) {
+ throw new Exception("Must not have more than 1 element @SQLLimitSize on " + element.getClass().getCanonicalName());
+ }
+ return ((Column) annotation[0]).length();
+ }
+
+ public static boolean isAnnotationGroup(final Field field, final Class> annotationType) {
+ try {
+ final Annotation[] anns = field.getAnnotations();
+ for (final Annotation ann : anns) {
+ if (ann.annotationType() == annotationType) {
+ return true;
+ }
+ }
+ for (final Annotation ann : anns) {
+ final Annotation[] anns2 = ann.annotationType().getDeclaredAnnotations();
+ for (final Annotation ann2 : anns2) {
+ if (ann2.annotationType() == annotationType) {
+ return true;
+ }
+ }
+ }
+ } catch (final Exception ex) {
+ LOGGER.error("Catch exception when try to get annotation...{}", ex.getLocalizedMessage());
+ return false;
+ }
+ return false;
+ }
+
+ public static boolean getNotNull(final Field element) throws Exception {
+ final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class);
+ if (annotation.length == 0) {
+ return true;
+ }
+ if (annotation.length > 1) {
+ throw new Exception("Must not have more than 1 element @Column on " + element.getClass().getCanonicalName());
+ }
+ return ((Column) annotation[0]).nullable();
+ }
+
+ public static boolean isPrimaryKey(final Field element) throws Exception {
+ final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class);
+ if (annotation.length == 0) {
+ return true;
+ }
+ if (annotation.length > 1) {
+ throw new Exception("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 {
+ final Annotation[] annotation = element.getDeclaredAnnotationsByType(GeneratedValue.class);
+ if (annotation.length == 0) {
+ return null;
+ }
+ if (annotation.length > 1) {
+ throw new Exception("Must not have more than 1 element @Column on " + element.getClass().getCanonicalName());
+ }
+ return ((GeneratedValue) annotation[0]).strategy();
+ }
+
+}
diff --git a/src/org/kar/archidata/annotation/SQLCreateTime.java b/src/org/kar/archidata/annotation/CreationTimestamp.java
similarity index 86%
rename from src/org/kar/archidata/annotation/SQLCreateTime.java
rename to src/org/kar/archidata/annotation/CreationTimestamp.java
index 51dfdec..ac04d4f 100644
--- a/src/org/kar/archidata/annotation/SQLCreateTime.java
+++ b/src/org/kar/archidata/annotation/CreationTimestamp.java
@@ -7,6 +7,6 @@ import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
-public @interface SQLCreateTime {
-
+public @interface CreationTimestamp {
+
}
diff --git a/src/org/kar/archidata/annotation/SQLPrimaryKey.java b/src/org/kar/archidata/annotation/SQLAddOn.java
similarity index 77%
rename from src/org/kar/archidata/annotation/SQLPrimaryKey.java
rename to src/org/kar/archidata/annotation/SQLAddOn.java
index 60944cf..c1c5037 100644
--- a/src/org/kar/archidata/annotation/SQLPrimaryKey.java
+++ b/src/org/kar/archidata/annotation/SQLAddOn.java
@@ -5,8 +5,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-@Target(ElementType.FIELD)
+@Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME)
-public @interface SQLPrimaryKey {
-
+public @interface SQLAddOn {
+
}
diff --git a/src/org/kar/archidata/annotation/SQLComment.java b/src/org/kar/archidata/annotation/SQLComment.java
index 9bfa21f..e05df17 100644
--- a/src/org/kar/archidata/annotation/SQLComment.java
+++ b/src/org/kar/archidata/annotation/SQLComment.java
@@ -8,7 +8,7 @@ import java.lang.annotation.Target;
@Target({ ElementType.TYPE, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLComment {
-
+
String value();
-
+
}
diff --git a/src/org/kar/archidata/annotation/SQLDefault.java b/src/org/kar/archidata/annotation/SQLDefault.java
index ec88f2e..fd96353 100644
--- a/src/org/kar/archidata/annotation/SQLDefault.java
+++ b/src/org/kar/archidata/annotation/SQLDefault.java
@@ -8,7 +8,7 @@ import java.lang.annotation.Target;
@Target({ ElementType.TYPE, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLDefault {
-
+
String value();
-
+
}
diff --git a/src/org/kar/archidata/annotation/SQLDeleted.java b/src/org/kar/archidata/annotation/SQLDeleted.java
index 681700a..84f0359 100644
--- a/src/org/kar/archidata/annotation/SQLDeleted.java
+++ b/src/org/kar/archidata/annotation/SQLDeleted.java
@@ -8,5 +8,5 @@ import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLDeleted {
-
+
}
diff --git a/src/org/kar/archidata/annotation/SQLIfNotExists.java b/src/org/kar/archidata/annotation/SQLIfNotExists.java
index 9b185d6..68b4590 100644
--- a/src/org/kar/archidata/annotation/SQLIfNotExists.java
+++ b/src/org/kar/archidata/annotation/SQLIfNotExists.java
@@ -8,5 +8,5 @@ import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLIfNotExists {
-
+
}
diff --git a/src/org/kar/archidata/annotation/SQLLimitSize.java b/src/org/kar/archidata/annotation/SQLLimitSize.java
deleted file mode 100644
index 5ed10c4..0000000
--- a/src/org/kar/archidata/annotation/SQLLimitSize.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.kar.archidata.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Target(ElementType.FIELD)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface SQLLimitSize {
- int value();
-}
diff --git a/src/org/kar/archidata/annotation/SQLNotRead.java b/src/org/kar/archidata/annotation/SQLNotRead.java
index 50bb67b..a67bd72 100644
--- a/src/org/kar/archidata/annotation/SQLNotRead.java
+++ b/src/org/kar/archidata/annotation/SQLNotRead.java
@@ -8,5 +8,5 @@ import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLNotRead {
-
+
}
diff --git a/src/org/kar/archidata/annotation/SQLTableName.java b/src/org/kar/archidata/annotation/SQLTableName.java
deleted file mode 100644
index 5902edc..0000000
--- a/src/org/kar/archidata/annotation/SQLTableName.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.kar.archidata.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface SQLTableName {
-
- String value();
-
-}
diff --git a/src/org/kar/archidata/annotation/SQLUpdateTime.java b/src/org/kar/archidata/annotation/SQLUpdateTime.java
deleted file mode 100644
index fe2ecad..0000000
--- a/src/org/kar/archidata/annotation/SQLUpdateTime.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.kar.archidata.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Target(ElementType.FIELD)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface SQLUpdateTime {
-
-}
diff --git a/src/org/kar/archidata/annotation/SQLAutoIncrement.java b/src/org/kar/archidata/annotation/UpdateTimestamp.java
similarity index 87%
rename from src/org/kar/archidata/annotation/SQLAutoIncrement.java
rename to src/org/kar/archidata/annotation/UpdateTimestamp.java
index 8c22c7d..ec980a5 100644
--- a/src/org/kar/archidata/annotation/SQLAutoIncrement.java
+++ b/src/org/kar/archidata/annotation/UpdateTimestamp.java
@@ -7,6 +7,6 @@ import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
-public @interface SQLAutoIncrement {
-
+public @interface UpdateTimestamp {
+
}
diff --git a/src/org/kar/archidata/annotation/SQLNotNull.java b/src/org/kar/archidata/annotation/addOn/SQLTableExternalForeinKeyAsList.java
similarity index 59%
rename from src/org/kar/archidata/annotation/SQLNotNull.java
rename to src/org/kar/archidata/annotation/addOn/SQLTableExternalForeinKeyAsList.java
index 07a20aa..7fc59cf 100644
--- a/src/org/kar/archidata/annotation/SQLNotNull.java
+++ b/src/org/kar/archidata/annotation/addOn/SQLTableExternalForeinKeyAsList.java
@@ -1,12 +1,15 @@
-package org.kar.archidata.annotation;
+package org.kar.archidata.annotation.addOn;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import org.kar.archidata.annotation.SQLAddOn;
+
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
-public @interface SQLNotNull {
-
+@SQLAddOn
+public @interface SQLTableExternalForeinKeyAsList {
+
}
diff --git a/src/org/kar/archidata/annotation/SQLTableLinkGeneric.java b/src/org/kar/archidata/annotation/addOn/SQLTableExternalLink.java
similarity index 65%
rename from src/org/kar/archidata/annotation/SQLTableLinkGeneric.java
rename to src/org/kar/archidata/annotation/addOn/SQLTableExternalLink.java
index e2cbcc6..94bb6fb 100644
--- a/src/org/kar/archidata/annotation/SQLTableLinkGeneric.java
+++ b/src/org/kar/archidata/annotation/addOn/SQLTableExternalLink.java
@@ -1,32 +1,28 @@
-package org.kar.archidata.annotation;
+package org.kar.archidata.annotation.addOn;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-
-
+import org.kar.archidata.annotation.SQLAddOn;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
-public @interface SQLTableLinkGeneric {
- public static String AUTOMATIC ="__auto__";
- public enum ModelLink {
- NONE,
- INTERNAL, // The list is serialized in a string ',' separated
- EXTERNAL // an external table is created and
- };
- // Permit to select the link mode.
- ModelLink value() default ModelLink.EXTERNAL;
- // If automatic table name, the table name is: parentTableName_externalTableName__link
+@SQLAddOn
+public @interface SQLTableExternalLink {
+ public static String AUTOMATIC = "__auto__";
+
+ // If automatic table name, the table name is: parentTableName_externalTableName__link
String tableName() default AUTOMATIC;
+
// If automatic table name, the name of the foreign table is manage with the variable name.
String externalTableName() default AUTOMATIC;
+
// If the external link have a field to filter with a specific value (name of the field)
String filterField() default AUTOMATIC;
+
// If the external link have a field to filter with a specific value (value of the field)
String filterValue() default AUTOMATIC;
-
}
diff --git a/src/org/kar/archidata/annotation/security/DenyAll.java b/src/org/kar/archidata/annotation/security/DenyAll.java
index ede47ab..f5253df 100644
--- a/src/org/kar/archidata/annotation/security/DenyAll.java
+++ b/src/org/kar/archidata/annotation/security/DenyAll.java
@@ -1,15 +1,14 @@
package org.kar.archidata.annotation.security;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import jakarta.ws.rs.NameBinding;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
@NameBinding
@Retention(RUNTIME)
-@Target({METHOD})
-public @interface DenyAll {
-}
+@Target({ METHOD })
+public @interface DenyAll {}
diff --git a/src/org/kar/archidata/annotation/security/PermitAll.java b/src/org/kar/archidata/annotation/security/PermitAll.java
index ea5e210..7077eb9 100644
--- a/src/org/kar/archidata/annotation/security/PermitAll.java
+++ b/src/org/kar/archidata/annotation/security/PermitAll.java
@@ -1,14 +1,14 @@
package org.kar.archidata.annotation.security;
-import jakarta.ws.rs.NameBinding;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import jakarta.ws.rs.NameBinding;
+
@NameBinding
@Retention(RUNTIME)
-@Target({METHOD})
-public @interface PermitAll {
-}
+@Target({ METHOD })
+public @interface PermitAll {}
diff --git a/src/org/kar/archidata/annotation/security/PermitTokenInURI.java b/src/org/kar/archidata/annotation/security/PermitTokenInURI.java
index f1f6404..62f43d8 100644
--- a/src/org/kar/archidata/annotation/security/PermitTokenInURI.java
+++ b/src/org/kar/archidata/annotation/security/PermitTokenInURI.java
@@ -1,14 +1,14 @@
package org.kar.archidata.annotation.security;
-import jakarta.ws.rs.NameBinding;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import jakarta.ws.rs.NameBinding;
+
@NameBinding
@Retention(RUNTIME)
-@Target({METHOD})
-public @interface PermitTokenInURI {
-}
+@Target({ METHOD })
+public @interface PermitTokenInURI {}
diff --git a/src/org/kar/archidata/annotation/security/RolesAllowed.java b/src/org/kar/archidata/annotation/security/RolesAllowed.java
index 9cb18be..662f11a 100644
--- a/src/org/kar/archidata/annotation/security/RolesAllowed.java
+++ b/src/org/kar/archidata/annotation/security/RolesAllowed.java
@@ -1,15 +1,16 @@
package org.kar.archidata.annotation.security;
-import jakarta.ws.rs.NameBinding;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import jakarta.ws.rs.NameBinding;
+
@NameBinding
@Retention(RUNTIME)
-@Target({METHOD})
+@Target({ METHOD })
public @interface RolesAllowed {
String[] value();
}
diff --git a/src/org/kar/archidata/api/DataResource.java b/src/org/kar/archidata/api/DataResource.java
index 8a696c9..8db3e2a 100644
--- a/src/org/kar/archidata/api/DataResource.java
+++ b/src/org/kar/archidata/api/DataResource.java
@@ -1,12 +1,32 @@
package org.kar.archidata.api;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Date;
+
+import javax.imageio.ImageIO;
+
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
-import org.kar.archidata.filter.GenericContext;
-import org.kar.archidata.model.Data;
-import org.kar.archidata.sqlWrapper.SqlWrapper;
import org.kar.archidata.annotation.security.PermitTokenInURI;
import org.kar.archidata.annotation.security.RolesAllowed;
+import org.kar.archidata.filter.GenericContext;
+import org.kar.archidata.model.Data;
+import org.kar.archidata.sqlWrapper.QuerryCondition;
+import org.kar.archidata.sqlWrapper.SqlWrapper;
import org.kar.archidata.util.ConfigBaseVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -28,413 +48,376 @@ import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.SecurityContext;
import jakarta.ws.rs.core.StreamingOutput;
-import javax.imageio.ImageIO;
-import java.awt.*;
-import java.awt.image.BufferedImage;
-import java.io.*;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Date;
-
-
// https://stackoverflow.com/questions/35367113/jersey-webservice-scalable-approach-to-download-file-and-reply-to-client
// https://gist.github.com/aitoroses/4f7a2b197b732a6a691d
@Path("/data")
@Produces(MediaType.APPLICATION_JSON)
public class DataResource {
- static final Logger logger = LoggerFactory.getLogger(MediaType.class);
- private final static int CHUNK_SIZE = 1024 * 1024; // 1MB chunks
- private final static int CHUNK_SIZE_IN = 50 * 1024 * 1024; // 1MB chunks
- /**
- * Upload some datas
- */
- private static long tmpFolderId = 1;
-
- private static void createFolder(String path) throws IOException {
- if (!Files.exists(java.nio.file.Path.of(path))) {
- //Log.print("Create folder: " + path);
- Files.createDirectories(java.nio.file.Path.of(path));
- }
- }
-
- public static long getTmpDataId() {
- return tmpFolderId++;
- }
-
- public static String getTmpFileInData(long tmpFolderId) {
- String filePath = ConfigBaseVariable.getTmpDataFolder() + File.separator + tmpFolderId;
- try {
- createFolder(ConfigBaseVariable.getTmpDataFolder() + File.separator);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return filePath;
- }
-
- public static String getFileData(long tmpFolderId) {
- String filePath = ConfigBaseVariable.getMediaDataFolder() + File.separator + tmpFolderId + File.separator + "data";
- try {
- createFolder(ConfigBaseVariable.getMediaDataFolder() + File.separator + tmpFolderId + File.separator);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return filePath;
- }
-
- public static Data getWithSha512(String sha512) {
- logger.info("find sha512 = {}", sha512);
- try {
- return SqlWrapper.getWhere(Data.class, "sha512", "=", sha512);
+ private static final Logger LOGGER = LoggerFactory.getLogger(MediaType.class);
+ private final static int CHUNK_SIZE = 1024 * 1024; // 1MB chunks
+ private final static int CHUNK_SIZE_IN = 50 * 1024 * 1024; // 1MB chunks
+ /**
+ * Upload some datas
+ */
+ private static long tmpFolderId = 1;
+
+ private static void createFolder(String path) throws IOException {
+ if (!Files.exists(java.nio.file.Path.of(path))) {
+ //Log.print("Create folder: " + path);
+ Files.createDirectories(java.nio.file.Path.of(path));
+ }
+ }
+
+ public static long getTmpDataId() {
+ return tmpFolderId++;
+ }
+
+ public static String getTmpFileInData(long tmpFolderId) {
+ String filePath = ConfigBaseVariable.getTmpDataFolder() + File.separator + tmpFolderId;
+ try {
+ createFolder(ConfigBaseVariable.getTmpDataFolder() + File.separator);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return filePath;
+ }
+
+ public static String getFileData(long tmpFolderId) {
+ String filePath = ConfigBaseVariable.getMediaDataFolder() + File.separator + tmpFolderId + File.separator + "data";
+ try {
+ createFolder(ConfigBaseVariable.getMediaDataFolder() + File.separator + tmpFolderId + File.separator);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return filePath;
+ }
+
+ public static Data getWithSha512(String sha512) {
+ LOGGER.info("find sha512 = {}", sha512);
+ try {
+ return SqlWrapper.getWhere(Data.class, new QuerryCondition("sha512", "=", sha512));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
- return null;
- }
-
- public static Data getWithId(long id) {
- logger.info("find id = {}", id);
- try {
+ return null;
+ }
+
+ public static Data getWithId(long id) {
+ LOGGER.info("find id = {}", id);
+ try {
return SqlWrapper.get(Data.class, id);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
- return null;
- }
-
- public static Data createNewData(long tmpUID, String originalFileName, String sha512) throws IOException {
- // determine mime type:
- Data injectedData = new Data();
- String mimeType = "";
- String extension = originalFileName.substring(originalFileName.lastIndexOf('.') + 1);
- switch (extension.toLowerCase()) {
- case "jpg":
- case "jpeg":
- mimeType = "image/jpeg";
- break;
- case "png":
- mimeType = "image/png";
- break;
- case "webp":
- mimeType = "image/webp";
- break;
- case "mka":
- mimeType = "audio/x-matroska";
- break;
- case "mkv":
- mimeType = "video/x-matroska";
- break;
- case "webm":
- mimeType = "video/webm";
- break;
- default:
- throw new IOException("Can not find the mime type of data input: '" + extension + "'");
- }
- injectedData.mimeType = mimeType;
- injectedData.sha512 = sha512;
- String tmpPath = getTmpFileInData(tmpUID);
- injectedData.size = Files.size(Paths.get(tmpPath));
-
- try {
- injectedData = SqlWrapper.insert(injectedData);
+ return null;
+ }
+
+ public static Data createNewData(long tmpUID, String originalFileName, String sha512) throws IOException {
+ // determine mime type:
+ Data injectedData = new Data();
+ String mimeType = "";
+ String extension = originalFileName.substring(originalFileName.lastIndexOf('.') + 1);
+ switch (extension.toLowerCase()) {
+ case "jpg":
+ case "jpeg":
+ mimeType = "image/jpeg";
+ break;
+ case "png":
+ mimeType = "image/png";
+ break;
+ case "webp":
+ mimeType = "image/webp";
+ break;
+ case "mka":
+ mimeType = "audio/x-matroska";
+ break;
+ case "mkv":
+ mimeType = "video/x-matroska";
+ break;
+ case "webm":
+ mimeType = "video/webm";
+ break;
+ default:
+ throw new IOException("Can not find the mime type of data input: '" + extension + "'");
+ }
+ injectedData.mimeType = mimeType;
+ injectedData.sha512 = sha512;
+ String tmpPath = getTmpFileInData(tmpUID);
+ injectedData.size = Files.size(Paths.get(tmpPath));
+
+ try {
+ injectedData = SqlWrapper.insert(injectedData);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
- String mediaPath = getFileData(injectedData.id);
- logger.info("src = {}", tmpPath);
- logger.info("dst = {}", mediaPath);
- Files.move(Paths.get(tmpPath), Paths.get(mediaPath), StandardCopyOption.ATOMIC_MOVE);
- logger.info("Move done");
- return injectedData;
- }
-
- public static String saveTemporaryFile(InputStream uploadedInputStream, long idData) {
- return saveFile(uploadedInputStream, DataResource.getTmpFileInData(idData));
- }
-
- public static void removeTemporaryFile(long idData) {
- String filepath = DataResource.getTmpFileInData(idData);
- if (Files.exists(Paths.get(filepath))) {
- try {
- Files.delete(Paths.get(filepath));
- } catch (IOException e) {
- logger.info("can not delete temporary file : {}", Paths.get(filepath));
- e.printStackTrace();
- }
- }
- }
-
- // save uploaded file to a defined location on the server
- static String saveFile(InputStream uploadedInputStream, String serverLocation) {
- String out = "";
- try {
- OutputStream outpuStream = new FileOutputStream(new File(
- serverLocation));
- int read = 0;
- byte[] bytes = new byte[CHUNK_SIZE_IN];
- 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
- byte[] sha512Digest = md.digest();
- // convert in hexadecimal
- out = bytesToHex(sha512Digest);
- uploadedInputStream.close();
- } catch (IOException ex) {
- logger.info("Can not write in temporary file ... ");
- ex.printStackTrace();
- } catch (NoSuchAlgorithmException ex) {
- logger.info("Can not find sha512 algorithms");
- ex.printStackTrace();
- }
- return out;
- }
-
- public static String bytesToHex(byte[] bytes) {
- StringBuilder sb = new StringBuilder();
- for (byte b : bytes) {
- sb.append(String.format("%02x", b));
- }
- return sb.toString();
- }
-
-
- public Data getSmall(Long id) {
- try {
+ String mediaPath = getFileData(injectedData.id);
+ LOGGER.info("src = {}", tmpPath);
+ LOGGER.info("dst = {}", mediaPath);
+ Files.move(Paths.get(tmpPath), Paths.get(mediaPath), StandardCopyOption.ATOMIC_MOVE);
+ LOGGER.info("Move done");
+ return injectedData;
+ }
+
+ public static String saveTemporaryFile(InputStream uploadedInputStream, long idData) {
+ return saveFile(uploadedInputStream, DataResource.getTmpFileInData(idData));
+ }
+
+ public static void removeTemporaryFile(long idData) {
+ String filepath = DataResource.getTmpFileInData(idData);
+ if (Files.exists(Paths.get(filepath))) {
+ try {
+ Files.delete(Paths.get(filepath));
+ } catch (IOException e) {
+ LOGGER.info("can not delete temporary file : {}", Paths.get(filepath));
+ e.printStackTrace();
+ }
+ }
+ }
+
+ // save uploaded file to a defined location on the server
+ static String saveFile(InputStream uploadedInputStream, String serverLocation) {
+ String out = "";
+ try {
+ OutputStream outpuStream = new FileOutputStream(new File(serverLocation));
+ int read = 0;
+ byte[] bytes = new byte[CHUNK_SIZE_IN];
+ 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
+ byte[] sha512Digest = md.digest();
+ // convert in hexadecimal
+ out = bytesToHex(sha512Digest);
+ uploadedInputStream.close();
+ } catch (IOException ex) {
+ LOGGER.info("Can not write in temporary file ... ");
+ ex.printStackTrace();
+ } catch (NoSuchAlgorithmException ex) {
+ LOGGER.info("Can not find sha512 algorithms");
+ ex.printStackTrace();
+ }
+ return out;
+ }
+
+ public static String bytesToHex(byte[] bytes) {
+ StringBuilder sb = new StringBuilder();
+ for (byte b : bytes) {
+ sb.append(String.format("%02x", b));
+ }
+ return sb.toString();
+ }
+
+ public Data getSmall(Long id) {
+ try {
return SqlWrapper.get(Data.class, id);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
- return null;
- }
-
- @POST
- @Path("/upload/")
- @Consumes({MediaType.MULTIPART_FORM_DATA})
- @RolesAllowed("ADMIN")
- public Response uploadFile(@Context SecurityContext sc, @FormDataParam("file") InputStream fileInputStream, @FormDataParam("file") FormDataContentDisposition fileMetaData) {
- GenericContext gc = (GenericContext) sc.getUserPrincipal();
- logger.info("===================================================");
- logger.info("== DATA uploadFile {}", (gc==null?"null":gc.userByToken));
- logger.info("===================================================");
- //public NodeSmall uploadFile(final FormDataMultiPart form) {
- logger.info("Upload file: ");
- String filePath = ConfigBaseVariable.getTmpDataFolder() + File.separator + tmpFolderId++;
- try {
- createFolder(ConfigBaseVariable.getTmpDataFolder() + File.separator);
- } catch (IOException e) {
- e.printStackTrace();
- }
- saveFile(fileInputStream, filePath);
- return Response.ok("Data uploaded successfully !!").build();
- //return null;
- }
-
- @GET
- @Path("{id}")
- @PermitTokenInURI
- @RolesAllowed("USER")
- @Produces(MediaType.APPLICATION_OCTET_STREAM)
- public Response retriveDataId(@Context SecurityContext sc, @QueryParam(HttpHeaders.AUTHORIZATION) String token, @HeaderParam("Range") String range, @PathParam("id") Long id) throws Exception {
- GenericContext gc = (GenericContext) sc.getUserPrincipal();
- //logger.info("===================================================");
- logger.info("== DATA retriveDataId ? id={} user={}", id, (gc==null?"null":gc.userByToken));
- //logger.info("===================================================");
- Data value = getSmall(id);
- if (value == null) {
- Response.status(404).
- entity("media NOT FOUND: " + id).
- type("text/plain").
- build();
- }
- return buildStream(ConfigBaseVariable.getMediaDataFolder() + File.separator + id + File.separator + "data", range, value.mimeType);
- }
-
- @GET
- @Path("thumbnail/{id}")
- @RolesAllowed("USER")
- @PermitTokenInURI
- @Produces(MediaType.APPLICATION_OCTET_STREAM)
- //@CacheMaxAge(time = 10, unit = TimeUnit.DAYS)
- public Response retriveDataThumbnailId(@Context SecurityContext sc,
- @QueryParam(HttpHeaders.AUTHORIZATION) String token,
- @HeaderParam("Range") String range,
- @PathParam("id") Long id) throws Exception {
- //GenericContext gc = (GenericContext) sc.getUserPrincipal();
- //logger.info("===================================================");
- //logger.info("== DATA retriveDataThumbnailId ? {}", (gc==null?"null":gc.user));
- //logger.info("===================================================");
- Data value = getSmall(id);
- if (value == null) {
- return Response.status(404).
- entity("media NOT FOUND: " + id).
- type("text/plain").
- build();
- }
- String filePathName = ConfigBaseVariable.getMediaDataFolder() + File.separator + id + File.separator + "data";
- File inputFile = new File(filePathName);
- if (!inputFile.exists()) {
- return Response.status(404).
- entity("{\"error\":\"media Does not exist: " + id + "\"}").
- type("application/json").
- build();
- }
- if ( value.mimeType.contentEquals("image/jpeg")
- || value.mimeType.contentEquals("image/png")
- // || value.mimeType.contentEquals("image/webp")
- ) {
- // reads input image
- BufferedImage inputImage = ImageIO.read(inputFile);
- int scaledWidth = 250;
- int scaledHeight = (int)((float)inputImage.getHeight() / (float)inputImage.getWidth() * (float) scaledWidth);
- // creates output image
- BufferedImage outputImage = new BufferedImage(scaledWidth,
- scaledHeight, inputImage.getType());
-
- // scales the input image to the output image
- Graphics2D g2d = outputImage.createGraphics();
- g2d.drawImage(inputImage, 0, 0, scaledWidth, scaledHeight, null);
- g2d.dispose();
- // create the output stream:
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try {
- // TODO: check how to remove buffer file !!! here, it is not needed at all...
- ImageIO.write( outputImage, "JPG", baos);
+ return null;
+ }
+
+ @POST
+ @Path("/upload/")
+ @Consumes({ MediaType.MULTIPART_FORM_DATA })
+ @RolesAllowed("ADMIN")
+ public Response uploadFile(@Context SecurityContext sc, @FormDataParam("file") InputStream fileInputStream, @FormDataParam("file") FormDataContentDisposition fileMetaData) {
+ GenericContext gc = (GenericContext) sc.getUserPrincipal();
+ LOGGER.info("===================================================");
+ LOGGER.info("== DATA uploadFile {}", (gc == null ? "null" : gc.userByToken));
+ LOGGER.info("===================================================");
+ //public NodeSmall uploadFile(final FormDataMultiPart form) {
+ LOGGER.info("Upload file: ");
+ String filePath = ConfigBaseVariable.getTmpDataFolder() + File.separator + tmpFolderId++;
+ try {
+ createFolder(ConfigBaseVariable.getTmpDataFolder() + File.separator);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ saveFile(fileInputStream, filePath);
+ return Response.ok("Data uploaded successfully !!").build();
+ //return null;
+ }
+
+ @GET
+ @Path("{id}")
+ @PermitTokenInURI
+ @RolesAllowed("USER")
+ @Produces(MediaType.APPLICATION_OCTET_STREAM)
+ public Response retriveDataId(@Context SecurityContext sc, @QueryParam(HttpHeaders.AUTHORIZATION) String token, @HeaderParam("Range") String range, @PathParam("id") Long id) throws Exception {
+ GenericContext gc = (GenericContext) sc.getUserPrincipal();
+ //logger.info("===================================================");
+ LOGGER.info("== DATA retriveDataId ? id={} user={}", id, (gc == null ? "null" : gc.userByToken));
+ //logger.info("===================================================");
+ Data value = getSmall(id);
+ if (value == null) {
+ Response.status(404).entity("media NOT FOUND: " + id).type("text/plain").build();
+ }
+ return buildStream(ConfigBaseVariable.getMediaDataFolder() + File.separator + id + File.separator + "data", range, value.mimeType);
+ }
+
+ @GET
+ @Path("thumbnail/{id}")
+ @RolesAllowed("USER")
+ @PermitTokenInURI
+ @Produces(MediaType.APPLICATION_OCTET_STREAM)
+ //@CacheMaxAge(time = 10, unit = TimeUnit.DAYS)
+ public Response retriveDataThumbnailId(@Context SecurityContext sc, @QueryParam(HttpHeaders.AUTHORIZATION) String token, @HeaderParam("Range") String range, @PathParam("id") Long id)
+ throws Exception {
+ //GenericContext gc = (GenericContext) sc.getUserPrincipal();
+ //logger.info("===================================================");
+ //logger.info("== DATA retriveDataThumbnailId ? {}", (gc==null?"null":gc.user));
+ //logger.info("===================================================");
+ Data value = getSmall(id);
+ if (value == null) {
+ return Response.status(404).entity("media NOT FOUND: " + id).type("text/plain").build();
+ }
+ String filePathName = ConfigBaseVariable.getMediaDataFolder() + File.separator + id + File.separator + "data";
+ File inputFile = new File(filePathName);
+ if (!inputFile.exists()) {
+ return Response.status(404).entity("{\"error\":\"media Does not exist: " + id + "\"}").type("application/json").build();
+ }
+ if (value.mimeType.contentEquals("image/jpeg") || value.mimeType.contentEquals("image/png")
+ // || value.mimeType.contentEquals("image/webp")
+ ) {
+ // reads input image
+ BufferedImage inputImage = ImageIO.read(inputFile);
+ int scaledWidth = 250;
+ int scaledHeight = (int) ((float) inputImage.getHeight() / (float) inputImage.getWidth() * (float) scaledWidth);
+ // creates output image
+ BufferedImage outputImage = new BufferedImage(scaledWidth, scaledHeight, inputImage.getType());
+
+ // scales the input image to the output image
+ Graphics2D g2d = outputImage.createGraphics();
+ g2d.drawImage(inputImage, 0, 0, scaledWidth, scaledHeight, null);
+ g2d.dispose();
+ // create the output stream:
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try {
+ // TODO: check how to remove buffer file !!! here, it is not needed at all...
+ ImageIO.write(outputImage, "JPG", baos);
} catch (IOException e) {
e.printStackTrace();
- return Response.status(500).
- entity("Internal Error: resize fail: " + e.getMessage()).
- type("text/plain").
- build();
+ return Response.status(500).entity("Internal Error: resize fail: " + e.getMessage()).type("text/plain").build();
}
- byte[] imageData = baos.toByteArray();
- //Response.ok(new ByteArrayInputStream(imageData)).build();
- Response.ResponseBuilder out = Response.ok(imageData)
- .header(HttpHeaders.CONTENT_LENGTH, imageData.length);
- out.type("image/jpeg");
- // TODO: move this in a decorator !!!
- CacheControl cc = new CacheControl();
- cc.setMaxAge(3600);
- cc.setNoCache(false);
- out.cacheControl(cc);
- return out.build();
- }
- return buildStream(filePathName, range, value.mimeType);
- }
- //@Secured
- @GET
- @Path("{id}/{name}")
- @PermitTokenInURI
- @RolesAllowed("USER")
- @Produces(MediaType.APPLICATION_OCTET_STREAM)
- public Response retriveDataFull(@Context SecurityContext sc, @QueryParam(HttpHeaders.AUTHORIZATION) String token, @HeaderParam("Range") String range, @PathParam("id") Long id, @PathParam("name") String name) throws Exception {
- GenericContext gc = (GenericContext) sc.getUserPrincipal();
- //logger.info("===================================================");
- logger.info("== DATA retriveDataFull ? id={} user={}", id, (gc==null?"null":gc.userByToken));
- //logger.info("===================================================");
- Data value = getSmall(id);
- if (value == null) {
- Response.status(404).
- entity("media NOT FOUND: " + id).
- type("text/plain").
- build();
- }
- return buildStream(ConfigBaseVariable.getMediaDataFolder() + File.separator + id + File.separator + "data", range, value.mimeType);
- }
-
- /**
- * Adapted from http://stackoverflow.com/questions/12768812/video-streaming-to-ipad-does-not-work-with-tapestry5/12829541#12829541
- *
- * @param range range header
- * @return Streaming output
- * @throws Exception IOException if an error occurs in streaming.
- */
- private Response buildStream(final String filename, final String range, String mimeType) throws Exception {
- File file = new File(filename);
- //logger.info("request range : {}", range);
- // range not requested : Firefox does not send range headers
- if (range == null) {
- final StreamingOutput output = new StreamingOutput() {
- @Override
- public void write(OutputStream out) {
- try (FileInputStream in = new FileInputStream(file)) {
- byte[] buf = new byte[1024 * 1024];
- int len;
- while ((len = in.read(buf)) != -1) {
- try {
- out.write(buf, 0, len);
- out.flush();
- //logger.info("---- wrote {} bytes file ----", len);
- } catch (IOException ex) {
- logger.info("remote close connection");
- break;
- }
- }
- } catch (IOException ex) {
- throw new InternalServerErrorException(ex);
- }
- }
- };
- Response.ResponseBuilder out = Response.ok(output)
- .header(HttpHeaders.CONTENT_LENGTH, file.length());
- if (mimeType != null) {
- out.type(mimeType);
- }
- return out.build();
-
- }
-
- String[] ranges = range.split("=")[1].split("-");
- final long from = Long.parseLong(ranges[0]);
-
- //logger.info("request range : {}", ranges.length);
- //Chunk media if the range upper bound is unspecified. Chrome, Opera sends "bytes=0-"
- long to = CHUNK_SIZE + from;
- if (ranges.length == 1) {
- to = file.length() - 1;
- } else {
- if (to >= file.length()) {
- to = (long) (file.length() - 1);
- }
- }
- 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);
-
- final long len = to - from + 1;
- final MediaStreamer streamer = new MediaStreamer(len, raf);
- 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();
- }
-
+ byte[] imageData = baos.toByteArray();
+ //Response.ok(new ByteArrayInputStream(imageData)).build();
+ Response.ResponseBuilder out = Response.ok(imageData).header(HttpHeaders.CONTENT_LENGTH, imageData.length);
+ out.type("image/jpeg");
+ // TODO: move this in a decorator !!!
+ CacheControl cc = new CacheControl();
+ cc.setMaxAge(3600);
+ cc.setNoCache(false);
+ out.cacheControl(cc);
+ return out.build();
+ }
+ return buildStream(filePathName, range, value.mimeType);
+ }
+
+ //@Secured
+ @GET
+ @Path("{id}/{name}")
+ @PermitTokenInURI
+ @RolesAllowed("USER")
+ @Produces(MediaType.APPLICATION_OCTET_STREAM)
+ public Response retriveDataFull(@Context SecurityContext sc, @QueryParam(HttpHeaders.AUTHORIZATION) String token, @HeaderParam("Range") String range, @PathParam("id") Long id,
+ @PathParam("name") String name) throws Exception {
+ GenericContext gc = (GenericContext) sc.getUserPrincipal();
+ //logger.info("===================================================");
+ LOGGER.info("== DATA retriveDataFull ? id={} user={}", id, (gc == null ? "null" : gc.userByToken));
+ //logger.info("===================================================");
+ Data value = getSmall(id);
+ if (value == null) {
+ Response.status(404).entity("media NOT FOUND: " + id).type("text/plain").build();
+ }
+ return buildStream(ConfigBaseVariable.getMediaDataFolder() + File.separator + id + File.separator + "data", range, value.mimeType);
+ }
+
+ /**
+ * Adapted from http://stackoverflow.com/questions/12768812/video-streaming-to-ipad-does-not-work-with-tapestry5/12829541#12829541
+ *
+ * @param range range header
+ * @return Streaming output
+ * @throws Exception IOException if an error occurs in streaming.
+ */
+ private Response buildStream(final String filename, final String range, String mimeType) throws Exception {
+ File file = new File(filename);
+ //logger.info("request range : {}", range);
+ // range not requested : Firefox does not send range headers
+ if (range == null) {
+ final StreamingOutput output = new StreamingOutput() {
+ @Override
+ public void write(OutputStream out) {
+ try (FileInputStream in = new FileInputStream(file)) {
+ byte[] buf = new byte[1024 * 1024];
+ int len;
+ while ((len = in.read(buf)) != -1) {
+ try {
+ out.write(buf, 0, len);
+ out.flush();
+ //logger.info("---- wrote {} bytes file ----", len);
+ } catch (IOException ex) {
+ LOGGER.info("remote close connection");
+ break;
+ }
+ }
+ } catch (IOException ex) {
+ throw new InternalServerErrorException(ex);
+ }
+ }
+ };
+ Response.ResponseBuilder out = Response.ok(output).header(HttpHeaders.CONTENT_LENGTH, file.length());
+ if (mimeType != null) {
+ out.type(mimeType);
+ }
+ return out.build();
+
+ }
+
+ String[] ranges = range.split("=")[1].split("-");
+ final long from = Long.parseLong(ranges[0]);
+
+ //logger.info("request range : {}", ranges.length);
+ //Chunk media if the range upper bound is unspecified. Chrome, Opera sends "bytes=0-"
+ long to = CHUNK_SIZE + from;
+ if (ranges.length == 1) {
+ to = file.length() - 1;
+ } else {
+ if (to >= file.length()) {
+ to = (long) (file.length() - 1);
+ }
+ }
+ 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);
+
+ final long len = to - from + 1;
+ final MediaStreamer streamer = new MediaStreamer(len, raf);
+ 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();
+ }
+
public static void undelete(Long id) throws Exception {
SqlWrapper.unsetDelete(Data.class, id);
}
-
+
}
diff --git a/src/org/kar/archidata/api/FrontGeneric.java b/src/org/kar/archidata/api/FrontGeneric.java
index d570349..3af6a77 100644
--- a/src/org/kar/archidata/api/FrontGeneric.java
+++ b/src/org/kar/archidata/api/FrontGeneric.java
@@ -3,100 +3,110 @@ package org.kar.archidata.api;
import java.io.File;
import java.util.List;
-import jakarta.ws.rs.*;
+import org.kar.archidata.annotation.security.PermitAll;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.NotFoundException;
+import jakarta.ws.rs.NotSupportedException;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.core.CacheControl;
import jakarta.ws.rs.core.PathSegment;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.ResponseBuilder;
-import org.kar.archidata.annotation.security.PermitAll;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
public class FrontGeneric {
- static final Logger logger = LoggerFactory.getLogger(FrontGeneric.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(FrontGeneric.class);
protected String baseFrontFolder = "/data/front";
private String getExtension(String filename) {
- if (filename.contains(".")) {
- return filename.substring(filename.lastIndexOf(".") + 1);
- }
- return "";
+ if (filename.contains(".")) {
+ return filename.substring(filename.lastIndexOf(".") + 1);
+ }
+ return "";
+ }
+
+ private Response retrive(String fileName) throws Exception {
+ String filePathName = baseFrontFolder + File.separator + fileName;
+ String extention = getExtension(filePathName);
+ String mineType = null;
+ LOGGER.debug("try retrive : '{}' '{}'", filePathName, extention);
+ if (extention.length() != 0 && extention.length() <= 5) {
+ if (extention.equalsIgnoreCase("jpg") || extention.equalsIgnoreCase("jpeg")) {
+ mineType = "image/jpeg";
+ } else if (extention.equalsIgnoreCase("gif")) {
+ mineType = "image/gif";
+ } else if (extention.equalsIgnoreCase("png")) {
+ mineType = "image/png";
+ } else if (extention.equalsIgnoreCase("svg")) {
+ mineType = "image/svg+xml";
+ } else if (extention.equalsIgnoreCase("webp")) {
+ mineType = "image/webp";
+ } else if (extention.equalsIgnoreCase("js")) {
+ mineType = "application/javascript";
+ } else if (extention.equalsIgnoreCase("json")) {
+ mineType = "application/json";
+ } else if (extention.equalsIgnoreCase("ico")) {
+ mineType = "image/x-icon";
+ } else if (extention.equalsIgnoreCase("html")) {
+ mineType = "text/html";
+ } else if (extention.equalsIgnoreCase("css")) {
+ mineType = "text/css";
+ } else if (extention.equalsIgnoreCase("mka")) {
+ mineType = "audio/x-matroska";
+ } else if (extention.equalsIgnoreCase("mkv")) {
+ mineType = "video/x-matroska";
+ } else if (extention.equalsIgnoreCase("webm")) {
+ mineType = "video/webm";
+ } else {
+ throw new NotSupportedException("Not supported model: '" + fileName + "'");
+ }
+ } else {
+ mineType = "text/html";
+ filePathName = baseFrontFolder + File.separator + "index.html";
+ }
+ LOGGER.debug(" ==> '[}'", filePathName);
+ // reads input image
+ File download = new File(filePathName);
+ if (!download.exists()) {
+ throw new NotFoundException("Not Found: '" + fileName + "' extension='" + extention + "'");
+ }
+ ResponseBuilder response = Response.ok((Object) download);
+ // use this if I want to download the file:
+ //response.header("Content-Disposition", "attachment; filename=" + fileName);
+ CacheControl cc = new CacheControl();
+ cc.setMaxAge(60);
+ cc.setNoCache(false);
+ response.cacheControl(cc);
+ response.type(mineType);
+
+ return response.build();
+ }
+
+ @GET
+ @PermitAll()
+ //@Produces(MediaType.APPLICATION_OCTET_STREAM)
+ //@CacheMaxAge(time = 1, unit = TimeUnit.DAYS)
+ public Response retrive0() throws Exception {
+ return retrive("index.html");
+ }
+
+ @GET
+ @Path("{any: .*}")
+ @PermitAll()
+ //@Produces(MediaType.APPLICATION_OCTET_STREAM)
+ //@CacheMaxAge(time = 10, unit = TimeUnit.DAYS)
+ public Response retrive1(@PathParam("any") List segments) throws Exception {
+ String filename = "";
+ for (PathSegment elem : segments) {
+ if (!filename.isEmpty()) {
+ filename += File.separator;
+ }
+ filename += elem.getPath();
+ }
+ return retrive(filename);
}
- private Response retrive(String fileName) throws Exception {
- String filePathName = baseFrontFolder + File.separator + fileName;
- String extention = getExtension(filePathName);
- String mineType = null;
- logger.debug("try retrive : '{}' '{}'", filePathName, extention);
- if (extention.length() !=0 && extention.length() <= 5) {
- if (extention.equalsIgnoreCase("jpg") || extention.equalsIgnoreCase("jpeg")) {
- mineType = "image/jpeg";
- } else if (extention.equalsIgnoreCase("gif")) {
- mineType = "image/gif";
- } else if (extention.equalsIgnoreCase("png")) {
- mineType = "image/png";
- } else if (extention.equalsIgnoreCase("svg")) {
- mineType = "image/svg+xml";
- } else if (extention.equalsIgnoreCase("webp")) {
- mineType = "image/webp";
- } else if (extention.equalsIgnoreCase("js")) {
- mineType = "application/javascript";
- } else if (extention.equalsIgnoreCase("json")) {
- mineType = "application/json";
- } else if (extention.equalsIgnoreCase("ico")) {
- mineType = "image/x-icon";
- } else if (extention.equalsIgnoreCase("html")) {
- mineType = "text/html";
- } else if (extention.equalsIgnoreCase("css")) {
- mineType = "text/css";
- } else {
- throw new NotSupportedException("Not supported model: '" + fileName + "'");
- }
- } else {
- mineType = "text/html";
- filePathName = baseFrontFolder + File.separator + "index.html";
- }
- logger.debug(" ==> '[}'", filePathName);
- // reads input image
- File download = new File(filePathName);
- if (!download.exists()) {
- throw new NotFoundException("Not Found: '" + fileName + "' extension='" + extention + "'");
- }
- ResponseBuilder response = Response.ok((Object)download);
- // use this if I want to download the file:
- //response.header("Content-Disposition", "attachment; filename=" + fileName);
- CacheControl cc = new CacheControl();
- cc.setMaxAge(60);
- cc.setNoCache(false);
- response.cacheControl(cc);
- response.type(mineType);
-
- return response.build();
- }
-
- @GET
- @PermitAll()
- //@Produces(MediaType.APPLICATION_OCTET_STREAM)
- //@CacheMaxAge(time = 1, unit = TimeUnit.DAYS)
- public Response retrive0() throws Exception {
- return retrive("index.html");
- }
-
- @GET
- @Path("{any: .*}")
- @PermitAll()
- //@Produces(MediaType.APPLICATION_OCTET_STREAM)
- //@CacheMaxAge(time = 10, unit = TimeUnit.DAYS)
- public Response retrive1(@PathParam("any") List segments) throws Exception {
- String filename = "";
- for (PathSegment elem: segments) {
- if (!filename.isEmpty()) {
- filename += File.separator;
- }
- filename += elem.getPath();
- }
- return retrive(filename);
- }
}
diff --git a/src/org/kar/archidata/api/MediaStreamer.java b/src/org/kar/archidata/api/MediaStreamer.java
index 6262bbb..15d7d93 100644
--- a/src/org/kar/archidata/api/MediaStreamer.java
+++ b/src/org/kar/archidata/api/MediaStreamer.java
@@ -1,8 +1,5 @@
package org.kar.archidata.api;
-import jakarta.ws.rs.InternalServerErrorException;
-import jakarta.ws.rs.WebApplicationException;
-import jakarta.ws.rs.core.StreamingOutput;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
@@ -10,51 +7,55 @@ import java.io.RandomAccessFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import jakarta.ws.rs.InternalServerErrorException;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.StreamingOutput;
+
public class MediaStreamer implements StreamingOutput {
- static final Logger logger = LoggerFactory.getLogger(MediaStreamer.class);
- private final int CHUNK_SIZE = 1024 * 1024; // 1MB chunks
- final byte[] buf = new byte[CHUNK_SIZE];
- private long length;
- private RandomAccessFile raf;
-
- public MediaStreamer(long length, RandomAccessFile raf) throws IOException {
- //logger.info("request stream of {} data", length / 1024);
- if (length<0) {
- throw new IOException("Wrong size of the file to stream: " + length);
- }
- this.length = length;
- this.raf = raf;
- }
-
- @Override
- public void write(OutputStream outputStream) {
- try {
- while (length != 0) {
- int read = raf.read(buf, 0, buf.length > length ? (int) length : buf.length);
- try {
- outputStream.write(buf, 0, read);
- } catch (IOException ex) {
- logger.info("remote close connection");
- break;
- }
- length -= read;
- }
- } catch (IOException ex) {
- throw new InternalServerErrorException(ex);
- } catch (WebApplicationException ex) {
- throw new InternalServerErrorException(ex);
- } finally {
- try {
- raf.close();
- } catch (IOException ex) {
- ex.printStackTrace();
- throw new InternalServerErrorException(ex);
- }
- }
- }
-
- public long getLenth() {
- return length;
- }
-
+ private static final Logger LOGGER = LoggerFactory.getLogger(MediaStreamer.class);
+ private final int CHUNK_SIZE = 1024 * 1024; // 1MB chunks
+ final byte[] buf = new byte[CHUNK_SIZE];
+ private long length;
+ private RandomAccessFile raf;
+
+ public MediaStreamer(long length, RandomAccessFile raf) throws IOException {
+ //logger.info("request stream of {} data", length / 1024);
+ if (length < 0) {
+ throw new IOException("Wrong size of the file to stream: " + length);
+ }
+ this.length = length;
+ this.raf = raf;
+ }
+
+ @Override
+ public void write(OutputStream outputStream) {
+ try {
+ while (length != 0) {
+ int read = raf.read(buf, 0, buf.length > length ? (int) length : buf.length);
+ try {
+ outputStream.write(buf, 0, read);
+ } catch (IOException ex) {
+ LOGGER.info("remote close connection");
+ break;
+ }
+ length -= read;
+ }
+ } catch (IOException ex) {
+ throw new InternalServerErrorException(ex);
+ } catch (WebApplicationException ex) {
+ throw new InternalServerErrorException(ex);
+ } finally {
+ try {
+ raf.close();
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ throw new InternalServerErrorException(ex);
+ }
+ }
+ }
+
+ public long getLenth() {
+ return length;
+ }
+
}
diff --git a/src/org/kar/archidata/catcher/ExceptionCatcher.java b/src/org/kar/archidata/catcher/ExceptionCatcher.java
index af08cf5..b61671d 100644
--- a/src/org/kar/archidata/catcher/ExceptionCatcher.java
+++ b/src/org/kar/archidata/catcher/ExceptionCatcher.java
@@ -1,29 +1,26 @@
package org.kar.archidata.catcher;
-import jakarta.ws.rs.core.MediaType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
+import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
-
-public class ExceptionCatcher
-implements ExceptionMapper {
- final Logger logger = LoggerFactory.getLogger(ExceptionCatcher.class);
- @Override
- public Response toResponse(Exception exception) {
- logger.warn("Catch exception (not managed...):");
- RestErrorResponse ret = build(exception);
- logger.error("Error UUID={}", ret.uuid);
- exception.printStackTrace();
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
- .entity(ret)
- .type(MediaType.APPLICATION_JSON)
- .build();
- }
-
- private RestErrorResponse build(Exception exception) {
- return new RestErrorResponse(Response.Status.INTERNAL_SERVER_ERROR, "Catch Unknown Exception", exception.getMessage());
- }
-
+public class ExceptionCatcher implements ExceptionMapper {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatcher.class);
+
+ @Override
+ public Response toResponse(Exception exception) {
+ LOGGER.warn("Catch exception (not managed...):");
+ RestErrorResponse ret = build(exception);
+ LOGGER.error("Error UUID={}", ret.uuid);
+ exception.printStackTrace();
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(ret).type(MediaType.APPLICATION_JSON).build();
+ }
+
+ private RestErrorResponse build(Exception exception) {
+ return new RestErrorResponse(Response.Status.INTERNAL_SERVER_ERROR, "Catch Unknown Exception", exception.getMessage());
+ }
+
}
diff --git a/src/org/kar/archidata/catcher/FailException404API.java b/src/org/kar/archidata/catcher/FailException404API.java
index 69e6b71..f01c1a8 100644
--- a/src/org/kar/archidata/catcher/FailException404API.java
+++ b/src/org/kar/archidata/catcher/FailException404API.java
@@ -1,29 +1,25 @@
package org.kar.archidata.catcher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import jakarta.ws.rs.ClientErrorException;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-public class FailException404API
-implements ExceptionMapper {
- final Logger logger = LoggerFactory.getLogger(FailException404API.class);
- @Override
- public Response toResponse(ClientErrorException exception) {
- RestErrorResponse ret = build(exception);
- logger.error("Error UUID={}", ret.uuid);
- return Response.status(exception.getResponse().getStatusInfo().toEnum())
- .entity(ret)
- .type(MediaType.APPLICATION_JSON)
- .build();
- }
-
- private RestErrorResponse build(ClientErrorException exception) {
- return new RestErrorResponse(exception.getResponse().getStatusInfo().toEnum(), "Catch system exception" , exception.getMessage());
- }
-
+public class FailException404API implements ExceptionMapper {
+ private static final Logger LOGGER = LoggerFactory.getLogger(FailException404API.class);
+
+ @Override
+ public Response toResponse(ClientErrorException exception) {
+ RestErrorResponse ret = build(exception);
+ LOGGER.error("Error UUID={}", ret.uuid);
+ return Response.status(exception.getResponse().getStatusInfo().toEnum()).entity(ret).type(MediaType.APPLICATION_JSON).build();
+ }
+
+ private RestErrorResponse build(ClientErrorException exception) {
+ return new RestErrorResponse(exception.getResponse().getStatusInfo().toEnum(), "Catch system exception", exception.getMessage());
+ }
+
}
diff --git a/src/org/kar/archidata/catcher/FailExceptionCatcher.java b/src/org/kar/archidata/catcher/FailExceptionCatcher.java
index 3eac821..efa7b9e 100644
--- a/src/org/kar/archidata/catcher/FailExceptionCatcher.java
+++ b/src/org/kar/archidata/catcher/FailExceptionCatcher.java
@@ -1,31 +1,27 @@
package org.kar.archidata.catcher;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.ext.ExceptionMapper;
-
import org.kar.archidata.exception.FailException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.ExceptionMapper;
-public class FailExceptionCatcher
-implements ExceptionMapper {
- final Logger logger = LoggerFactory.getLogger(FailExceptionCatcher.class);
- @Override
- public Response toResponse(FailException exception) {
- RestErrorResponse ret = build(exception);
- logger.error("Error UUID={}", ret.uuid);
- // Not display backtrace ==> this may be a normal case ...
- //exception.printStackTrace();
- return Response.status(exception.status)
- .entity(ret)
- .type(MediaType.APPLICATION_JSON)
- .build();
- }
-
- private RestErrorResponse build(FailException exception) {
- return new RestErrorResponse(exception.status, "Request Fail", exception.getMessage());
- }
-
+public class FailExceptionCatcher implements ExceptionMapper {
+ private static final Logger LOGGER = LoggerFactory.getLogger(FailExceptionCatcher.class);
+
+ @Override
+ public Response toResponse(FailException exception) {
+ RestErrorResponse ret = build(exception);
+ LOGGER.error("Error UUID={}", ret.uuid);
+ // Not display backtrace ==> this may be a normal case ...
+ //exception.printStackTrace();
+ return Response.status(exception.status).entity(ret).type(MediaType.APPLICATION_JSON).build();
+ }
+
+ private RestErrorResponse build(FailException exception) {
+ return new RestErrorResponse(exception.status, "Request Fail", exception.getMessage());
+ }
+
}
diff --git a/src/org/kar/archidata/catcher/InputExceptionCatcher.java b/src/org/kar/archidata/catcher/InputExceptionCatcher.java
index 1620cec..7029176 100644
--- a/src/org/kar/archidata/catcher/InputExceptionCatcher.java
+++ b/src/org/kar/archidata/catcher/InputExceptionCatcher.java
@@ -1,30 +1,26 @@
package org.kar.archidata.catcher;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.ext.ExceptionMapper;
-
import org.kar.archidata.exception.InputException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.ExceptionMapper;
-public class InputExceptionCatcher
-implements ExceptionMapper {
- final Logger logger = LoggerFactory.getLogger(InputExceptionCatcher.class);
- @Override
- public Response toResponse(InputException exception) {
- RestErrorResponse ret = build(exception);
- logger.error("Error UUID={}", ret.uuid);
- exception.printStackTrace();
- return Response.status(exception.status)
- .entity(ret)
- .type(MediaType.APPLICATION_JSON)
- .build();
- }
-
- private RestErrorResponse build(InputException exception) {
- return new RestErrorResponse(exception.status, "Error on input='" + exception.missingVariable + "'" , exception.getMessage());
- }
-
+public class InputExceptionCatcher implements ExceptionMapper {
+ private static final Logger LOGGER = LoggerFactory.getLogger(InputExceptionCatcher.class);
+
+ @Override
+ public Response toResponse(InputException exception) {
+ RestErrorResponse ret = build(exception);
+ LOGGER.error("Error UUID={}", ret.uuid);
+ exception.printStackTrace();
+ return Response.status(exception.status).entity(ret).type(MediaType.APPLICATION_JSON).build();
+ }
+
+ private RestErrorResponse build(InputException exception) {
+ return new RestErrorResponse(exception.status, "Error on input='" + exception.missingVariable + "'", exception.getMessage());
+ }
+
}
diff --git a/src/org/kar/archidata/catcher/RestErrorResponse.java b/src/org/kar/archidata/catcher/RestErrorResponse.java
index 152870e..63a2a46 100644
--- a/src/org/kar/archidata/catcher/RestErrorResponse.java
+++ b/src/org/kar/archidata/catcher/RestErrorResponse.java
@@ -7,7 +7,7 @@ import jakarta.ws.rs.core.Response;
public class RestErrorResponse {
public UUID uuid = UUID.randomUUID();
- public String time;
+ public String time;
public String error;
public String message;
final public int status;
@@ -20,6 +20,7 @@ public class RestErrorResponse {
this.status = status.getStatusCode();
this.statusMessage = status.getReasonPhrase();
}
+
public RestErrorResponse(Response.Status status, String error, String message) {
this.time = Instant.now().toString();
this.error = error;
@@ -27,6 +28,7 @@ public class RestErrorResponse {
this.status = status.getStatusCode();
this.statusMessage = status.getReasonPhrase();
}
+
public RestErrorResponse(Response.Status status) {
this.time = Instant.now().toString();
this.status = status.getStatusCode();
diff --git a/src/org/kar/archidata/catcher/SystemExceptionCatcher.java b/src/org/kar/archidata/catcher/SystemExceptionCatcher.java
index f729d26..1421683 100644
--- a/src/org/kar/archidata/catcher/SystemExceptionCatcher.java
+++ b/src/org/kar/archidata/catcher/SystemExceptionCatcher.java
@@ -1,30 +1,26 @@
package org.kar.archidata.catcher;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.ext.ExceptionMapper;
-
import org.kar.archidata.exception.SystemException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.ExceptionMapper;
-public class SystemExceptionCatcher
-implements ExceptionMapper {
- final Logger logger = LoggerFactory.getLogger(SystemExceptionCatcher.class);
- @Override
- public Response toResponse(SystemException exception) {
- RestErrorResponse ret = build(exception);
- logger.error("Error UUID={}", ret.uuid);
- exception.printStackTrace();
- return Response.status(exception.status)
- .entity(ret)
- .type(MediaType.APPLICATION_JSON)
- .build();
- }
-
- private RestErrorResponse build(SystemException exception) {
- return new RestErrorResponse(exception.status, "System error", exception.getMessage());
- }
-
+public class SystemExceptionCatcher implements ExceptionMapper {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SystemExceptionCatcher.class);
+
+ @Override
+ public Response toResponse(SystemException exception) {
+ RestErrorResponse ret = build(exception);
+ LOGGER.error("Error UUID={}", ret.uuid);
+ exception.printStackTrace();
+ return Response.status(exception.status).entity(ret).type(MediaType.APPLICATION_JSON).build();
+ }
+
+ private RestErrorResponse build(SystemException exception) {
+ return new RestErrorResponse(exception.status, "System error", exception.getMessage());
+ }
+
}
diff --git a/src/org/kar/archidata/db/DBConfig.java b/src/org/kar/archidata/db/DBConfig.java
index 6733ea5..0966a84 100644
--- a/src/org/kar/archidata/db/DBConfig.java
+++ b/src/org/kar/archidata/db/DBConfig.java
@@ -6,87 +6,82 @@ import org.slf4j.LoggerFactory;
public class DBConfig {
static final Logger LOGGER = LoggerFactory.getLogger(SqlWrapper.class);
- private final String type;
- private final String hostname;
- private final int port;
- private final String login;
- private final String password;
- private final String dbName;
- private final boolean keepConnected;
-
- public DBConfig(String type, String hostname, Integer port, String login, String password, String dbName, boolean keepConnected) {
- if (type == null) {
- this.type = "mysql";
- } else {
- this.type = type;
- }
- if (hostname == null) {
- this.hostname = "localhost";
- } else {
- this.hostname = hostname;
- }
- if (port == null) {
- this.port = 3306;
- } else {
- this.port = port;
- }
- this.login = login;
- this.password = password;
- this.dbName = dbName;
- this.keepConnected = keepConnected;
- }
-
- @Override
- public String toString() {
- return "DBConfig{" +
- "type='" + type + '\'' +
- ", hostname='" + hostname + '\'' +
- ", port=" + port +
- ", login='" + login + '\'' +
- ", password='" + password + '\'' +
- ", dbName='" + dbName + '\'' +
- '}';
- }
-
- public String getHostname() {
- return hostname;
- }
-
- public int getPort() {
- return port;
- }
-
- public String getLogin() {
- return login;
- }
-
- public String getPassword() {
- return password;
- }
-
- public String getDbName() {
- return dbName;
- }
- public boolean getKeepConnected() {
- return keepConnected;
- }
-
- public String getUrl() {
- return getUrl(false);
- }
- public String getUrl(boolean isRoot) {
- if (type.equals("sqlite")) {
- if (isRoot == true) {
- LOGGER.error("Can not manage root connection on SQLite...");
- }
- if (this.hostname.equals("memory")) {
- return "jdbc:sqlite::memory:";
- }
- return "jdbc:sqlite:" + this.hostname + ".db";
- }
- if (isRoot) {
- return "jdbc:" + this.type + "://" + this.hostname + ":" + this.port + "/?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC";
- }
+ private final String type;
+ private final String hostname;
+ private final int port;
+ private final String login;
+ private final String password;
+ private final String dbName;
+ private final boolean keepConnected;
+
+ public DBConfig(String type, String hostname, Integer port, String login, String password, String dbName, boolean keepConnected) {
+ if (type == null) {
+ this.type = "mysql";
+ } else {
+ this.type = type;
+ }
+ if (hostname == null) {
+ this.hostname = "localhost";
+ } else {
+ this.hostname = hostname;
+ }
+ if (port == null) {
+ this.port = 3306;
+ } else {
+ this.port = port;
+ }
+ this.login = login;
+ this.password = password;
+ this.dbName = dbName;
+ this.keepConnected = keepConnected;
+ }
+
+ @Override
+ public String toString() {
+ return "DBConfig{type='" + type + '\'' + ", hostname='" + hostname + '\'' + ", port=" + port + ", login='" + login + '\'' + ", password='" + password + '\'' + ", dbName='" + dbName + "' }";
+ }
+
+ public String getHostname() {
+ return hostname;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public String getLogin() {
+ return login;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public String getDbName() {
+ return dbName;
+ }
+
+ public boolean getKeepConnected() {
+ return keepConnected;
+ }
+
+ public String getUrl() {
+ return getUrl(false);
+ }
+
+ public String getUrl(boolean isRoot) {
+ if (type.equals("sqlite")) {
+ if (isRoot == true) {
+ LOGGER.error("Can not manage root connection on SQLite...");
+ }
+ if (this.hostname.equals("memory")) {
+ return "jdbc:sqlite::memory:";
+ }
+ return "jdbc:sqlite:" + this.hostname + ".db";
+ }
+ if (isRoot) {
+ return "jdbc:" + this.type + "://" + this.hostname + ":" + this.port + "/?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC";
+ }
return "jdbc:" + this.type + "://" + this.hostname + ":" + this.port + "/" + this.dbName + "?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC";
- }
+ }
}
diff --git a/src/org/kar/archidata/db/DBEntry.java b/src/org/kar/archidata/db/DBEntry.java
index 7f2db64..1355c37 100644
--- a/src/org/kar/archidata/db/DBEntry.java
+++ b/src/org/kar/archidata/db/DBEntry.java
@@ -2,7 +2,9 @@ package org.kar.archidata.db;
import java.io.Closeable;
import java.io.IOException;
-import java.sql.*;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
@@ -11,69 +13,70 @@ import org.slf4j.LoggerFactory;
public class DBEntry implements Closeable {
final static Logger LOGGER = LoggerFactory.getLogger(DBEntry.class);
- public DBConfig config;
- public Connection connection;
- private static List stored = new ArrayList<>();
-
- private DBEntry(DBConfig config, boolean root) throws IOException {
- this.config = config;
- if (root) {
- connectRoot();
- } else {
- connect();
- }
- }
-
- public static DBEntry createInterface(DBConfig config) throws IOException {
- return createInterface(config, false);
- }
- public static DBEntry createInterface(DBConfig config, boolean root) throws IOException {
- if (config.getKeepConnected()) {
- for (DBEntry elem : stored) {
- if (elem == null) {
- continue;
- }
- if (elem.config.getUrl().equals(config.getUrl())) {
- return elem;
- }
- }
- DBEntry tmp = new DBEntry(config, root);
- stored.add(tmp);
- return tmp;
- } else {
- return new DBEntry(config, root);
- }
- }
-
- public void connectRoot() throws IOException {
- try {
- connection = DriverManager.getConnection(config.getUrl(true), config.getLogin(), config.getPassword());
- } catch (SQLException ex) {
- throw new IOException("Connection db fail: " + ex.getMessage());
- }
-
- }
-
- public void connect() throws IOException {
- try {
- connection = DriverManager.getConnection(config.getUrl(), config.getLogin(), config.getPassword());
- } catch (SQLException ex) {
- throw new IOException("Connection db fail: " + ex.getMessage());
- }
-
- }
-
+ public DBConfig config;
+ public Connection connection;
+ private static List stored = new ArrayList<>();
+
+ private DBEntry(DBConfig config, boolean root) throws IOException {
+ this.config = config;
+ if (root) {
+ connectRoot();
+ } else {
+ connect();
+ }
+ }
+
+ public static DBEntry createInterface(DBConfig config) throws IOException {
+ return createInterface(config, false);
+ }
+
+ public static DBEntry createInterface(DBConfig config, boolean root) throws IOException {
+ if (config.getKeepConnected()) {
+ for (DBEntry elem : stored) {
+ if (elem == null) {
+ continue;
+ }
+ if (elem.config.getUrl().equals(config.getUrl())) {
+ return elem;
+ }
+ }
+ DBEntry tmp = new DBEntry(config, root);
+ stored.add(tmp);
+ return tmp;
+ } else {
+ return new DBEntry(config, root);
+ }
+ }
+
+ public void connectRoot() throws IOException {
+ try {
+ connection = DriverManager.getConnection(config.getUrl(true), config.getLogin(), config.getPassword());
+ } catch (SQLException ex) {
+ throw new IOException("Connection db fail: " + ex.getMessage());
+ }
+
+ }
+
+ public void connect() throws IOException {
+ try {
+ connection = DriverManager.getConnection(config.getUrl(), config.getLogin(), config.getPassword());
+ } catch (SQLException ex) {
+ throw new IOException("Connection db fail: " + ex.getMessage());
+ }
+
+ }
+
@Override
public void close() throws IOException {
if (config.getKeepConnected()) {
return;
}
- try {
- //connection.commit();
- connection.close();
- } catch (SQLException ex) {
- throw new IOException("Dis-connection db fail: " + ex.getMessage());
- }
+ try {
+ //connection.commit();
+ connection.close();
+ } catch (SQLException ex) {
+ throw new IOException("Dis-connection db fail: " + ex.getMessage());
+ }
}
}
diff --git a/src/org/kar/archidata/exception/FailException.java b/src/org/kar/archidata/exception/FailException.java
index 1f0e8ab..7b58416 100644
--- a/src/org/kar/archidata/exception/FailException.java
+++ b/src/org/kar/archidata/exception/FailException.java
@@ -5,10 +5,12 @@ import jakarta.ws.rs.core.Response;
public class FailException extends Exception {
private static final long serialVersionUID = 1L;
public final Response.Status status;
+
public FailException(Response.Status status, String message) {
super(message);
this.status = status;
}
+
public FailException(String message) {
super(message);
this.status = Response.Status.BAD_REQUEST;
diff --git a/src/org/kar/archidata/exception/InputException.java b/src/org/kar/archidata/exception/InputException.java
index 1c4b69a..1a3a610 100644
--- a/src/org/kar/archidata/exception/InputException.java
+++ b/src/org/kar/archidata/exception/InputException.java
@@ -6,11 +6,13 @@ public class InputException extends Exception {
private static final long serialVersionUID = 1L;
public final String missingVariable;
public final Response.Status status;
+
public InputException(Response.Status status, String variable, String message) {
super(message);
this.missingVariable = variable;
this.status = status;
}
+
public InputException(String variable, String message) {
super(message);
this.missingVariable = variable;
diff --git a/src/org/kar/archidata/exception/NotFoundException.java b/src/org/kar/archidata/exception/NotFoundException.java
index ed5df9a..d2e5fdb 100644
--- a/src/org/kar/archidata/exception/NotFoundException.java
+++ b/src/org/kar/archidata/exception/NotFoundException.java
@@ -4,6 +4,7 @@ import jakarta.ws.rs.core.Response;
public class NotFoundException extends FailException {
private static final long serialVersionUID = 1L;
+
public NotFoundException(String message) {
super(Response.Status.NOT_FOUND, message);
}
diff --git a/src/org/kar/archidata/exception/RESTErrorResponseExeption.java b/src/org/kar/archidata/exception/RESTErrorResponseExeption.java
index ed0870a..fb52729 100644
--- a/src/org/kar/archidata/exception/RESTErrorResponseExeption.java
+++ b/src/org/kar/archidata/exception/RESTErrorResponseExeption.java
@@ -4,12 +4,12 @@ import java.util.UUID;
public class RESTErrorResponseExeption extends Exception {
public UUID uuid;
- public String time;
+ public String time;
public String error;
public String message;
public int status;
public String statusMessage;
-
+
public RESTErrorResponseExeption() {
super();
this.uuid = null;
@@ -19,8 +19,8 @@ public class RESTErrorResponseExeption extends Exception {
this.status = 0;
this.statusMessage = null;
}
- public RESTErrorResponseExeption(UUID uuid, String time, String error, String message, int status,
- String statusMessage) {
+
+ public RESTErrorResponseExeption(UUID uuid, String time, String error, String message, int status, String statusMessage) {
super();
this.uuid = uuid;
this.time = time;
@@ -29,13 +29,10 @@ public class RESTErrorResponseExeption extends Exception {
this.status = status;
this.statusMessage = statusMessage;
}
-
+
@Override
public String toString() {
- return "RESTErrorResponseExeption [uuid=" + uuid + ", time=" + time + ", error=" + error + ", message="
- + message + ", status=" + status + ", statusMessage=" + statusMessage + "]";
+ return "RESTErrorResponseExeption [uuid=" + uuid + ", time=" + time + ", error=" + error + ", message=" + message + ", status=" + status + ", statusMessage=" + statusMessage + "]";
}
-
-
}
diff --git a/src/org/kar/archidata/exception/SystemException.java b/src/org/kar/archidata/exception/SystemException.java
index d5fe003..70e91bb 100644
--- a/src/org/kar/archidata/exception/SystemException.java
+++ b/src/org/kar/archidata/exception/SystemException.java
@@ -5,10 +5,12 @@ import jakarta.ws.rs.core.Response;
public class SystemException extends Exception {
private static final long serialVersionUID = 1L;
public final Response.Status status;
+
public SystemException(Response.Status status, String message) {
super(message);
this.status = status;
}
+
public SystemException(String message) {
super(message);
this.status = Response.Status.INTERNAL_SERVER_ERROR;
diff --git a/src/org/kar/archidata/exception/UnAuthorizedException.java b/src/org/kar/archidata/exception/UnAuthorizedException.java
index 731f277..54085b9 100644
--- a/src/org/kar/archidata/exception/UnAuthorizedException.java
+++ b/src/org/kar/archidata/exception/UnAuthorizedException.java
@@ -4,6 +4,7 @@ import jakarta.ws.rs.core.Response;
public class UnAuthorizedException extends FailException {
private static final long serialVersionUID = 1L;
+
public UnAuthorizedException(String message) {
super(Response.Status.UNAUTHORIZED, message);
}
diff --git a/src/org/kar/archidata/filter/AuthenticationFilter.java b/src/org/kar/archidata/filter/AuthenticationFilter.java
index e17de8b..3ad8231 100644
--- a/src/org/kar/archidata/filter/AuthenticationFilter.java
+++ b/src/org/kar/archidata/filter/AuthenticationFilter.java
@@ -1,10 +1,26 @@
package org.kar.archidata.filter;
+import java.io.IOException;
import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+// https://stackoverflow.com/questions/26777083/best-practice-for-rest-token-based-authentication-with-jax-rs-and-jersey
+// https://stackoverflow.com/questions/26777083/best-practice-for-rest-token-based-authentication-with-jax-rs-and-jersey/45814178#45814178
+// https://stackoverflow.com/questions/32817210/how-to-access-jersey-resource-secured-by-rolesallowed
+
import org.kar.archidata.annotation.security.DenyAll;
import org.kar.archidata.annotation.security.PermitAll;
+import org.kar.archidata.annotation.security.PermitTokenInURI;
import org.kar.archidata.annotation.security.RolesAllowed;
import org.kar.archidata.catcher.RestErrorResponse;
+import org.kar.archidata.model.UserByToken;
+import org.kar.archidata.util.JWTWrapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.nimbusds.jwt.JWTClaimsSet;
import jakarta.annotation.Priority;
import jakarta.ws.rs.Priorities;
@@ -18,23 +34,6 @@ import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.Provider;
-import org.kar.archidata.annotation.security.PermitTokenInURI;
-import org.kar.archidata.model.UserByToken;
-import org.kar.archidata.util.JWTWrapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.nimbusds.jwt.JWTClaimsSet;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-// https://stackoverflow.com/questions/26777083/best-practice-for-rest-token-based-authentication-with-jax-rs-and-jersey
-// https://stackoverflow.com/questions/26777083/best-practice-for-rest-token-based-authentication-with-jax-rs-and-jersey/45814178#45814178
-// https://stackoverflow.com/questions/32817210/how-to-access-jersey-resource-secured-by-rolesallowed
-
//@PreMatching
@Provider
@Priority(Priorities.AUTHENTICATION)
@@ -43,189 +42,183 @@ public class AuthenticationFilter implements ContainerRequestFilter {
@Context
private ResourceInfo resourceInfo;
protected final String applicationName;
-
- private static final String AUTHENTICATION_SCHEME = "Yota";
- private static final String AUTHENTICATION_TOKEN_SCHEME = "Zota";
-
-
-
- public AuthenticationFilter(String applicationName) {
+
+ private static final String AUTHENTICATION_SCHEME = "Yota";
+ private static final String AUTHENTICATION_TOKEN_SCHEME = "Zota";
+
+ public AuthenticationFilter(String applicationName) {
super();
this.applicationName = applicationName;
}
-
+
@Override
- public void filter(ContainerRequestContext requestContext) throws IOException {
- /*
- logger.debug("-----------------------------------------------------");
- logger.debug("---- Check if have authorization ----");
- logger.debug("-----------------------------------------------------");
- logger.debug(" for:{}", requestContext.getUriInfo().getPath());
- */
- Method method = resourceInfo.getResourceMethod();
- // Access denied for all
- if(method.isAnnotationPresent(DenyAll.class)) {
- logger.debug(" ==> deny all {}", requestContext.getUriInfo().getPath());
- requestContext.abortWith(Response.status(Response.Status.FORBIDDEN).entity("Access blocked !!!").build());
- return;
- }
-
- //Access allowed for all
- if( method.isAnnotationPresent(PermitAll.class)) {
- //logger.debug(" ==> permit all " + requestContext.getUriInfo().getPath());
- // no control ...
- return;
- }
- // this is a security guard, all the API must define their access level:
- if(!method.isAnnotationPresent(RolesAllowed.class)) {
- logger.error(" ==> missing @RolesAllowed {}", requestContext.getUriInfo().getPath());
- requestContext.abortWith(Response.status(Response.Status.FORBIDDEN).entity("Access ILLEGAL !!!").build());
- return;
- }
-
- // Get the Authorization header from the request
- String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
- //logger.debug("authorizationHeader: {}", authorizationHeader);
- if(authorizationHeader == null && method.isAnnotationPresent(PermitTokenInURI.class)) {
- MultivaluedMap quaryparam = requestContext.getUriInfo().getQueryParameters();
- for (Entry> item: quaryparam.entrySet()) {
- if (item.getKey().equals(HttpHeaders.AUTHORIZATION)) {
- if (!item.getValue().isEmpty()) {
- authorizationHeader = item.getValue().get(0);
- }
- break;
- }
- }
- }
- // logger.debug("authorizationHeader: {}", authorizationHeader);
- boolean isApplicationToken = isApplicationTokenBasedAuthentication(authorizationHeader);
- boolean isJwtToken = isTokenBasedAuthentication(authorizationHeader);
- // Validate the Authorization header data Model "Yota jwt.to.ken" "Zota tokenId:hash(token)"
- if (!isApplicationToken && !isJwtToken) {
- logger.warn("REJECTED unauthorized: {}", requestContext.getUriInfo().getPath());
- abortWithUnauthorized(requestContext, "REJECTED unauthorized: " + requestContext.getUriInfo().getPath());
- return;
- }
- UserByToken userByToken = null;
- if (isJwtToken) {
- // Extract the token from the Authorization header (Remove "Yota ")
- String token = authorizationHeader.substring(AUTHENTICATION_SCHEME.length()).trim();
- //logger.debug("token: {}", token);
- try {
- userByToken = validateJwtToken(token);
- } catch (Exception e) {
- logger.error("Fail to validate token: {}", e.getMessage());
- abortWithUnauthorized(requestContext, "Fail to validate token: " + e.getMessage());
- return;
- }
- if (userByToken == null) {
- logger.warn("get a NULL user ...");
- abortWithUnauthorized(requestContext, "get a NULL user ...");
- return;
- }
- } else {
- // Extract the token from the Authorization header (Remove "Zota ")
- String token = authorizationHeader.substring(AUTHENTICATION_TOKEN_SCHEME.length()).trim();
- //logger.debug("token: {}", token);
- try {
- userByToken = validateToken(token);
- } catch (Exception e) {
- logger.error("Fail to validate token: {}", e.getMessage());
- abortWithUnauthorized(requestContext, "Fail to validate token: "+ e.getMessage());
- return;
- }
- if (userByToken == null) {
- logger.warn("get a NULL application ...");
- abortWithUnauthorized(requestContext, "get a NULL application ...");
- return;
- }
-
- }
- // create the security context model:
- String scheme = requestContext.getUriInfo().getRequestUri().getScheme();
- MySecurityContext userContext = new MySecurityContext(userByToken, scheme);
- // retrieve the allowed right:
- RolesAllowed rolesAnnotation = method.getAnnotation(RolesAllowed.class);
- List roles = Arrays.asList(rolesAnnotation.value());
- // check if the user have the right:
- boolean haveRight = false;
- for (String role : roles) {
- if (userContext.isUserInRole(role)) {
- haveRight = true;
- break;
- }
- }
- //Is user valid?
- if( ! haveRight) {
- logger.error("REJECTED not enought right : {} require: {}", requestContext.getUriInfo().getPath(), roles);
- requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).entity("Not enought RIGHT !!!").build());
- return;
- }
- requestContext.setSecurityContext(userContext);
- // logger.debug("Get local user : {} / {}", user, userByToken);
- }
-
- private boolean isTokenBasedAuthentication(String authorizationHeader) {
- // Check if the Authorization header is valid
- // It must not be null and must be prefixed with "Bearer" plus a whitespace
- // The authentication scheme comparison must be case-insensitive
- return authorizationHeader != null && authorizationHeader.toLowerCase().startsWith(AUTHENTICATION_SCHEME.toLowerCase() + " ");
- }
-
- private boolean isApplicationTokenBasedAuthentication(String authorizationHeader) {
- // Check if the Authorization header is valid
- // It must not be null and must be prefixed with "Bearer" plus a whitespace
- // The authentication scheme comparison must be case-insensitive
- return authorizationHeader != null && authorizationHeader.toLowerCase().startsWith(AUTHENTICATION_TOKEN_SCHEME.toLowerCase() + " ");
- }
-
-
- private void abortWithUnauthorized(ContainerRequestContext requestContext, String message) {
-
- // Abort the filter chain with a 401 status code response
- // The WWW-Authenticate header is sent along with the response
- logger.warn("abortWithUnauthorized:");
+ public void filter(ContainerRequestContext requestContext) throws IOException {
+ /*
+ logger.debug("-----------------------------------------------------");
+ logger.debug("---- Check if have authorization ----");
+ logger.debug("-----------------------------------------------------");
+ logger.debug(" for:{}", requestContext.getUriInfo().getPath());
+ */
+ Method method = resourceInfo.getResourceMethod();
+ // Access denied for all
+ if (method.isAnnotationPresent(DenyAll.class)) {
+ logger.debug(" ==> deny all {}", requestContext.getUriInfo().getPath());
+ requestContext.abortWith(Response.status(Response.Status.FORBIDDEN).entity("Access blocked !!!").build());
+ return;
+ }
+
+ //Access allowed for all
+ if (method.isAnnotationPresent(PermitAll.class)) {
+ //logger.debug(" ==> permit all " + requestContext.getUriInfo().getPath());
+ // no control ...
+ return;
+ }
+ // this is a security guard, all the API must define their access level:
+ if (!method.isAnnotationPresent(RolesAllowed.class)) {
+ logger.error(" ==> missing @RolesAllowed {}", requestContext.getUriInfo().getPath());
+ requestContext.abortWith(Response.status(Response.Status.FORBIDDEN).entity("Access ILLEGAL !!!").build());
+ return;
+ }
+
+ // Get the Authorization header from the request
+ String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
+ //logger.debug("authorizationHeader: {}", authorizationHeader);
+ if (authorizationHeader == null && method.isAnnotationPresent(PermitTokenInURI.class)) {
+ MultivaluedMap quaryparam = requestContext.getUriInfo().getQueryParameters();
+ for (Entry> item : quaryparam.entrySet()) {
+ if (item.getKey().equals(HttpHeaders.AUTHORIZATION)) {
+ if (!item.getValue().isEmpty()) {
+ authorizationHeader = item.getValue().get(0);
+ }
+ break;
+ }
+ }
+ }
+ // logger.debug("authorizationHeader: {}", authorizationHeader);
+ boolean isApplicationToken = isApplicationTokenBasedAuthentication(authorizationHeader);
+ boolean isJwtToken = isTokenBasedAuthentication(authorizationHeader);
+ // Validate the Authorization header data Model "Yota jwt.to.ken" "Zota tokenId:hash(token)"
+ if (!isApplicationToken && !isJwtToken) {
+ logger.warn("REJECTED unauthorized: {}", requestContext.getUriInfo().getPath());
+ abortWithUnauthorized(requestContext, "REJECTED unauthorized: " + requestContext.getUriInfo().getPath());
+ return;
+ }
+ UserByToken userByToken = null;
+ if (isJwtToken) {
+ // Extract the token from the Authorization header (Remove "Yota ")
+ String token = authorizationHeader.substring(AUTHENTICATION_SCHEME.length()).trim();
+ //logger.debug("token: {}", token);
+ try {
+ userByToken = validateJwtToken(token);
+ } catch (Exception e) {
+ logger.error("Fail to validate token: {}", e.getMessage());
+ abortWithUnauthorized(requestContext, "Fail to validate token: " + e.getMessage());
+ return;
+ }
+ if (userByToken == null) {
+ logger.warn("get a NULL user ...");
+ abortWithUnauthorized(requestContext, "get a NULL user ...");
+ return;
+ }
+ } else {
+ // Extract the token from the Authorization header (Remove "Zota ")
+ String token = authorizationHeader.substring(AUTHENTICATION_TOKEN_SCHEME.length()).trim();
+ //logger.debug("token: {}", token);
+ try {
+ userByToken = validateToken(token);
+ } catch (Exception e) {
+ logger.error("Fail to validate token: {}", e.getMessage());
+ abortWithUnauthorized(requestContext, "Fail to validate token: " + e.getMessage());
+ return;
+ }
+ if (userByToken == null) {
+ logger.warn("get a NULL application ...");
+ abortWithUnauthorized(requestContext, "get a NULL application ...");
+ return;
+ }
+
+ }
+ // create the security context model:
+ String scheme = requestContext.getUriInfo().getRequestUri().getScheme();
+ MySecurityContext userContext = new MySecurityContext(userByToken, scheme);
+ // retrieve the allowed right:
+ RolesAllowed rolesAnnotation = method.getAnnotation(RolesAllowed.class);
+ List roles = Arrays.asList(rolesAnnotation.value());
+ // check if the user have the right:
+ boolean haveRight = false;
+ for (String role : roles) {
+ if (userContext.isUserInRole(role)) {
+ haveRight = true;
+ break;
+ }
+ }
+ //Is user valid?
+ if (!haveRight) {
+ logger.error("REJECTED not enought right : {} require: {}", requestContext.getUriInfo().getPath(), roles);
+ requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).entity("Not enought RIGHT !!!").build());
+ return;
+ }
+ requestContext.setSecurityContext(userContext);
+ // logger.debug("Get local user : {} / {}", user, userByToken);
+ }
+
+ private boolean isTokenBasedAuthentication(String authorizationHeader) {
+ // Check if the Authorization header is valid
+ // It must not be null and must be prefixed with "Bearer" plus a whitespace
+ // The authentication scheme comparison must be case-insensitive
+ return authorizationHeader != null && authorizationHeader.toLowerCase().startsWith(AUTHENTICATION_SCHEME.toLowerCase() + " ");
+ }
+
+ private boolean isApplicationTokenBasedAuthentication(String authorizationHeader) {
+ // Check if the Authorization header is valid
+ // It must not be null and must be prefixed with "Bearer" plus a whitespace
+ // The authentication scheme comparison must be case-insensitive
+ return authorizationHeader != null && authorizationHeader.toLowerCase().startsWith(AUTHENTICATION_TOKEN_SCHEME.toLowerCase() + " ");
+ }
+
+ private void abortWithUnauthorized(ContainerRequestContext requestContext, String message) {
+
+ // Abort the filter chain with a 401 status code response
+ // The WWW-Authenticate header is sent along with the response
+ logger.warn("abortWithUnauthorized:");
RestErrorResponse ret = new RestErrorResponse(Response.Status.UNAUTHORIZED, "Unauthorized", message);
logger.error("Error UUID={}", ret.uuid);
- requestContext.abortWith(Response.status(ret.status)
- .header(HttpHeaders.WWW_AUTHENTICATE,
- AUTHENTICATION_SCHEME + " base64(HEADER).base64(CONTENT).base64(KEY)")
- .entity(ret)
- .type(MediaType.APPLICATION_JSON)
- .build());
- }
-
- protected UserByToken validateToken(String authorization) throws Exception {
- logger.info("Must be Override by the application implmentation, otherwise it dose not work");
- return null;
- }
- // must be override to be good implementation
- protected UserByToken validateJwtToken(String authorization) throws Exception {
- //logger.debug(" validate token : " + authorization);
- JWTClaimsSet ret = JWTWrapper.validateToken(authorization, "KarAuth", null);
- // check the token is valid !!! (signed and coherent issuer...
- if (ret == null) {
- logger.error("The token is not valid: '{}'", authorization);
- return null;
- }
- // check userID
- String userUID = ret.getSubject();
- long id = Long.parseLong(userUID);
- UserByToken user = new UserByToken();
- user.id = id;
- user.name = (String)ret.getClaim("login");
- user.type = UserByToken.TYPE_USER;
- Object rowRight = ret.getClaim("right");
- if (rowRight != null) {
- Map> rights = (Map>) ret.getClaim("right");
- if (rights.containsKey(this.applicationName)) {
- user.right = rights.get(this.applicationName);
- } else {
- logger.error("Connect with no right for this application='{}' full Right='{}'", this.applicationName, rights);
- }
- }
- //logger.debug("request user: '{}' right: '{}' row='{}'", userUID, user.right, rowRight);
- return user;
- //return UserDB.getUserOrCreate(id, (String)ret.getClaim("login") );
- }
+ requestContext.abortWith(Response.status(ret.status).header(HttpHeaders.WWW_AUTHENTICATE, AUTHENTICATION_SCHEME + " base64(HEADER).base64(CONTENT).base64(KEY)").entity(ret)
+ .type(MediaType.APPLICATION_JSON).build());
+ }
+
+ protected UserByToken validateToken(String authorization) throws Exception {
+ logger.info("Must be Override by the application implmentation, otherwise it dose not work");
+ return null;
+ }
+
+ // must be override to be good implementation
+ protected UserByToken validateJwtToken(String authorization) throws Exception {
+ //logger.debug(" validate token : " + authorization);
+ JWTClaimsSet ret = JWTWrapper.validateToken(authorization, "KarAuth", null);
+ // check the token is valid !!! (signed and coherent issuer...
+ if (ret == null) {
+ logger.error("The token is not valid: '{}'", authorization);
+ return null;
+ }
+ // check userID
+ String userUID = ret.getSubject();
+ long id = Long.parseLong(userUID);
+ UserByToken user = new UserByToken();
+ user.id = id;
+ user.name = (String) ret.getClaim("login");
+ user.type = UserByToken.TYPE_USER;
+ Object rowRight = ret.getClaim("right");
+ if (rowRight != null) {
+ Map> rights = (Map>) ret.getClaim("right");
+ if (rights.containsKey(this.applicationName)) {
+ user.right = rights.get(this.applicationName);
+ } else {
+ logger.error("Connect with no right for this application='{}' full Right='{}'", this.applicationName, rights);
+ }
+ }
+ //logger.debug("request user: '{}' right: '{}' row='{}'", userUID, user.right, rowRight);
+ return user;
+ //return UserDB.getUserOrCreate(id, (String)ret.getClaim("login") );
+ }
}
diff --git a/src/org/kar/archidata/filter/CORSFilter.java b/src/org/kar/archidata/filter/CORSFilter.java
index 9046e6d..6675bc9 100644
--- a/src/org/kar/archidata/filter/CORSFilter.java
+++ b/src/org/kar/archidata/filter/CORSFilter.java
@@ -1,25 +1,23 @@
package org.kar.archidata.filter;
+import java.io.IOException;
+
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerResponseContext;
import jakarta.ws.rs.container.ContainerResponseFilter;
import jakarta.ws.rs.ext.Provider;
-import java.io.IOException;
-
@Provider
public class CORSFilter implements ContainerResponseFilter {
-
- @Override
- public void filter(ContainerRequestContext request,
- ContainerResponseContext response) throws IOException {
- //System.err.println("filter cors ..." + request.toString());
-
- response.getHeaders().add("Access-Control-Allow-Origin", "*");
- response.getHeaders().add("Access-Control-Allow-Headers", "*");
- // "Origin, content-type, Content-type, Accept, authorization, mime-type, filename");
- response.getHeaders().add("Access-Control-Allow-Credentials", "true");
- response.getHeaders().add("Access-Control-Allow-Methods",
- "GET, POST, PUT, DELETE, OPTIONS, HEAD");
- }
+
+ @Override
+ public void filter(ContainerRequestContext request, ContainerResponseContext response) throws IOException {
+ //System.err.println("filter cors ..." + request.toString());
+
+ response.getHeaders().add("Access-Control-Allow-Origin", "*");
+ response.getHeaders().add("Access-Control-Allow-Headers", "*");
+ // "Origin, content-type, Content-type, Accept, authorization, mime-type, filename");
+ response.getHeaders().add("Access-Control-Allow-Credentials", "true");
+ response.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
+ }
}
diff --git a/src/org/kar/archidata/filter/GenericContext.java b/src/org/kar/archidata/filter/GenericContext.java
index b7a177f..4fbaa2e 100644
--- a/src/org/kar/archidata/filter/GenericContext.java
+++ b/src/org/kar/archidata/filter/GenericContext.java
@@ -1,22 +1,22 @@
package org.kar.archidata.filter;
-import org.kar.archidata.model.UserByToken;
-
import java.security.Principal;
+import org.kar.archidata.model.UserByToken;
+
public class GenericContext implements Principal {
-
- public UserByToken userByToken;
-
- public GenericContext(UserByToken userByToken) {
- this.userByToken = userByToken;
- }
-
- @Override
- public String getName() {
- if (this.userByToken == null) {
- return "???";
- }
- return this.userByToken.name;
- }
+
+ public UserByToken userByToken;
+
+ public GenericContext(UserByToken userByToken) {
+ this.userByToken = userByToken;
+ }
+
+ @Override
+ public String getName() {
+ if (this.userByToken == null) {
+ return "???";
+ }
+ return this.userByToken.name;
+ }
}
diff --git a/src/org/kar/archidata/filter/MySecurityContext.java b/src/org/kar/archidata/filter/MySecurityContext.java
index a5e442e..a66453c 100644
--- a/src/org/kar/archidata/filter/MySecurityContext.java
+++ b/src/org/kar/archidata/filter/MySecurityContext.java
@@ -1,48 +1,49 @@
package org.kar.archidata.filter;
+import java.security.Principal;
+
import org.kar.archidata.model.UserByToken;
import jakarta.ws.rs.core.SecurityContext;
-import java.security.Principal;
// https://simplapi.wordpress.com/2015/09/19/jersey-jax-rs-securitycontext-in-action/
class MySecurityContext implements SecurityContext {
-
- private final GenericContext contextPrincipale;
- private final String sheme;
-
- public MySecurityContext(UserByToken userByToken, String sheme) {
- this.contextPrincipale = new GenericContext(userByToken);
- this.sheme = sheme;
- }
-
- @Override
- public Principal getUserPrincipal() {
- return contextPrincipale;
- }
-
- @Override
- public boolean isUserInRole(String role) {
- if (contextPrincipale.userByToken != null) {
- Object value = this.contextPrincipale.userByToken.right.get(role);
- if (value instanceof Boolean ret) {
- return ret;
- }
- }
- return false;
- }
-
- @Override
- public boolean isSecure() {
- return sheme.equalsIgnoreCase("https");
- }
-
- @Override
- public String getAuthenticationScheme() {
- if (contextPrincipale.userByToken != null) {
- return "Zota";
- }
- return null;
- }
-
+
+ private final GenericContext contextPrincipale;
+ private final String sheme;
+
+ public MySecurityContext(UserByToken userByToken, String sheme) {
+ this.contextPrincipale = new GenericContext(userByToken);
+ this.sheme = sheme;
+ }
+
+ @Override
+ public Principal getUserPrincipal() {
+ return contextPrincipale;
+ }
+
+ @Override
+ public boolean isUserInRole(String role) {
+ if (contextPrincipale.userByToken != null) {
+ Object value = this.contextPrincipale.userByToken.right.get(role);
+ if (value instanceof Boolean ret) {
+ return ret;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isSecure() {
+ return sheme.equalsIgnoreCase("https");
+ }
+
+ @Override
+ public String getAuthenticationScheme() {
+ if (contextPrincipale.userByToken != null) {
+ return "Zota";
+ }
+ return null;
+ }
+
}
\ No newline at end of file
diff --git a/src/org/kar/archidata/filter/OptionFilter.java b/src/org/kar/archidata/filter/OptionFilter.java
index a1282d3..cff309a 100644
--- a/src/org/kar/archidata/filter/OptionFilter.java
+++ b/src/org/kar/archidata/filter/OptionFilter.java
@@ -1,21 +1,20 @@
package org.kar.archidata.filter;
+import java.io.IOException;
+
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerRequestFilter;
import jakarta.ws.rs.container.PreMatching;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.Provider;
-import java.io.IOException;
@Provider
@PreMatching
public class OptionFilter implements ContainerRequestFilter {
- @Override
- public void filter(ContainerRequestContext requestContext) throws IOException {
- if (requestContext.getMethod().contentEquals("OPTIONS")) {
- requestContext.abortWith(Response.status(Response.Status.NO_CONTENT).build());
- }
- }
+ @Override
+ public void filter(ContainerRequestContext requestContext) throws IOException {
+ if (requestContext.getMethod().contentEquals("OPTIONS")) {
+ requestContext.abortWith(Response.status(Response.Status.NO_CONTENT).build());
+ }
+ }
}
-
-
diff --git a/src/org/kar/archidata/migration/MigrationEngine.java b/src/org/kar/archidata/migration/MigrationEngine.java
index 62736b6..41e024b 100644
--- a/src/org/kar/archidata/migration/MigrationEngine.java
+++ b/src/org/kar/archidata/migration/MigrationEngine.java
@@ -25,15 +25,17 @@ public class MigrationEngine {
public MigrationEngine() {
this(new ArrayList(), null);
}
+
/**
* Migration engine constructor (specific mode).
* @param datas All the migration ordered.
* @param init Initialization migration model.
*/
- public MigrationEngine( List datas, MigrationInterface init) {
+ public MigrationEngine(List datas, MigrationInterface init) {
this.datas = datas;
this.init = init;
}
+
/**
* Add a Migration in the list
* @param migration Migration to add.
@@ -41,6 +43,7 @@ public class MigrationEngine {
public void add(MigrationInterface migration) {
this.datas.add(migration);
}
+
/**
* Set first initialization class
* @param migration migration class for first init.
@@ -48,6 +51,7 @@ public class MigrationEngine {
public void setInit(MigrationInterface migration) {
init = migration;
}
+
/**
* Get the current version/migration name
* @return Model represent the last migration. If null then no migration has been done.
@@ -59,7 +63,7 @@ public class MigrationEngine {
try {
List data = SqlWrapper.gets(MigrationModel.class, false);
if (data == null) {
- LOGGER.error("Can not collect the migration table in the DB:{}" );
+ LOGGER.error("Can not collect the migration table in the DB:{}");
return null;
}
if (data.size() == 0) {
@@ -68,15 +72,16 @@ public class MigrationEngine {
}
LOGGER.debug("List of migrations:");
for (MigrationModel elem : data) {
- LOGGER.debug(" - date={} name={} end={}", elem.modify_date, elem.name, elem.terminated);
+ LOGGER.debug(" - date={} name={} end={}", elem.modify_date, elem.name, elem.terminated);
}
- return data.get(data.size()-1);
+ return data.get(data.size() - 1);
} catch (Exception ex) {
LOGGER.error("Fail to Request migration table in the DB:{}", ex.getMessage());
ex.printStackTrace();
}
return null;
}
+
/**
* Process the automatic migration of the system
* @param config SQL connection for the migration
@@ -85,11 +90,11 @@ public class MigrationEngine {
*/
public void migrate(DBConfig config) throws InterruptedException, IOException {
LOGGER.info("Execute migration ... [BEGIN]");
-
+
// STEP 1: Check the DB exist:
LOGGER.info("Verify existance of '{}'", config.getDbName());
boolean exist = SqlWrapper.isDBExist(config.getDbName());
- if(!exist) {
+ if (!exist) {
LOGGER.warn("DB: '{}' DOES NOT EXIST ==> create one", config.getDbName());
// create the local DB:
SqlWrapper.createDB(config.getDbName());
@@ -114,7 +119,7 @@ public class MigrationEngine {
ex.printStackTrace();
while (true) {
LOGGER.error("Fail to create the local DB SQL model for migaration ==> wait administrator interventions");
- Thread.sleep(60*60*1000);
+ Thread.sleep(60 * 60 * 1000);
}
}
LOGGER.info("Create Table with : {}", sqlQuery.get(0));
@@ -124,7 +129,7 @@ public class MigrationEngine {
ex.printStackTrace();
while (true) {
LOGGER.error("Fail to create the local DB model for migaration ==> wait administrator interventions");
- Thread.sleep(60*60*1000);
+ Thread.sleep(60 * 60 * 1000);
}
}
}
@@ -142,15 +147,15 @@ public class MigrationEngine {
// nothing to do the initialization model is alone and it is the first time
} else {
// we insert a placeholder to simulate all migration is well done.
- String placeholderName = this.datas.get(this.datas.size()-1).getName();
+ String placeholderName = this.datas.get(this.datas.size() - 1).getName();
MigrationModel migrationResult = new MigrationModel();
- migrationResult.name = placeholderName;
+ migrationResult.name = placeholderName;
migrationResult.stepId = 0;
migrationResult.terminated = true;
- migrationResult.count = 0;
- migrationResult.log = "Place-holder for first initialization";
- try {
- migrationResult = SqlWrapper.insert(migrationResult);
+ migrationResult.count = 0;
+ migrationResult.log = "Place-holder for first initialization";
+ try {
+ migrationResult = SqlWrapper.insert(migrationResult);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
@@ -158,9 +163,9 @@ public class MigrationEngine {
}
} else {
if (currentVersion.terminated == false) {
- while(true) {
- LOGGER.error("An error occured in the last migration: '{}' defect @{}/{} ==> wait administrator interventions", currentVersion.name , currentVersion.stepId, currentVersion.count);
- Thread.sleep(60*60*1000);
+ while (true) {
+ LOGGER.error("An error occured in the last migration: '{}' defect @{}/{} ==> wait administrator interventions", currentVersion.name, currentVersion.stepId, currentVersion.count);
+ Thread.sleep(60 * 60 * 1000);
}
}
LOGGER.info("Upgrade the system Current version: {}", currentVersion.name);
@@ -168,8 +173,8 @@ public class MigrationEngine {
if (currentVersion.name.equals(this.init.getName())) {
toApply = this.datas;
} else {
- for (int iii=0; iii wait administrator interventions", migrationResult.name , migrationResult.stepId, migrationResult.count);
+ while (true) {
+ LOGGER.error("An error occured in the migration (OUTSIDE detection): '{}' defect @{}/{} ==> wait administrator interventions", migrationResult.name, migrationResult.stepId,
+ migrationResult.count);
try {
- Thread.sleep(60*60*1000);
+ Thread.sleep(60 * 60 * 1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
@@ -231,13 +238,13 @@ public class MigrationEngine {
}
LOGGER.info("Migrate: [{}/{}] {} [ END ]", id, count, elem.getName());
}
-
+
public void revertTo(DBEntry entry, String migrationName) {
MigrationModel currentVersion = getCurrentVersion();
List toApply = new ArrayList<>();
boolean find = false;
- for (int iii=this.datas.size()-1; iii>=0; iii--) {
- if ( ! find) {
+ for (int iii = this.datas.size() - 1; iii >= 0; iii--) {
+ if (!find) {
if (this.datas.get(iii).getName() == currentVersion.name) {
find = true;
}
@@ -254,6 +261,7 @@ public class MigrationEngine {
revertSingle(entry, elem, id, count);
}
}
+
public void revertSingle(DBEntry entry, MigrationInterface elem, int id, int count) {
LOGGER.info("Revert migration: {} [BEGIN]", elem.getName());
diff --git a/src/org/kar/archidata/migration/MigrationException.java b/src/org/kar/archidata/migration/MigrationException.java
index 80afc2c..55c24a3 100644
--- a/src/org/kar/archidata/migration/MigrationException.java
+++ b/src/org/kar/archidata/migration/MigrationException.java
@@ -1,7 +1,7 @@
package org.kar.archidata.migration;
public class MigrationException extends Exception {
-
+
private static final long serialVersionUID = 20230502L;
}
diff --git a/src/org/kar/archidata/migration/MigrationInterface.java b/src/org/kar/archidata/migration/MigrationInterface.java
index cf2a561..f0100fa 100644
--- a/src/org/kar/archidata/migration/MigrationInterface.java
+++ b/src/org/kar/archidata/migration/MigrationInterface.java
@@ -8,6 +8,7 @@ public interface MigrationInterface {
* @return Migration name
*/
String getName();
+
/**
* Migrate the system to a new version.
* @param entry DB interface for the migration.
@@ -16,6 +17,7 @@ public interface MigrationInterface {
* @return true if migration is finished.
*/
boolean applyMigration(DBEntry entry, StringBuilder log, MigrationModel model);
+
/**
* Remove a migration the system to the previous version.
* @param entry DB interface for the migration.
diff --git a/src/org/kar/archidata/migration/MigrationModel.java b/src/org/kar/archidata/migration/MigrationModel.java
index bb2fbaa..999b6de 100644
--- a/src/org/kar/archidata/migration/MigrationModel.java
+++ b/src/org/kar/archidata/migration/MigrationModel.java
@@ -3,31 +3,31 @@ package org.kar.archidata.migration;
import org.kar.archidata.annotation.SQLComment;
import org.kar.archidata.annotation.SQLDefault;
import org.kar.archidata.annotation.SQLIfNotExists;
-import org.kar.archidata.annotation.SQLLimitSize;
-import org.kar.archidata.annotation.SQLNotNull;
-import org.kar.archidata.annotation.SQLTableName;
import org.kar.archidata.model.GenericTable;
import com.fasterxml.jackson.annotation.JsonInclude;
+import jakarta.persistence.Column;
+import jakarta.persistence.Table;
+
// For logs only
//public static final String TABLE_NAME = "KAR_migration";
-@SQLTableName ("KAR_migration")
+@Table(name = "KAR_migration")
@SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL)
-public class MigrationModel extends GenericTable{
+public class MigrationModel extends GenericTable {
@SQLComment("Name of the migration")
- @SQLLimitSize(256)
- public String name;
- @SQLNotNull
+ @Column(length = 256)
+ public String name;
+ @Column(nullable = false)
@SQLDefault("'0'")
- @SQLComment("if the migration is well terminated or not")
- public Boolean terminated = false;
- @SQLComment("index in the migration progression")
- public Integer stepId = 0;
- @SQLComment("number of element in the migration")
- public Integer count;
- @SQLComment("Log generate by the migration")
- public String log = "";
+ @SQLComment("if the migration is well terminated or not")
+ public Boolean terminated = false;
+ @SQLComment("index in the migration progression")
+ public Integer stepId = 0;
+ @SQLComment("number of element in the migration")
+ public Integer count;
+ @SQLComment("Log generate by the migration")
+ public String log = "";
}
diff --git a/src/org/kar/archidata/migration/MigrationSqlStep.java b/src/org/kar/archidata/migration/MigrationSqlStep.java
index d3b956f..cd34cb3 100644
--- a/src/org/kar/archidata/migration/MigrationSqlStep.java
+++ b/src/org/kar/archidata/migration/MigrationSqlStep.java
@@ -12,19 +12,26 @@ import org.slf4j.LoggerFactory;
public class MigrationSqlStep implements MigrationInterface {
final static Logger LOGGER = LoggerFactory.getLogger(MigrationSqlStep.class);
- private List actions = new ArrayList<>();
-
+ private final List actions = new ArrayList<>();
+
@Override
public String getName() {
return getClass().getCanonicalName();
}
+ public void display() {
+ for (int iii = 0; iii < this.actions.size(); iii++) {
+ final String action = this.actions.get(iii);
+ LOGGER.info(" >>>> SQL ACTION : {}/{} ==> \n{}", iii, this.actions.size(), action);
+ }
+ }
+
@Override
- public boolean applyMigration(DBEntry entry, StringBuilder log, MigrationModel model) {
- for (int iii=0; iii>>> SQL ACTION : {}/{}", iii, actions.size());
- String action = actions.get(iii);
+ public boolean applyMigration(final DBEntry entry, final StringBuilder log, final MigrationModel model) {
+ for (int iii = 0; iii < this.actions.size(); iii++) {
+ log.append("action [" + iii + "/" + this.actions.size() + "]\n");
+ LOGGER.info(" >>>> SQL ACTION : {}/{}", iii, this.actions.size());
+ final String action = this.actions.get(iii);
LOGGER.info("SQL request: ```{}```", action);
log.append("SQL: " + action + "\n");
try {
@@ -33,28 +40,28 @@ public class MigrationSqlStep implements MigrationInterface {
ex.printStackTrace();
LOGGER.info("SQL request ERROR: ", ex.getMessage());
log.append("SQL request ERROR: " + ex.getMessage() + "\n");
- model.stepId = iii+1;
+ model.stepId = iii + 1;
model.log = log.toString();
- try {
- SqlWrapper.update(model, model.id, List.of("stepId", "log"));
- } catch (Exception e) {
+ try {
+ SqlWrapper.update(model, model.id, List.of("stepId", "log"));
+ } catch (final Exception e) {
e.printStackTrace();
}
return false;
}
- log.append("action [" + iii + "/" + actions.size() + "] ==> DONE\n");
- LOGGER.info(" >>>> SQL ACTION : {}/{} ==> DONE", iii, actions.size());
- model.stepId = iii+1;
+ log.append("action [" + iii + "/" + this.actions.size() + "] ==> DONE\n");
+ LOGGER.info(" >>>> SQL ACTION : {}/{} ==> DONE", iii, this.actions.size());
+ model.stepId = iii + 1;
model.log = log.toString();
- try {
- SqlWrapper.update(model, model.id, List.of("stepId", "log"));
- } catch (Exception e) {
+ try {
+ SqlWrapper.update(model, model.id, List.of("stepId", "log"));
+ } catch (final Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
- try {
+ try {
Thread.sleep(100);
- } catch (InterruptedException e) {
+ } catch (final InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
@@ -63,21 +70,22 @@ public class MigrationSqlStep implements MigrationInterface {
}
@Override
- public boolean revertMigration(DBEntry entry, StringBuilder log) {
+ public boolean revertMigration(final DBEntry entry, final StringBuilder log) {
return false;
}
- public void addAction(String action) {
- actions.add(action);
+ public void addAction(final String action) {
+ this.actions.add(action);
}
- public void addClass(Class> clazz) throws Exception {
- List tmp = SqlWrapper.createTable(clazz, false);
- actions.addAll(tmp);
+
+ public void addClass(final Class> clazz) throws Exception {
+ final List tmp = SqlWrapper.createTable(clazz, false);
+ this.actions.addAll(tmp);
}
@Override
public int getNumberOfStep() {
- return actions.size();
+ return this.actions.size();
}
}
diff --git a/src/org/kar/archidata/model/Data.java b/src/org/kar/archidata/model/Data.java
index a63502f..2bef3b7 100644
--- a/src/org/kar/archidata/model/Data.java
+++ b/src/org/kar/archidata/model/Data.java
@@ -1,28 +1,25 @@
package org.kar.archidata.model;
-
import org.kar.archidata.annotation.SQLComment;
import org.kar.archidata.annotation.SQLIfNotExists;
-import org.kar.archidata.annotation.SQLLimitSize;
-import org.kar.archidata.annotation.SQLNotNull;
-import org.kar.archidata.annotation.SQLTableName;
import com.fasterxml.jackson.annotation.JsonInclude;
-@SQLTableName ("data")
+import jakarta.persistence.Column;
+import jakarta.persistence.Table;
+
+@Table(name = "data")
@SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Data extends GenericTable {
- @SQLNotNull
- @SQLLimitSize(128)
- @SQLComment("Sha512 of the data")
- public String sha512;
- @SQLNotNull
- @SQLLimitSize(128)
- @SQLComment("Mime -type of the media")
- public String mimeType;
- @SQLNotNull
- @SQLComment("Size in Byte of the data")
- public Long size;
+ @Column(length = 128, nullable = false)
+ @SQLComment("Sha512 of the data")
+ public String sha512;
+ @Column(length = 128, nullable = false)
+ @SQLComment("Mime -type of the media")
+ public String mimeType;
+ @Column(nullable = false)
+ @SQLComment("Size in Byte of the data")
+ public Long size;
}
diff --git a/src/org/kar/archidata/model/GenericTable.java b/src/org/kar/archidata/model/GenericTable.java
index 5a3a7db..20fb800 100644
--- a/src/org/kar/archidata/model/GenericTable.java
+++ b/src/org/kar/archidata/model/GenericTable.java
@@ -2,38 +2,40 @@ package org.kar.archidata.model;
import java.sql.Timestamp;
-import org.kar.archidata.annotation.SQLAutoIncrement;
+import org.kar.archidata.annotation.CreationTimestamp;
import org.kar.archidata.annotation.SQLComment;
-import org.kar.archidata.annotation.SQLCreateTime;
import org.kar.archidata.annotation.SQLDefault;
import org.kar.archidata.annotation.SQLDeleted;
-import org.kar.archidata.annotation.SQLNotNull;
import org.kar.archidata.annotation.SQLNotRead;
-import org.kar.archidata.annotation.SQLPrimaryKey;
-import org.kar.archidata.annotation.SQLUpdateTime;
+import org.kar.archidata.annotation.UpdateTimestamp;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
public class GenericTable {
- @SQLAutoIncrement // Add AUTO_INCREMENT modifier
- @SQLPrimaryKey // Create a PRIMARY KEY based on this field
- @SQLNotNull
- @SQLComment("Primary key of the base")
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(nullable = false, unique = true)
+ @SQLComment("Primary key of the base")
public Long id = null;
- @SQLNotRead
- @SQLNotNull
- @SQLDefault("'0'")
- @SQLDeleted
- @SQLComment("When delete, they are not removed, they are just set in a deleted state")
+ @SQLNotRead
+ @Column(nullable = false)
+ @SQLDefault("'0'")
+ @SQLDeleted
+ @SQLComment("When delete, they are not removed, they are just set in a deleted state")
public Boolean deleted = null;
- @SQLNotRead
- @SQLCreateTime
- @SQLNotNull
- @SQLComment("Create time of the object")
- @SQLDefault("CURRENT_TIMESTAMP(3)")
+ @SQLNotRead
+ @CreationTimestamp
+ @Column(nullable = false)
+ @SQLComment("Create time of the object")
+ @SQLDefault("CURRENT_TIMESTAMP(3)")
public Timestamp create_date = null;
- @SQLNotRead
- @SQLUpdateTime
- @SQLNotNull
- @SQLComment("When update the object")
- @SQLDefault("CURRENT_TIMESTAMP(3)")
+ @SQLNotRead
+ @UpdateTimestamp
+ @Column(nullable = false)
+ @SQLComment("When update the object")
+ @SQLDefault("CURRENT_TIMESTAMP(3)")
public Timestamp modify_date = null;
}
diff --git a/src/org/kar/archidata/model/GenericToken.java b/src/org/kar/archidata/model/GenericToken.java
index 5f6195d..ed56849 100644
--- a/src/org/kar/archidata/model/GenericToken.java
+++ b/src/org/kar/archidata/model/GenericToken.java
@@ -3,21 +3,22 @@ package org.kar.archidata.model;
import java.sql.Timestamp;
import org.kar.archidata.annotation.SQLIfNotExists;
-import org.kar.archidata.annotation.SQLNotNull;
-import org.kar.archidata.annotation.SQLTableName;
import com.fasterxml.jackson.annotation.JsonInclude;
-@SQLTableName ("applicationToken")
+import jakarta.persistence.Column;
+import jakarta.persistence.Table;
+
+@Table(name = "applicationToken")
@SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL)
public class GenericToken extends GenericTable {
- @SQLNotNull
- public Long parentId;
- @SQLNotNull
- public String name;
- @SQLNotNull
- public Timestamp endValidityTime = null;
- @SQLNotNull
- public String token;
+ @Column(nullable = false)
+ public Long parentId;
+ @Column(nullable = false)
+ public String name;
+ @Column(nullable = false)
+ public Timestamp endValidityTime = null;
+ @Column(nullable = false)
+ public String token;
}
diff --git a/src/org/kar/archidata/model/GetToken.java b/src/org/kar/archidata/model/GetToken.java
index 1f6390e..a57eb03 100644
--- a/src/org/kar/archidata/model/GetToken.java
+++ b/src/org/kar/archidata/model/GetToken.java
@@ -3,6 +3,7 @@ package org.kar.archidata.model;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonInclude(JsonInclude.Include.NON_NULL)
-public record GetToken(String jwt) {
+public record GetToken(
+ String jwt) {
}
diff --git a/src/org/kar/archidata/model/Migration.java b/src/org/kar/archidata/model/Migration.java
index 66a1bb6..f8e942c 100644
--- a/src/org/kar/archidata/model/Migration.java
+++ b/src/org/kar/archidata/model/Migration.java
@@ -1,6 +1,6 @@
package org.kar.archidata.model;
-public class Migration extends GenericTable{
- public String migrationId;
-
+public class Migration extends GenericTable {
+ public String migrationId;
+
}
diff --git a/src/org/kar/archidata/model/Token.java b/src/org/kar/archidata/model/Token.java
index 61f1ae6..28da800 100644
--- a/src/org/kar/archidata/model/Token.java
+++ b/src/org/kar/archidata/model/Token.java
@@ -3,46 +3,38 @@ package org.kar.archidata.model;
import java.sql.ResultSet;
import java.sql.SQLException;
-
public class Token {
- public Long id;
- public Long userId;
- public String token;
- public String createTime;
- public String endValidityTime;
-
- public Token() {
- }
-
- public Token(long id, long userId, String token, String createTime, String endValidityTime) {
- this.id = id;
- this.userId = userId;
- this.token = token;
- this.createTime = createTime;
- this.endValidityTime = endValidityTime;
- }
-
- public Token(ResultSet rs) {
- int iii = 1;
- try {
- this.id = rs.getLong(iii++);
- this.userId = rs.getLong(iii++);
- this.token = rs.getString(iii++);
- this.createTime = rs.getString(iii++);
- this.endValidityTime = rs.getString(iii++);
- } catch (SQLException ex) {
- ex.printStackTrace();
- }
- }
-
- @Override
- public String toString() {
- return "Token{" +
- "id=" + id +
- ", userId=" + userId +
- ", token='" + token + '\'' +
- ", createTime=" + createTime +
- ", endValidityTime=" + endValidityTime +
- '}';
- }
+ public Long id;
+ public Long userId;
+ public String token;
+ public String createTime;
+ public String endValidityTime;
+
+ public Token() {}
+
+ public Token(long id, long userId, String token, String createTime, String endValidityTime) {
+ this.id = id;
+ this.userId = userId;
+ this.token = token;
+ this.createTime = createTime;
+ this.endValidityTime = endValidityTime;
+ }
+
+ public Token(ResultSet rs) {
+ int iii = 1;
+ try {
+ this.id = rs.getLong(iii++);
+ this.userId = rs.getLong(iii++);
+ this.token = rs.getString(iii++);
+ this.createTime = rs.getString(iii++);
+ this.endValidityTime = rs.getString(iii++);
+ } catch (SQLException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "Token{" + "id=" + id + ", userId=" + userId + ", token='" + token + '\'' + ", createTime=" + createTime + ", endValidityTime=" + endValidityTime + '}';
+ }
}
diff --git a/src/org/kar/archidata/model/User.java b/src/org/kar/archidata/model/User.java
index 30a44c6..c5acec3 100644
--- a/src/org/kar/archidata/model/User.java
+++ b/src/org/kar/archidata/model/User.java
@@ -15,35 +15,43 @@ CREATE TABLE `user` (
*/
import java.sql.Timestamp;
+import java.util.List;
import org.kar.archidata.annotation.SQLDefault;
import org.kar.archidata.annotation.SQLIfNotExists;
-import org.kar.archidata.annotation.SQLLimitSize;
-import org.kar.archidata.annotation.SQLNotNull;
-import org.kar.archidata.annotation.SQLTableName;
+import org.kar.archidata.sqlWrapper.Foreign;
import com.fasterxml.jackson.annotation.JsonInclude;
-@SQLTableName ("user")
+import jakarta.persistence.Column;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.Table;
+
+@Table(name = "user")
@SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL)
public class User extends GenericTable {
- @SQLLimitSize(128)
- public String login = null;
-
- public Timestamp lastConnection = null;
- @SQLDefault("'0'")
- @SQLNotNull
- public boolean admin = false;
- @SQLDefault("'0'")
- @SQLNotNull
- public boolean blocked = false;
- @SQLDefault("'0'")
- @SQLNotNull
- public boolean removed = false;
+ @Column(length = 128)
+ public String login = null;
+
+ public Timestamp lastConnection = null;
+ @SQLDefault("'0'")
+ @Column(nullable = false)
+ public boolean admin = false;
+ @SQLDefault("'0'")
+ @Column(nullable = false)
+ public boolean blocked = false;
+ @SQLDefault("'0'")
+ @Column(nullable = false)
+ public boolean removed = false;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ public List> covers;
+
@Override
public String toString() {
- return "User [login=" + login + ", last=" + lastConnection + ", admin=" + admin + "]";
+ return "User [login=" + this.login + ", last=" + this.lastConnection + ", admin=" + this.admin + "]";
}
-
+
}
diff --git a/src/org/kar/archidata/model/UserByToken.java b/src/org/kar/archidata/model/UserByToken.java
index c97b4f6..bf274bb 100644
--- a/src/org/kar/archidata/model/UserByToken.java
+++ b/src/org/kar/archidata/model/UserByToken.java
@@ -3,7 +3,6 @@ package org.kar.archidata.model;
import java.util.HashMap;
import java.util.Map;
-
public class UserByToken {
public static final int TYPE_USER = -1;
public static final int TYPE_APPLICATION = -2;
@@ -11,49 +10,49 @@ public class UserByToken {
public Integer type = null;
public Long id = null;
- public Long parentId = null; // FOr application, this is the id of the application, and of user token, this is the USERID
- public String name = null;
- // Right map
- public Map right = new HashMap<>();
-
- public boolean hasRight(String key, Object value) {
- if (! this.right.containsKey(key)) {
- return false;
- }
- Object data = this.right.get(key);
- if (data instanceof Boolean elem) {
- if (value instanceof Boolean castVal) {
- if (elem == castVal) {
- return true;
- }
- }
- return false;
- }
- if (data instanceof String elem) {
- if (value instanceof String castVal) {
- if (elem.equals(castVal)) {
- return true;
- }
- }
- return false;
- }
- if (data instanceof Long elem) {
- if (value instanceof Long castVal) {
- if (elem == castVal) {
- return true;
- }
- }
- return false;
- }
- if (data instanceof Double elem) {
- if (value instanceof Double castVal) {
- if (elem == castVal) {
- return true;
- }
- }
- return false;
- }
- return false;
- }
-
+ public Long parentId = null; // FOr application, this is the id of the application, and of user token, this is the USERID
+ public String name = null;
+ // Right map
+ public Map right = new HashMap<>();
+
+ public boolean hasRight(String key, Object value) {
+ if (!this.right.containsKey(key)) {
+ return false;
+ }
+ Object data = this.right.get(key);
+ if (data instanceof Boolean elem) {
+ if (value instanceof Boolean castVal) {
+ if (elem == castVal) {
+ return true;
+ }
+ }
+ return false;
+ }
+ if (data instanceof String elem) {
+ if (value instanceof String castVal) {
+ if (elem.equals(castVal)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ if (data instanceof Long elem) {
+ if (value instanceof Long castVal) {
+ if (elem == castVal) {
+ return true;
+ }
+ }
+ return false;
+ }
+ if (data instanceof Double elem) {
+ if (value instanceof Double castVal) {
+ if (elem == castVal) {
+ return true;
+ }
+ }
+ return false;
+ }
+ return false;
+ }
+
}
diff --git a/src/org/kar/archidata/sqlWrapper/Foreign.java b/src/org/kar/archidata/sqlWrapper/Foreign.java
new file mode 100644
index 0000000..15ba153
--- /dev/null
+++ b/src/org/kar/archidata/sqlWrapper/Foreign.java
@@ -0,0 +1,16 @@
+package org.kar.archidata.sqlWrapper;
+
+public class Foreign {
+ public final Long id;
+ public final T data;
+
+ public Foreign(final Long id) {
+ this.id = id;
+ this.data = null;
+ }
+
+ public Foreign(final T data) {
+ this.id = null;
+ this.data = data;
+ }
+}
diff --git a/src/org/kar/archidata/sqlWrapper/GenericAddOn.java b/src/org/kar/archidata/sqlWrapper/GenericAddOn.java
new file mode 100644
index 0000000..31d60cb
--- /dev/null
+++ b/src/org/kar/archidata/sqlWrapper/GenericAddOn.java
@@ -0,0 +1,11 @@
+package org.kar.archidata.sqlWrapper;
+
+import org.kar.archidata.sqlWrapper.addOn.AddOnSQLTableExternalForeinKeyAsList;
+import org.kar.archidata.sqlWrapper.addOn.AddOnSQLTableExternalLink;
+
+public class GenericAddOn {
+ public static void addGenericAddOn() {
+ SqlWrapper.addAddOn(new AddOnSQLTableExternalLink());
+ SqlWrapper.addAddOn(new AddOnSQLTableExternalForeinKeyAsList());
+ }
+}
diff --git a/src/org/kar/archidata/sqlWrapper/QuerryAnd.java b/src/org/kar/archidata/sqlWrapper/QuerryAnd.java
new file mode 100644
index 0000000..d2a077e
--- /dev/null
+++ b/src/org/kar/archidata/sqlWrapper/QuerryAnd.java
@@ -0,0 +1,43 @@
+package org.kar.archidata.sqlWrapper;
+
+import java.sql.PreparedStatement;
+import java.util.ArrayList;
+import java.util.List;
+
+public class QuerryAnd implements QuerryItem {
+ protected final List childs;
+
+ public QuerryAnd(List childs) {
+ this.childs = childs;
+ }
+
+ public QuerryAnd(QuerryItem... items) {
+ this.childs = new ArrayList<>();
+ for (int iii = 0; iii < items.length; iii++) {
+ this.childs.add(items[iii]);
+ }
+ }
+
+ public void generateQuerry(StringBuilder querry, String tableName) {
+ querry.append(" (");
+ boolean first = false;
+ for (QuerryItem elem : this.childs) {
+ if (first) {
+ first = false;
+ } else {
+ querry.append(" AND ");
+ }
+ elem.generateQuerry(querry, tableName);
+ }
+ querry.append(")");
+ }
+
+ @Override
+ public int injectQuerry(PreparedStatement ps, int iii) throws Exception {
+
+ for (QuerryItem elem : this.childs) {
+ iii = elem.injectQuerry(ps, iii);
+ }
+ return iii;
+ }
+}
diff --git a/src/org/kar/archidata/sqlWrapper/QuerryCondition.java b/src/org/kar/archidata/sqlWrapper/QuerryCondition.java
new file mode 100644
index 0000000..50f3dd2
--- /dev/null
+++ b/src/org/kar/archidata/sqlWrapper/QuerryCondition.java
@@ -0,0 +1,31 @@
+package org.kar.archidata.sqlWrapper;
+
+import java.sql.PreparedStatement;
+
+public class QuerryCondition implements QuerryItem {
+ private final String key;
+ private final String comparator;
+ private final Object value;
+
+ public QuerryCondition(String key, String comparator, Object value) {
+ this.key = key;
+ this.comparator = comparator;
+ this.value = value;
+ }
+
+ public void generateQuerry(StringBuilder querry, String tableName) {
+ querry.append(tableName);
+ querry.append(".");
+ querry.append(this.key);
+ querry.append(" ");
+ querry.append(this.comparator);
+ querry.append(" ?");
+
+ }
+
+ @Override
+ public int injectQuerry(PreparedStatement ps, int iii) throws Exception {
+ SqlWrapper.addElement(ps, this.value, iii++);
+ return iii;
+ }
+}
diff --git a/src/org/kar/archidata/sqlWrapper/QuerryItem.java b/src/org/kar/archidata/sqlWrapper/QuerryItem.java
new file mode 100644
index 0000000..8a12e1a
--- /dev/null
+++ b/src/org/kar/archidata/sqlWrapper/QuerryItem.java
@@ -0,0 +1,9 @@
+package org.kar.archidata.sqlWrapper;
+
+import java.sql.PreparedStatement;
+
+public interface QuerryItem {
+ void generateQuerry(StringBuilder querry, String tableName);
+
+ int injectQuerry(PreparedStatement ps, int iii) throws Exception;
+}
diff --git a/src/org/kar/archidata/sqlWrapper/QuerryOr.java b/src/org/kar/archidata/sqlWrapper/QuerryOr.java
new file mode 100644
index 0000000..21d7a11
--- /dev/null
+++ b/src/org/kar/archidata/sqlWrapper/QuerryOr.java
@@ -0,0 +1,35 @@
+package org.kar.archidata.sqlWrapper;
+
+import java.sql.PreparedStatement;
+import java.util.List;
+
+public class QuerryOr implements QuerryItem {
+ protected final List childs;
+
+ public QuerryOr(List childs) {
+ this.childs = childs;
+ }
+
+ public void generateQuerry(StringBuilder querry, String tableName) {
+ querry.append(" (");
+ boolean first = false;
+ for (QuerryItem elem : this.childs) {
+ if (first) {
+ first = false;
+ } else {
+ querry.append(" OR ");
+ }
+ elem.generateQuerry(querry, tableName);
+ }
+ querry.append(")");
+ }
+
+ @Override
+ public int injectQuerry(PreparedStatement ps, int iii) throws Exception {
+
+ for (QuerryItem elem : this.childs) {
+ iii = elem.injectQuerry(ps, iii);
+ }
+ return iii;
+ }
+}
diff --git a/src/org/kar/archidata/sqlWrapper/SqlWrapper.java b/src/org/kar/archidata/sqlWrapper/SqlWrapper.java
index f2d5da7..9bcffd2 100644
--- a/src/org/kar/archidata/sqlWrapper/SqlWrapper.java
+++ b/src/org/kar/archidata/sqlWrapper/SqlWrapper.java
@@ -1,28 +1,29 @@
package org.kar.archidata.sqlWrapper;
import java.io.IOException;
-import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
+import java.sql.Date;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-import java.util.stream.Collectors;
-import java.sql.*;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
import org.kar.archidata.GlobalConfiguration;
-import org.kar.archidata.annotation.SQLAutoIncrement;
-import org.kar.archidata.annotation.SQLComment;
+import org.kar.archidata.annotation.AnnotationTools;
+import org.kar.archidata.annotation.CreationTimestamp;
+import org.kar.archidata.annotation.SQLAddOn;
+import org.kar.archidata.annotation.SQLDefault;
+import org.kar.archidata.annotation.SQLDeleted;
import org.kar.archidata.annotation.SQLIfNotExists;
-import org.kar.archidata.annotation.SQLLimitSize;
-import org.kar.archidata.annotation.SQLNotNull;
import org.kar.archidata.annotation.SQLNotRead;
-import org.kar.archidata.annotation.SQLPrimaryKey;
-import org.kar.archidata.annotation.SQLTableLinkGeneric;
-import org.kar.archidata.annotation.SQLTableLinkGeneric.ModelLink;
-import org.kar.archidata.annotation.SQLTableName;
-import org.kar.archidata.annotation.SQLUpdateTime;
+import org.kar.archidata.annotation.UpdateTimestamp;
import org.kar.archidata.db.DBEntry;
import org.kar.archidata.util.ConfigBaseVariable;
import org.slf4j.Logger;
@@ -31,34 +32,32 @@ import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
+import jakarta.persistence.GenerationType;
import jakarta.ws.rs.InternalServerErrorException;
-import org.kar.archidata.annotation.SQLCreateTime;
-import org.kar.archidata.annotation.SQLDefault;
-import org.kar.archidata.annotation.SQLDeleted;
-
public class SqlWrapper {
static final Logger LOGGER = LoggerFactory.getLogger(SqlWrapper.class);
static final List addOn = new ArrayList<>();
-
- public static void addAddOn(SqlWrapperAddOn addOn) {
+
+ public static void addAddOn(final SqlWrapperAddOn addOn) {
SqlWrapper.addOn.add(addOn);
};
-
+
public static class ExceptionDBInterface extends Exception {
private static final long serialVersionUID = 1L;
public int errorID;
- ExceptionDBInterface(int errorId, String message) {
+
+ public ExceptionDBInterface(final int errorId, final String message) {
super(message);
this.errorID = errorId;
}
}
-
+
public SqlWrapper() {
-
+
}
- public static boolean isDBExist(String name) throws InternalServerErrorException {
+ public static boolean isDBExist(final String name) throws InternalServerErrorException {
if (ConfigBaseVariable.getDBType().equals("sqlite")) {
// no base manage in sqLite ...
// TODO: check if the file exist or not ...
@@ -67,7 +66,7 @@ public class SqlWrapper {
DBEntry entry;
try {
entry = DBEntry.createInterface(GlobalConfiguration.dbConfig, true);
- } catch (IOException ex) {
+ } catch (final IOException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
LOGGER.error("Can not check if the DB exist!!! {}", ex.getMessage());
@@ -75,31 +74,32 @@ public class SqlWrapper {
}
try {
// TODO : Maybe connect with a temporary not specified connection interface to a db ...
- PreparedStatement ps = entry.connection.prepareStatement("show databases");
- ResultSet rs = ps.executeQuery();
- //LOGGER.info("List all tables: equals? '{}'", name);
- while (rs.next()) {
- String data = rs.getString(1);
- //LOGGER.info(" - '{}'", data);
- if (name.equals(data)) {
- return true;
- }
- }
+ final PreparedStatement ps = entry.connection.prepareStatement("show databases");
+ final ResultSet rs = ps.executeQuery();
+ //LOGGER.info("List all tables: equals? '{}'", name);
+ while (rs.next()) {
+ final String data = rs.getString(1);
+ //LOGGER.info(" - '{}'", data);
+ if (name.equals(data)) {
+ return true;
+ }
+ }
return false;
- } catch (SQLException ex) {
+ } catch (final SQLException ex) {
LOGGER.error("Can not check if the DB exist SQL-error !!! {}", ex.getMessage());
} finally {
- try {
+ try {
entry.close();
- } catch (IOException e) {
+ } catch (final IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
- entry = null;
+ entry = null;
}
throw new InternalServerErrorException("Can Not manage the DB-access");
}
- public static boolean createDB(String name) {
+
+ public static boolean createDB(final String name) {
if (ConfigBaseVariable.getDBType().equals("sqlite")) {
// no base manage in sqLite ...
// TODO: check if the file exist or not ...
@@ -107,17 +107,18 @@ public class SqlWrapper {
}
try {
return 1 == SqlWrapper.executeSimpleQuerry("CREATE DATABASE `" + name + "`;", true);
- } catch (SQLException ex) {
+ } catch (final SQLException ex) {
ex.printStackTrace();
LOGGER.error("Can not check if the DB exist!!! {}", ex.getMessage());
return false;
- } catch (IOException ex) {
+ } catch (final IOException ex) {
ex.printStackTrace();
LOGGER.error("Can not check if the DB exist!!! {}", ex.getMessage());
return false;
}
}
- public static boolean isTableExist(String name) throws InternalServerErrorException {
+
+ public static boolean isTableExist(final String name) throws InternalServerErrorException {
try {
String request = "";
if (ConfigBaseVariable.getDBType().equals("sqlite")) {
@@ -128,41 +129,41 @@ public class SqlWrapper {
AND name = ?;
""";
// PreparedStatement ps = entry.connection.prepareStatement("show tables");
- DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
- PreparedStatement ps = entry.connection.prepareStatement(request);
+ final DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
+ final PreparedStatement ps = entry.connection.prepareStatement(request);
ps.setString(1, name);
- ResultSet ret = ps.executeQuery();
- int count = ret.getInt("total");
+ final ResultSet ret = ps.executeQuery();
+ final int count = ret.getInt("total");
return count == 1;
} else {
- DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
+ final DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
// TODO : Maybe connect with a temporary not specified connection interface to a db ...
- PreparedStatement ps = entry.connection.prepareStatement("show tables");
- ResultSet rs = ps.executeQuery();
- //LOGGER.info("List all tables: equals? '{}'", name);
- while (rs.next()) {
- String data = rs.getString(1);
- //LOGGER.info(" - '{}'", data);
- if (name.equals(data)) {
- return true;
- }
- }
+ final PreparedStatement ps = entry.connection.prepareStatement("show tables");
+ final ResultSet rs = ps.executeQuery();
+ //LOGGER.info("List all tables: equals? '{}'", name);
+ while (rs.next()) {
+ final String data = rs.getString(1);
+ //LOGGER.info(" - '{}'", data);
+ if (name.equals(data)) {
+ return true;
+ }
+ }
return false;
}
- } catch (SQLException ex) {
+ } catch (final SQLException ex) {
LOGGER.error("Can not check if the table exist SQL-error !!! {}", ex.getMessage());
- } catch (IOException ex) {
+ } catch (final IOException ex) {
LOGGER.error("Can not check if the table exist!!! {}", ex.getMessage());
}
throw new InternalServerErrorException("Can Not manage the DB-access");
- }
-
- public static String convertTypeInSQL(Class> type) throws Exception {
+ }
+
+ public static String convertTypeInSQL(final Class> type) throws Exception {
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
- if (type == Long.class || type == long.class ) {
+ if (type == Long.class || type == long.class) {
return "bigint";
}
- if (type == Integer.class || type == int.class ) {
+ if (type == Integer.class || type == int.class) {
return "int";
}
if (type == Boolean.class || type == boolean.class) {
@@ -184,10 +185,10 @@ public class SqlWrapper {
return "text";
}
} else {
- if (type == Long.class || type == long.class ) {
+ if (type == Long.class || type == long.class) {
return "INTEGER";
}
- if (type == Integer.class || type == int.class ) {
+ if (type == Integer.class || type == int.class) {
return "INTEGER";
}
if (type == Boolean.class || type == boolean.class) {
@@ -212,163 +213,166 @@ public class SqlWrapper {
throw new Exception("Imcompatible type of element in object for: " + type.getCanonicalName());
}
- protected static void setValuedb(Class> type, T data, int index, Field field, PreparedStatement ps) throws IllegalArgumentException, IllegalAccessException, SQLException {
+ protected static void setValuedb(final Class> type, final T data, int index, final Field field, final PreparedStatement ps)
+ throws IllegalArgumentException, IllegalAccessException, SQLException {
if (type == Long.class) {
- Object tmp = field.get(data);
- if (tmp == null) {
- ps.setNull(index++, Types.BIGINT);
- } else {
- ps.setLong(index++, (Long)tmp);
- }
- } else if (type == long.class ) {
+ final Object tmp = field.get(data);
+ if (tmp == null) {
+ ps.setNull(index++, Types.BIGINT);
+ } else {
+ ps.setLong(index++, (Long) tmp);
+ }
+ } else if (type == long.class) {
ps.setLong(index++, field.getLong(data));
} else if (type == Integer.class) {
- Object tmp = field.get(data);
- if (tmp == null) {
- ps.setNull(index++, Types.INTEGER);
- } else {
- ps.setInt(index++, (Integer)tmp);
- }
- } else if (type == int.class ) {
+ final Object tmp = field.get(data);
+ if (tmp == null) {
+ ps.setNull(index++, Types.INTEGER);
+ } else {
+ ps.setInt(index++, (Integer) tmp);
+ }
+ } else if (type == int.class) {
ps.setInt(index++, field.getInt(data));
} else if (type == Float.class) {
- Object tmp = field.get(data);
- if (tmp == null) {
- ps.setNull(index++, Types.FLOAT);
- } else {
- ps.setFloat(index++, (Float)tmp);
- }
+ final Object tmp = field.get(data);
+ if (tmp == null) {
+ ps.setNull(index++, Types.FLOAT);
+ } else {
+ ps.setFloat(index++, (Float) tmp);
+ }
} else if (type == float.class) {
ps.setFloat(index++, field.getFloat(data));
} else if (type == Double.class) {
- Object tmp = field.get(data);
- if (tmp == null) {
- ps.setNull(index++, Types.DOUBLE);
- } else {
- ps.setDouble(index++, (Double)tmp);
- }
+ final Object tmp = field.get(data);
+ if (tmp == null) {
+ ps.setNull(index++, Types.DOUBLE);
+ } else {
+ ps.setDouble(index++, (Double) tmp);
+ }
} else if (type == Double.class) {
ps.setDouble(index++, field.getDouble(data));
} else if (type == Boolean.class) {
- Object tmp = field.get(data);
- if (tmp == null) {
- ps.setNull(index++, Types.INTEGER);
- } else {
- ps.setBoolean(index++, (Boolean)tmp);
- }
+ final Object tmp = field.get(data);
+ if (tmp == null) {
+ ps.setNull(index++, Types.INTEGER);
+ } else {
+ ps.setBoolean(index++, (Boolean) tmp);
+ }
} else if (type == boolean.class) {
ps.setBoolean(index++, field.getBoolean(data));
} else if (type == Timestamp.class) {
- Object tmp = field.get(data);
- if (tmp == null) {
- ps.setNull(index++, Types.INTEGER);
- } else {
- ps.setTimestamp(index++, (Timestamp)tmp);
- }
+ final Object tmp = field.get(data);
+ if (tmp == null) {
+ ps.setNull(index++, Types.INTEGER);
+ } else {
+ ps.setTimestamp(index++, (Timestamp) tmp);
+ }
} else if (type == Date.class) {
- Object tmp = field.get(data);
- if (tmp == null) {
- ps.setNull(index++, Types.INTEGER);
- } else {
- ps.setDate(index++, (Date)tmp);
- }
+ final Object tmp = field.get(data);
+ if (tmp == null) {
+ ps.setNull(index++, Types.INTEGER);
+ } else {
+ ps.setDate(index++, (Date) tmp);
+ }
} else if (type == String.class) {
- Object tmp = field.get(data);
- if (tmp == null) {
- ps.setNull(index++, Types.VARCHAR);
- } else {
- ps.setString(index++, (String)tmp);
- }
+ final Object tmp = field.get(data);
+ if (tmp == null) {
+ ps.setNull(index++, Types.VARCHAR);
+ } else {
+ ps.setString(index++, (String) tmp);
+ }
}
}
- protected static void setValueFromDb(Class> type, T data, int index, Field field, ResultSet rs) throws IllegalArgumentException, IllegalAccessException, SQLException {
+
+ protected static void setValueFromDb(final Class> type, final T data, final int index, final Field field, final ResultSet rs)
+ throws IllegalArgumentException, IllegalAccessException, SQLException {
if (type == Long.class) {
- Long tmp = rs.getLong(index);
+ final Long tmp = rs.getLong(index);
if (rs.wasNull()) {
field.set(data, null);
} else {
//logger.debug(" ==> {}", tmp);
field.set(data, tmp);
}
- } else if (type == long.class ) {
- Long tmp = rs.getLong(index);
+ } else if (type == long.class) {
+ final Long tmp = rs.getLong(index);
if (rs.wasNull()) {
//field.set(data, null);
} else {
field.setLong(data, tmp);
}
} else if (type == Integer.class) {
- Integer tmp = rs.getInt(index);
+ final Integer tmp = rs.getInt(index);
if (rs.wasNull()) {
field.set(data, null);
} else {
field.set(data, tmp);
}
- } else if (type == int.class ) {
- Integer tmp = rs.getInt(index);
+ } else if (type == int.class) {
+ final Integer tmp = rs.getInt(index);
if (rs.wasNull()) {
//field.set(data, null);
} else {
field.setInt(data, tmp);
}
} else if (type == Float.class) {
- Float tmp = rs.getFloat(index);
+ final Float tmp = rs.getFloat(index);
if (rs.wasNull()) {
field.set(data, null);
} else {
field.set(data, tmp);
}
} else if (type == float.class) {
- Float tmp = rs.getFloat(index);
+ final Float tmp = rs.getFloat(index);
if (rs.wasNull()) {
//field.set(data, null);
} else {
field.setFloat(data, tmp);
}
} else if (type == Double.class) {
- Double tmp = rs.getDouble(index);
+ final Double tmp = rs.getDouble(index);
if (rs.wasNull()) {
field.set(data, null);
} else {
field.set(data, tmp);
}
} else if (type == double.class) {
- Double tmp = rs.getDouble(index);
+ final Double tmp = rs.getDouble(index);
if (rs.wasNull()) {
//field.set(data, null);
} else {
field.setDouble(data, tmp);
}
} else if (type == Boolean.class) {
- Boolean tmp = rs.getBoolean(index);
+ final Boolean tmp = rs.getBoolean(index);
if (rs.wasNull()) {
field.set(data, null);
} else {
field.set(data, tmp);
}
} else if (type == boolean.class) {
- Boolean tmp = rs.getBoolean(index);
+ final Boolean tmp = rs.getBoolean(index);
if (rs.wasNull()) {
//field.set(data, null);
} else {
field.setBoolean(data, tmp);
}
} else if (type == Timestamp.class) {
- Timestamp tmp = rs.getTimestamp(index);
+ final Timestamp tmp = rs.getTimestamp(index);
if (rs.wasNull()) {
field.set(data, null);
} else {
field.set(data, tmp);
}
} else if (type == Date.class) {
- Date tmp = rs.getDate(index);
+ final Date tmp = rs.getDate(index);
if (rs.wasNull()) {
field.set(data, null);
} else {
field.set(data, tmp);
}
} else if (type == String.class) {
- String tmp = rs.getString(index);
+ final String tmp = rs.getString(index);
if (rs.wasNull()) {
field.set(data, null);
} else {
@@ -376,187 +380,187 @@ public class SqlWrapper {
}
}
}
- public static ModelLink getLinkMode(Field elem) {
- SQLTableLinkGeneric[] decorators = elem.getDeclaredAnnotationsByType(SQLTableLinkGeneric.class);
- if (decorators == null || decorators.length == 0) {
- return SQLTableLinkGeneric.ModelLink.NONE;
- }
- return decorators[0].value();
+
+ public static boolean isAddOnField(final Field field) {
+ return AnnotationTools.isAnnotationGroup(field, SQLAddOn.class);
}
- public static T insert(T data) throws Exception {
- Class> clazz = data.getClass();
- //public static NodeSmall createNode(String typeInNode, String name, String descrition, Long parentId) {
-
- DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
- // real add in the BDD:
- try {
- String tableName = getTableName(clazz);
- //boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
- StringBuilder query = new StringBuilder();
- query.append("INSERT INTO `");
- query.append(tableName);
- query.append("` (");
+ public static SqlWrapperAddOn findAddOnforField(final Field field) {
+ for (final SqlWrapperAddOn elem : addOn) {
+ if (elem.isCompatibleField(field)) {
+ return elem;
+ }
+ }
+ return null;
+ }
- boolean firstField = true;
- int count = 0;
- for (Field elem : clazz.getFields()) {
- // static field is only for internal global declaration ==> remove it ..
- if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
- continue;
- }
- boolean primaryKey = elem.getDeclaredAnnotationsByType(SQLPrimaryKey.class).length != 0;
- if (primaryKey) {
+ public static T insert(final T data) throws Exception {
+ final Class> clazz = data.getClass();
+ //public static NodeSmall createNode(String typeInNode, String name, String descrition, Long parentId) {
+
+ DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
+ // real add in the BDD:
+ try {
+ final String tableName = AnnotationTools.getTableName(clazz);
+ //boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
+ final StringBuilder querry = new StringBuilder();
+ querry.append("INSERT INTO `");
+ querry.append(tableName);
+ querry.append("` (");
+
+ boolean firstField = true;
+ int count = 0;
+ for (final Field elem : clazz.getFields()) {
+ // static field is only for internal global declaration ==> remove it ..
+ if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
continue;
}
- ModelLink linkGeneric = getLinkMode(elem);
- if (linkGeneric == ModelLink.EXTERNAL) {
+ if (AnnotationTools.isPrimaryKey(elem)) {
continue;
}
- boolean createTime = elem.getDeclaredAnnotationsByType(SQLCreateTime.class).length != 0;
+ final SqlWrapperAddOn addOn = findAddOnforField(elem);
+ if (addOn != null && addOn.isExternal()) {
+ continue;
+ }
+ final boolean createTime = elem.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0;
if (createTime) {
continue;
}
- boolean updateTime = elem.getDeclaredAnnotationsByType(SQLUpdateTime.class).length != 0;
+ final boolean updateTime = elem.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0;
if (updateTime) {
continue;
}
if (!elem.getClass().isPrimitive()) {
- Object tmp = elem.get(data);
- if(tmp == null && elem.getDeclaredAnnotationsByType(SQLDefault.class).length != 0) {
+ final Object tmp = elem.get(data);
+ if (tmp == null && elem.getDeclaredAnnotationsByType(SQLDefault.class).length != 0) {
continue;
}
}
count++;
- String name = elem.getName();
+ final String name = elem.getName();
if (firstField) {
- firstField = false;
+ firstField = false;
} else {
- query.append(",");
+ querry.append(",");
}
- query.append(" `");
- query.append(name);
- query.append("`");
- }
- firstField = true;
- query.append(") VALUES (");
- for (int iii = 0; iii remove it ..
- if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
- continue;
- }
- boolean primaryKey = elem.getDeclaredAnnotationsByType(SQLPrimaryKey.class).length != 0;
- if (primaryKey) {
+ querry.append("?");
+ }
+ querry.append(")");
+ //LOGGER.warn("generate the querry: '{}'", querry.toString());
+ // prepare the request:
+ final PreparedStatement ps = entry.connection.prepareStatement(querry.toString(), Statement.RETURN_GENERATED_KEYS);
+ Field primaryKeyField = null;
+ int iii = 1;
+ for (final Field elem : clazz.getFields()) {
+ // static field is only for internal global declaration ==> remove it ..
+ if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
+ continue;
+ }
+ if (AnnotationTools.isPrimaryKey(elem)) {
primaryKeyField = elem;
continue;
}
- ModelLink linkGeneric = getLinkMode(elem);
- if (linkGeneric == ModelLink.EXTERNAL) {
+ final SqlWrapperAddOn addOn = findAddOnforField(elem);
+ if (addOn != null && addOn.isExternal()) {
continue;
}
- boolean createTime = elem.getDeclaredAnnotationsByType(SQLCreateTime.class).length != 0;
+ final boolean createTime = elem.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0;
if (createTime) {
continue;
}
- boolean updateTime = elem.getDeclaredAnnotationsByType(SQLUpdateTime.class).length != 0;
+ final boolean updateTime = elem.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0;
if (updateTime) {
continue;
}
- if (linkGeneric == ModelLink.NONE) {
- Class> type = elem.getType();
+ if (addOn != null) {
+ // Add-on specific insertion.
+ final Object tmp = elem.get(data);
+ iii = addOn.insertData(ps, tmp, iii);
+ } else {
+ // Generic class insertion...
+ final Class> type = elem.getType();
if (!type.isPrimitive()) {
- Object tmp = elem.get(data);
- if(tmp == null && elem.getDeclaredAnnotationsByType(SQLDefault.class).length != 0) {
+ final Object tmp = elem.get(data);
+ if (tmp == null && elem.getDeclaredAnnotationsByType(SQLDefault.class).length != 0) {
continue;
}
}
setValuedb(type, data, iii++, elem, ps);
- } else {
- // transform the data in string to insert it ...
- Object tmp = elem.get(data);
- if (tmp == null) {
- ps.setNull(iii++, Types.BIGINT);
- } else {
- @SuppressWarnings("unchecked")
- String dataTmp = getStringOfIds((List)tmp);
- ps.setString(iii++, dataTmp);
- }
}
count++;
- }
- // execute the request
- int affectedRows = ps.executeUpdate();
- if (affectedRows == 0) {
- throw new SQLException("Creating node failed, no rows affected.");
- }
- Long uniqueSQLID = null;
- // Retrieve uid inserted
- try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
- if (generatedKeys.next()) {
- uniqueSQLID = generatedKeys.getLong(1);
- } else {
- throw new SQLException("Creating node failed, no ID obtained (1).");
- }
- } catch (Exception ex) {
- LOGGER.error("Can not get the UID key inserted ... ");
- ex.printStackTrace();
- throw new SQLException("Creating node failed, no ID obtained (2).");
- }
- if (primaryKeyField != null) {
- if (primaryKeyField.getType() == Long.class) {
- primaryKeyField.set(data, (Long)uniqueSQLID);
- } else if (primaryKeyField.getType() == long.class) {
- primaryKeyField.setLong(data, uniqueSQLID);
- } else {
- LOGGER.error("Can not manage the primary filed !!!");
- }
- }
- //ps.execute();
- } catch (SQLException ex) {
- ex.printStackTrace();
- } finally {
- entry.close();
- entry = null;
- }
- return data;
+ }
+ // execute the request
+ final int affectedRows = ps.executeUpdate();
+ if (affectedRows == 0) {
+ throw new SQLException("Creating node failed, no rows affected.");
+ }
+ Long uniqueSQLID = null;
+ // Retrieve uid inserted
+ try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
+ if (generatedKeys.next()) {
+ uniqueSQLID = generatedKeys.getLong(1);
+ } else {
+ throw new SQLException("Creating node failed, no ID obtained (1).");
+ }
+ } catch (final Exception ex) {
+ LOGGER.error("Can not get the UID key inserted ... ");
+ ex.printStackTrace();
+ throw new SQLException("Creating node failed, no ID obtained (2).");
+ }
+ if (primaryKeyField != null) {
+ if (primaryKeyField.getType() == Long.class) {
+ primaryKeyField.set(data, uniqueSQLID);
+ } else if (primaryKeyField.getType() == long.class) {
+ primaryKeyField.setLong(data, uniqueSQLID);
+ } else {
+ LOGGER.error("Can not manage the primary filed !!!");
+ }
+ }
+ //ps.execute();
+ } catch (final SQLException ex) {
+ ex.printStackTrace();
+ } finally {
+ entry.close();
+ entry = null;
+ }
+ return data;
}
+
// seems a good idea, but very dangerous if we not filter input data... if set an id it can be complicated...
- public static T insertWithJson(Class clazz, String jsonData) throws Exception {
- ObjectMapper mapper = new ObjectMapper();
- // parse the object to be sure the data are valid:
- T data = mapper.readValue(jsonData, clazz);
-
- return insert(data);
+ public static T insertWithJson(final Class clazz, final String jsonData) throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+ // parse the object to be sure the data are valid:
+ final T data = mapper.readValue(jsonData, clazz);
+
+ return insert(data);
}
-
- public static int update(Class clazz, long id, String jsonData) throws Exception {
- ObjectMapper mapper = new ObjectMapper();
- // parse the object to be sure the data are valid:
- T data = mapper.readValue(jsonData, clazz);
- // Read the tree to filter injection of data:
- JsonNode root = mapper.readTree(jsonData);
- List keys = new ArrayList<>();
- Iterator iterator = root.fieldNames();
- iterator.forEachRemaining(e -> keys.add(e));
- return update(data, id, keys);
+
+ public static int update(final Class clazz, final long id, final String jsonData) throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+ // parse the object to be sure the data are valid:
+ final T data = mapper.readValue(jsonData, clazz);
+ // Read the tree to filter injection of data:
+ final JsonNode root = mapper.readTree(jsonData);
+ final List keys = new ArrayList<>();
+ final Iterator iterator = root.fieldNames();
+ iterator.forEachRemaining(e -> keys.add(e));
+ return update(data, id, keys);
}
-
+
/**
- *
+ *
* @param
* @param data
* @param id
@@ -564,732 +568,649 @@ public class SqlWrapper {
* @return the affected rows.
* @throws Exception
*/
- public static int update(T data, long id, List filterValue) throws Exception {
- Class> clazz = data.getClass();
+ public static int update(final T data, final long id, final List filterValue) throws Exception {
+ final Class> clazz = data.getClass();
//public static NodeSmall createNode(String typeInNode, String name, String description, Long parentId) {
-
- DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
- // real add in the BDD:
- try {
- String tableName = getTableName(clazz);
- //boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
- StringBuilder query = new StringBuilder();
- query.append("UPDATE `");
- query.append(tableName);
- query.append("` SET ");
- boolean firstField = true;
- Field primaryKeyField = null;
- for (Field elem : clazz.getFields()) {
- // static field is only for internal global declaration ==> remove it ..
- if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
- continue;
- }
- boolean primaryKey = elem.getDeclaredAnnotationsByType(SQLPrimaryKey.class).length != 0;
- if (primaryKey) {
+ DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
+ // real add in the BDD:
+ try {
+ final String tableName = AnnotationTools.getTableName(clazz);
+ //boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
+ final StringBuilder querry = new StringBuilder();
+ querry.append("UPDATE `");
+ querry.append(tableName);
+ querry.append("` SET ");
+
+ boolean firstField = true;
+ Field primaryKeyField = null;
+ for (final Field elem : clazz.getFields()) {
+ // static field is only for internal global declaration ==> remove it ..
+ if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
+ continue;
+ }
+ if (AnnotationTools.isPrimaryKey(elem)) {
primaryKeyField = elem;
continue;
}
- ModelLink linkGeneric = getLinkMode(elem);
- if (linkGeneric == ModelLink.EXTERNAL) {
+ final SqlWrapperAddOn addOn = findAddOnforField(elem);
+ if (addOn != null && addOn.isExternal()) {
continue;
}
- boolean createTime = elem.getDeclaredAnnotationsByType(SQLCreateTime.class).length != 0;
+ final boolean createTime = elem.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0;
if (createTime) {
continue;
}
- String name = elem.getName();
- boolean updateTime = elem.getDeclaredAnnotationsByType(SQLUpdateTime.class).length != 0;
- if (! updateTime && !filterValue.contains(name)) {
+ final String name = elem.getName();
+ final boolean updateTime = elem.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0;
+ if (!updateTime && !filterValue.contains(name)) {
continue;
}
if (!elem.getClass().isPrimitive()) {
- Object tmp = elem.get(data);
- if(tmp == null && elem.getDeclaredAnnotationsByType(SQLDefault.class).length != 0) {
+ final Object tmp = elem.get(data);
+ if (tmp == null && elem.getDeclaredAnnotationsByType(SQLDefault.class).length != 0) {
continue;
}
}
if (firstField) {
- firstField = false;
+ firstField = false;
} else {
- query.append(",");
+ querry.append(",");
}
- query.append(" `");
- query.append(name);
- query.append("` = ");
- if (updateTime) {
- query.append(getDBNow());
- query.append(" ");
- } else {
- query.append("? ");
- }
- }
- query.append(" WHERE `");
- query.append(primaryKeyField.getName());
- query.append("` = ?");
- firstField = true;
- // logger.debug("generate the querry: '{}'", query.toString());
- // prepare the request:
- PreparedStatement ps = entry.connection.prepareStatement(query.toString(), Statement.RETURN_GENERATED_KEYS);
- int iii = 1;
- for (Field elem : clazz.getFields()) {
- // static field is only for internal global declaration ==> remove it ..
- if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
- continue;
- }
- boolean primaryKey = elem.getDeclaredAnnotationsByType(SQLPrimaryKey.class).length != 0;
- if (primaryKey) {
+ querry.append(" `");
+ querry.append(name);
+ querry.append("` = ");
+ if (updateTime) {
+ querry.append(getDBNow());
+ querry.append(" ");
+ } else {
+ querry.append("? ");
+ }
+ }
+ querry.append(" WHERE `");
+ querry.append(primaryKeyField.getName());
+ querry.append("` = ?");
+ firstField = true;
+ // logger.debug("generate the querry: '{}'", querry.toString());
+ // prepare the request:
+ final PreparedStatement ps = entry.connection.prepareStatement(querry.toString(), Statement.RETURN_GENERATED_KEYS);
+ int iii = 1;
+ for (final Field elem : clazz.getFields()) {
+ // static field is only for internal global declaration ==> remove it ..
+ if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
continue;
}
- ModelLink linkGeneric = getLinkMode(elem);
- if (linkGeneric == ModelLink.EXTERNAL) {
+ if (AnnotationTools.isPrimaryKey(elem)) {
continue;
}
- boolean createTime = elem.getDeclaredAnnotationsByType(SQLCreateTime.class).length != 0;
+ final SqlWrapperAddOn addOn = findAddOnforField(elem);
+ if (addOn != null && !addOn.canUpdate()) {
+ continue;
+ }
+ final boolean createTime = elem.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0;
if (createTime) {
continue;
}
- String name = elem.getName();
- boolean updateTime = elem.getDeclaredAnnotationsByType(SQLUpdateTime.class).length != 0;
+ final String name = elem.getName();
+ final boolean updateTime = elem.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0;
if (updateTime || !filterValue.contains(name)) {
continue;
}
- if (linkGeneric == ModelLink.NONE) {
- Class> type = elem.getType();
+ if (addOn == null) {
+ final Class> type = elem.getType();
if (!type.isPrimitive()) {
- Object tmp = elem.get(data);
- if(tmp == null && elem.getDeclaredAnnotationsByType(SQLDefault.class).length != 0) {
+ final Object tmp = elem.get(data);
+ if (tmp == null && elem.getDeclaredAnnotationsByType(SQLDefault.class).length != 0) {
continue;
}
}
setValuedb(type, data, iii++, elem, ps);
} else {
- // transform the data in string to insert it ...
- Object tmp = elem.get(data);
- if (tmp == null) {
- ps.setNull(iii++, Types.BIGINT);
- } else {
- @SuppressWarnings("unchecked")
- String dataTmp = getStringOfIds((List)tmp);
- ps.setString(iii++, dataTmp);
- }
+ iii = addOn.insertData(ps, data, iii);
}
- }
- ps.setLong(iii++, id);
- // execute the request
- int affectedRows = ps.executeUpdate();
- return affectedRows;
- } catch (SQLException ex) {
- ex.printStackTrace();
- } finally {
- entry.close();
- entry = null;
- }
- return 0;
+ }
+ ps.setLong(iii++, id);
+ // execute the request
+ final int affectedRows = ps.executeUpdate();
+ return affectedRows;
+ } catch (final SQLException ex) {
+ ex.printStackTrace();
+ } finally {
+ entry.close();
+ entry = null;
+ }
+ return 0;
}
- static void addElement(PreparedStatement ps, Object value, int iii) throws Exception {
- if (value.getClass() == Long.class) {
- ps.setLong(iii, (Long)value);
+ static void addElement(final PreparedStatement ps, final Object value, final int iii) throws Exception {
+ if (value.getClass() == Long.class) {
+ ps.setLong(iii, (Long) value);
} else if (value.getClass() == Integer.class) {
- ps.setInt(iii, (Integer)value);
+ ps.setInt(iii, (Integer) value);
} else if (value.getClass() == String.class) {
- ps.setString(iii, (String)value);
+ ps.setString(iii, (String) value);
} else if (value.getClass() == Short.class) {
- ps.setShort(iii, (Short)value);
+ ps.setShort(iii, (Short) value);
} else if (value.getClass() == Byte.class) {
- ps.setByte(iii, (Byte)value);
+ ps.setByte(iii, (Byte) value);
} else if (value.getClass() == Float.class) {
- ps.setFloat(iii, (Float)value);
+ ps.setFloat(iii, (Float) value);
} else if (value.getClass() == Double.class) {
- ps.setDouble(iii, (Double)value);
+ ps.setDouble(iii, (Double) value);
} else if (value.getClass() == Boolean.class) {
- ps.setBoolean(iii, (Boolean)value);
+ ps.setBoolean(iii, (Boolean) value);
} else if (value.getClass() == Boolean.class) {
- ps.setBoolean(iii, (Boolean)value);
+ ps.setBoolean(iii, (Boolean) value);
} else if (value.getClass() == Timestamp.class) {
- ps.setTimestamp(iii, (Timestamp)value);
+ ps.setTimestamp(iii, (Timestamp) value);
} else if (value.getClass() == Date.class) {
- ps.setDate(iii, (Date)value);
+ ps.setDate(iii, (Date) value);
} else {
throw new Exception("Not manage type ==> need to add it ...");
}
}
- @Deprecated
- public static T getWith(Class clazz, String key, String value) throws Exception {
- return getWhere(clazz, List.of(new WhereCondition(key, "=", value)), false);
+
+ public static T getWhere(final Class clazz, final QuerryItem condition) throws Exception {
+ return getWhere(clazz, condition, false);
}
- // keep the simple ...
- public static T getWhere(Class clazz, String key, String operator, Object value, boolean full ) throws Exception {
- return getWhere(clazz, List.of(new WhereCondition(key, operator, value)), full);
- }
- @Deprecated
- public static T getWhere(Class clazz, String key, String operator, Object value ) throws Exception {
- return getWhere(clazz, List.of(new WhereCondition(key, operator, value)), false);
- }
- @Deprecated
- public static T getWhere(Class clazz, String key, String operator, Object value, String key2, String operator2, Object value2 ) throws Exception {
- return getWhere(clazz,
- List.of(
- new WhereCondition(key, operator, value),
- new WhereCondition(key2, operator2, value2)
- ), false);
- }
- @Deprecated
- public static T getWhere(Class clazz, String key, String operator, Object value, String key2, String operator2, Object value2, boolean full ) throws Exception {
- return getWhere(clazz,
- List.of(
- new WhereCondition(key, operator, value),
- new WhereCondition(key2, operator2, value2)
- ), full);
- }
-
- public static T getWhere(Class clazz, List condition, boolean full ) throws Exception {
- List values = getsWhere(clazz, condition, full, 1);
- if (values.size() == 0) {
- return null;
- }
- return values.get(0);
- }
- @Deprecated
- public static List getsWhere(Class clazz, String key, String operator, Object value ) throws Exception {
- return getsWhere(clazz, List.of(new WhereCondition(key, operator, value)), null, false, null);
- }
- @Deprecated
- public static List getsWhere(Class clazz, String key, String operator, Object value, boolean full ) throws Exception {
- return getsWhere(clazz, List.of(new WhereCondition(key, operator, value)), null, full, null);
+ public static T getWhere(final Class clazz, final QuerryItem condition, final boolean full) throws Exception {
+ final List values = getsWhere(clazz, condition, full, 1);
+ if (values.size() == 0) {
+ return null;
+ }
+ return values.get(0);
}
- public static List getsWhere(Class clazz, List condition) throws Exception {
+ public static List getsWhere(final Class clazz, final QuerryItem condition) throws Exception {
return getsWhere(clazz, condition, null, false, null);
}
- public static List getsWhere(Class clazz, List condition, boolean full ) throws Exception {
+
+ public static List getsWhere(final Class clazz, final QuerryItem condition, final boolean full) throws Exception {
return getsWhere(clazz, condition, null, full, null);
}
- public static List getsWhere(Class clazz, List condition, boolean full, Integer linit) throws Exception {
+
+ public static List getsWhere(final Class clazz, final QuerryItem condition, final boolean full, final Integer linit) throws Exception {
return getsWhere(clazz, condition, null, full, linit);
}
- public static void whereAppendQuery(StringBuilder query, String tableName, List condition, boolean exclude_deleted) throws ExceptionDBInterface {
+
+ public static void whereAppendQuery(final StringBuilder querry, final String tableName, final QuerryItem condition, final boolean exclude_deleted) throws ExceptionDBInterface {
// Check if we have a condition to generate
- if (condition == null || condition.size() == 0) {
+ if (condition == null) {
+ if (exclude_deleted) {
+ querry.append(" WHERE ");
+ querry.append(tableName);
+ querry.append(".deleted = false ");
+ }
return;
}
- query.append(" WHERE ");
- boolean first = true;
- for (WhereCondition elem : condition) {
- if (first) {
- first = false;
- } else {
- query.append(" AND ");
- }
- query.append(tableName);
- query.append(".");
- query.append(elem.key());
- query.append(" ");
- query.append(elem.comparator());
- query.append(" ?");
- }
- if (exclude_deleted) {
- if (!first) {
- query.append(" AND ");
- }
- query.append(tableName);
- query.append(".deleted = false ");
- }
+ querry.append(" WHERE (");
+ condition.generateQuerry(querry, tableName);
+
+ querry.append(") ");
+ if (exclude_deleted) {
+ querry.append("AND ");
+ querry.append(tableName);
+ querry.append(".deleted = false ");
+ }
}
- public static void whereInjectValue(PreparedStatement ps, List condition) throws Exception {
+
+ public static void whereInjectValue(final PreparedStatement ps, final QuerryItem condition) throws Exception {
// Check if we have a condition to generate
- if (condition == null || condition.size() == 0) {
+ if (condition == null) {
return;
}
int iii = 1;
- for (WhereCondition elem : condition) {
- addElement(ps, elem.Value(), iii++);
- }
+ iii = condition.injectQuerry(ps, iii);
}
- public static int executeSimpleQuerry(String querry, boolean root) throws SQLException, IOException {
- DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig, root);
- Statement stmt = entry.connection.createStatement();
- return stmt.executeUpdate(querry);
+
+ public static int executeSimpleQuerry(final String querry, final boolean root) throws SQLException, IOException {
+ final DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig, root);
+ final Statement stmt = entry.connection.createStatement();
+ return stmt.executeUpdate(querry);
}
-
- public static int executeSimpleQuerry(String querry) throws SQLException, IOException {
+
+ public static int executeSimpleQuerry(final String querry) throws SQLException, IOException {
return executeSimpleQuerry(querry, false);
}
- public static boolean executeQuerry(String querry, boolean root) throws SQLException, IOException {
- DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig, root);
- Statement stmt = entry.connection.createStatement();
- return stmt.execute(querry);
+
+ public static boolean executeQuerry(final String querry, final boolean root) throws SQLException, IOException {
+ final DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig, root);
+ final Statement stmt = entry.connection.createStatement();
+ return stmt.execute(querry);
}
-
- public static boolean executeQuerry(String querry) throws SQLException, IOException {
+
+ public static boolean executeQuerry(final String querry) throws SQLException, IOException {
return executeQuerry(querry, false);
}
-
- @SuppressWarnings("unchecked")
- public static List getsWhere(Class clazz, List condition, String orderBy, boolean full, Integer linit) throws Exception {
- DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
- List outs = new ArrayList<>();
- // real add in the BDD:
- try {
- String tableName = getTableName(clazz);
- //boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
- StringBuilder query = new StringBuilder();
- query.append("SELECT ");
- //query.append(tableName);
- //query.append(" SET ");
- boolean firstField = true;
- int count = 0;
- boolean hasDeleted = false;
- for (Field elem : clazz.getFields()) {
- // static field is only for internal global declaration ==> remove it ..
- if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
- continue;
- }
- ModelLink linkGeneric = getLinkMode(elem);
- if (linkGeneric != ModelLink.NONE) {
+ @SuppressWarnings("unchecked")
+ public static List getsWhere(final Class clazz, final QuerryItem condition, final String orderBy, final boolean full, final Integer linit) throws Exception {
+ DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
+ final List outs = new ArrayList<>();
+ // real add in the BDD:
+ try {
+ final String tableName = AnnotationTools.getTableName(clazz);
+ //boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
+ final StringBuilder querry = new StringBuilder();
+ querry.append("SELECT ");
+ //querry.append(tableName);
+ //querry.append(" SET ");
+
+ boolean firstField = true;
+ int count = 0;
+ boolean hasDeleted = false;
+ for (final Field elem : clazz.getFields()) {
+ // static field is only for internal global declaration ==> remove it ..
+ if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
continue;
}
- boolean createTime = elem.getDeclaredAnnotationsByType(SQLCreateTime.class).length != 0;
+ final SqlWrapperAddOn addOn = findAddOnforField(elem);
+ if (addOn != null) {
+ continue;
+ }
+ final boolean createTime = elem.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0;
if (!full && createTime) {
continue;
}
if (!hasDeleted) {
hasDeleted = elem.getDeclaredAnnotationsByType(SQLDeleted.class).length != 0;
}
- String name = elem.getName();
- boolean updateTime = elem.getDeclaredAnnotationsByType(SQLUpdateTime.class).length != 0;
+ final String name = elem.getName();
+ final boolean updateTime = elem.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0;
if (!full && updateTime) {
continue;
}
count++;
if (firstField) {
- firstField = false;
+ firstField = false;
} else {
- query.append(",");
+ querry.append(",");
}
- query.append(" ");
- query.append(tableName);
- query.append(".");
-
- query.append(name);
- }
- query.append(" FROM `");
- query.append(tableName);
- query.append("` ");
- whereAppendQuery(query, tableName, condition, firstField);
- if (orderBy != null && orderBy.length() >= 1) {
- query.append(" ORDER BY ");
- //query.append(tableName);
- //query.append(".");
- query.append(orderBy);
- }
- if (linit != null && linit >= 1) {
- query.append(" LIMIT " + linit);
- }
- /*
- query.append(" AND ");
- query.append(tableName);
- query.append(".deleted = false ");
- */
- firstField = true;
- //logger.debug("generate the query: '{}'", query.toString());
- // prepare the request:
- PreparedStatement ps = entry.connection.prepareStatement(query.toString(), Statement.RETURN_GENERATED_KEYS);
- whereInjectValue(ps, condition);
- // execute the request
- ResultSet rs = ps.executeQuery();
- while (rs.next()) {
- Object data = clazz.getConstructors()[0].newInstance();
- count = 1;
- for (Field elem : clazz.getFields()) {
- // static field is only for internal global declaration ==> remove it ..
- if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
- continue;
- }
- ModelLink linkGeneric = getLinkMode(elem);
- if (linkGeneric != ModelLink.NONE) {
- continue;
- }
- boolean createTime = elem.getDeclaredAnnotationsByType(SQLCreateTime.class).length != 0;
- if (!full && createTime) {
- continue;
- }
- //String name = elem.getName();
- boolean updateTime = elem.getDeclaredAnnotationsByType(SQLUpdateTime.class).length != 0;
- if (!full && updateTime) {
- continue;
- }
- setValueFromDb(elem.getType(), data, count, elem, rs);
- count++;
- }
- T out = (T)data;
- outs.add(out);
- }
+ querry.append(" ");
+ querry.append(tableName);
+ querry.append(".");
- } catch (SQLException ex) {
- ex.printStackTrace();
- } catch (Exception ex) {
- ex.printStackTrace();
- } finally {
- entry.close();
- entry = null;
- }
- return outs;
+ querry.append(name);
+ }
+ querry.append(" FROM `");
+ querry.append(tableName);
+ querry.append("` ");
+ whereAppendQuery(querry, tableName, condition, firstField);
+ if (orderBy != null && orderBy.length() >= 1) {
+ querry.append(" ORDER BY ");
+ //querry.append(tableName);
+ //querry.append(".");
+ querry.append(orderBy);
+ }
+ if (linit != null && linit >= 1) {
+ querry.append(" LIMIT " + linit);
+ }
+ firstField = true;
+ LOGGER.debug("generate the querry: '{}'", querry.toString());
+ // prepare the request:
+ final PreparedStatement ps = entry.connection.prepareStatement(querry.toString(), Statement.RETURN_GENERATED_KEYS);
+ whereInjectValue(ps, condition);
+ // execute the request
+ final ResultSet rs = ps.executeQuery();
+ while (rs.next()) {
+ final Object data = clazz.getConstructors()[0].newInstance();
+ count = 1;
+ for (final Field elem : clazz.getFields()) {
+ // static field is only for internal global declaration ==> remove it ..
+ if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
+ continue;
+ }
+ final SqlWrapperAddOn addOn = findAddOnforField(elem);
+ if (addOn != null) {
+ continue;
+ }
+ final boolean createTime = elem.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0;
+ if (!full && createTime) {
+ continue;
+ }
+ //String name = elem.getName();
+ final boolean updateTime = elem.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0;
+ if (!full && updateTime) {
+ continue;
+ }
+ setValueFromDb(elem.getType(), data, count, elem, rs);
+ count++;
+ }
+ final T out = (T) data;
+ outs.add(out);
+ }
+
+ } catch (final SQLException ex) {
+ ex.printStackTrace();
+ } catch (final Exception ex) {
+ ex.printStackTrace();
+ } finally {
+ entry.close();
+ entry = null;
+ }
+ return outs;
}
-
- public static T get(Class clazz, long id) throws Exception {
- Field primaryKeyField = null;
- for (Field elem : clazz.getFields()) {
- // static field is only for internal global declaration ==> remove it ..
- if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
- continue;
- }
- boolean primaryKey = elem.getDeclaredAnnotationsByType(SQLPrimaryKey.class).length != 0;
- if (primaryKey) {
+
+ public static T get(final Class clazz, final long id) throws Exception {
+ Field primaryKeyField = null;
+ for (final Field elem : clazz.getFields()) {
+ // static field is only for internal global declaration ==> remove it ..
+ if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
+ continue;
+ }
+ if (AnnotationTools.isPrimaryKey(elem)) {
primaryKeyField = elem;
}
- }
+ }
if (primaryKeyField != null) {
- return SqlWrapper.getWhere(clazz, List.of(new WhereCondition(primaryKeyField.getName(), "=", id)), false);
+ return SqlWrapper.getWhere(clazz, new QuerryCondition(primaryKeyField.getName(), "=", id), false);
}
throw new Exception("Missing primary Key...");
}
-
- private enum StateLoad {
- DISABLE,
- NORMAL,
- ARRAY
- };
-
+
public static String getCurrentTimeStamp() {
- return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
+ return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
}
-
- public static List gets(Class clazz, boolean full) throws Exception {
+
+ public static List gets(final Class clazz, final boolean full) throws Exception {
LOGGER.debug("request get {} start @{}", clazz.getCanonicalName(), getCurrentTimeStamp());
- DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
- List out = new ArrayList<>();
- // real add in the BDD:
- try {
- String tableName = getTableName(clazz);
- //boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
- StringBuilder query = new StringBuilder();
- query.append("SELECT ");
- boolean firstField = true;
- int count = 0;
- StateLoad[] autoClasify = new StateLoad[clazz.getFields().length];
- int indexAutoClasify = 0;
- boolean hasDeleted = false;
- for (Field elem : clazz.getFields()) {
- // static field is only for internal global declaration ==> remove it ..
- if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
- continue;
- }
- boolean notRead = elem.getDeclaredAnnotationsByType(SQLNotRead.class).length != 0;
+ DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
+ final List out = new ArrayList<>();
+ // real add in the BDD:
+ try {
+ final String tableName = AnnotationTools.getTableName(clazz);
+ //boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
+ final StringBuilder querry = new StringBuilder();
+ querry.append("SELECT ");
+ boolean firstField = true;
+ int count = 0;
+ //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! A revoir, il faut faire une liste dynamique qui dépend des add_ons....
+ //StateLoad[] autoClasify = new StateLoad[clazz.getFields().length];
+ final List autoClasify = new ArrayList<>();
+ int indexAutoClasify = 0;
+ boolean hasDeleted = false;
+ for (final Field elem : clazz.getFields()) {
+ // static field is only for internal global declaration ==> remove it ..
+ if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
+ continue;
+ }
+ final boolean notRead = elem.getDeclaredAnnotationsByType(SQLNotRead.class).length != 0;
if (!full && notRead) {
- autoClasify[indexAutoClasify++] = StateLoad.DISABLE;
+ autoClasify.add(StateLoad.DISABLE);
continue;
}
if (!hasDeleted) {
hasDeleted = elem.getDeclaredAnnotationsByType(SQLDeleted.class).length != 0;
}
- String name = elem.getName();
- count++;
+ final String name = elem.getName();
if (firstField) {
- firstField = false;
+ firstField = false;
} else {
- query.append(",");
+ querry.append(",");
}
-
-
- ModelLink linkGeneric = getLinkMode(elem);
- if (linkGeneric == ModelLink.EXTERNAL) {
- autoClasify[indexAutoClasify++] = StateLoad.ARRAY;
- String localName = name;
- if (name.endsWith("s")) {
- localName = name.substring(0, name.length()-1);
+ final SqlWrapperAddOn addOn = findAddOnforField(elem);
+ if (addOn != null) {
+ count += addOn.generateQuerry(tableName, elem, querry, name, autoClasify);
+ } else {
+ count++;
+ autoClasify.add(StateLoad.NORMAL);
+ querry.append(" ");
+ querry.append(tableName);
+ querry.append(".");
+ querry.append(name);
+ }
+ }
+ querry.append(" FROM `");
+ querry.append(tableName);
+ querry.append("` ");
+ if (hasDeleted) {
+ querry.append(" WHERE ");
+ //querry.append(tableName);
+ //querry.append(".");
+ //querry.append(primaryKeyField.getName());
+ //querry.append(" = ?");
+ //querry.append(" AND ");
+ querry.append(tableName);
+ querry.append(".deleted = false ");
+ }
+ firstField = true;
+ LOGGER.debug("generate the querry: '{}'", querry.toString());
+ LOGGER.debug("request get {} prepare @{}", clazz.getCanonicalName(), getCurrentTimeStamp());
+ // prepare the request:
+ final PreparedStatement ps = entry.connection.prepareStatement(querry.toString(), Statement.RETURN_GENERATED_KEYS);
+
+ LOGGER.debug("request get {} querry @{}", clazz.getCanonicalName(), getCurrentTimeStamp());
+ // execute the request
+ final ResultSet rs = ps.executeQuery();
+ LOGGER.debug("request get {} transform @{}", clazz.getCanonicalName(), getCurrentTimeStamp());
+
+ while (rs.next()) {
+ indexAutoClasify = 0;
+ final Object data = clazz.getConstructors()[0].newInstance();
+ count = 1;
+ for (final Field elem : clazz.getFields()) {
+ if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
+ continue;
}
- String tmpVariable = "tmp_" + Integer.toString(count);
- query.append(" (SELECT GROUP_CONCAT(");
- query.append(tmpVariable);
- query.append(".");
- query.append(localName);
- query.append("_id SEPARATOR '-') FROM ");
- query.append(tableName);
- query.append("_link_");
- query.append(localName);
- query.append(" ");
- query.append(tmpVariable);
- query.append(" WHERE ");
- query.append(tmpVariable);
- query.append(".deleted = false AND ");
- query.append(tableName);
- query.append(".id = ");
- query.append(tmpVariable);
- query.append(".");
- query.append(tableName);
- query.append("_id GROUP BY ");
- query.append(tmpVariable);
- query.append(".");
- query.append(tableName);
- query.append("_id ) AS ");
- query.append(name);
- query.append(" ");
/*
- " (SELECT GROUP_CONCAT(tmp.data_id SEPARATOR '-')" +
- " FROM cover_link_node tmp" +
- " WHERE tmp.deleted = false" +
- " AND node.id = tmp.node_id" +
- " GROUP BY tmp.node_id) AS covers" +
- */
- } else {
- if (linkGeneric == ModelLink.NONE) {
- autoClasify[indexAutoClasify++] = StateLoad.NORMAL;
- } else {
- autoClasify[indexAutoClasify++] = StateLoad.ARRAY;
+ boolean notRead = elem.getDeclaredAnnotationsByType(SQLNotRead.class).length != 0;
+ */
+ final boolean notRead = autoClasify.get(indexAutoClasify) == StateLoad.DISABLE;
+ if (!full && notRead) {
+ indexAutoClasify++;
+ continue;
}
- query.append(" ");
- query.append(tableName);
- query.append(".");
- query.append(name);
+ //String name = elem.getName();
+ //boolean linkGeneric = elem.getDeclaredAnnotationsByType(SQLTableLinkGeneric.class).length != 0;
+
+ final SqlWrapperAddOn addOn = findAddOnforField(elem);
+ if (addOn != null) {
+ count += addOn.fillFromQuerry(rs, elem, data, count);
+ } else {
+ setValueFromDb(elem.getType(), data, count, elem, rs);
+ count++;
+ }
+ indexAutoClasify++;
}
- }
- query.append(" FROM `");
- query.append(tableName);
- query.append("` ");
- if (hasDeleted) {
- query.append(" WHERE ");
- //query.append(tableName);
- //query.append(".");
- //query.append(primaryKeyField.getName());
- //query.append(" = ?");
- //query.append(" AND ");
- query.append(tableName);
- query.append(".deleted = false ");
- }
- firstField = true;
- LOGGER.debug("generate the querry: '{}'", query.toString());
- LOGGER.debug("request get {} prepare @{}", clazz.getCanonicalName(), getCurrentTimeStamp());
- // prepare the request:
- PreparedStatement ps = entry.connection.prepareStatement(query.toString(), Statement.RETURN_GENERATED_KEYS);
+ //logger.debug("Read: {}", (T)data);
+ out.add((T) data);
+ }
- LOGGER.debug("request get {} query @{}", clazz.getCanonicalName(), getCurrentTimeStamp());
- // execute the request
- ResultSet rs = ps.executeQuery();
- LOGGER.debug("request get {} transform @{}", clazz.getCanonicalName(), getCurrentTimeStamp());
-
- while (rs.next()) {
- indexAutoClasify = 0;
- Object data = clazz.getConstructors()[0].newInstance();
- count = 1;
- for (Field elem : clazz.getFields()) {
- if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
- continue;
- }
- /*
- boolean notRead = elem.getDeclaredAnnotationsByType(SQLNotRead.class).length != 0;
- */
- boolean notRead = autoClasify[indexAutoClasify] == StateLoad.DISABLE;
- if (!full && notRead) {
- indexAutoClasify++;
- continue;
- }
- //String name = elem.getName();
- //boolean linkGeneric = elem.getDeclaredAnnotationsByType(SQLTableLinkGeneric.class).length != 0;
- boolean linkGeneric = autoClasify[indexAutoClasify] == StateLoad.ARRAY;
- if (linkGeneric) {
- List idList = getListOfIds(rs, count);
- elem.set(data, idList);
- } else {
- setValueFromDb(elem.getType(), data, count, elem, rs);
- }
- indexAutoClasify++;
- count++;
- }
- //logger.debug("Read: {}", (T)data);
- out.add((T)data);
- }
+ LOGGER.debug("request get {} ready @{}", clazz.getCanonicalName(), getCurrentTimeStamp());
- LOGGER.debug("request get {} ready @{}", clazz.getCanonicalName(), getCurrentTimeStamp());
-
- } catch (SQLException ex) {
- ex.printStackTrace();
- } finally {
- entry.close();
- entry = null;
- }
- return out;
+ } catch (final SQLException ex) {
+ ex.printStackTrace();
+ } finally {
+ entry.close();
+ entry = null;
+ }
+ return out;
}
- public static void addLink(Class> clazz, long localKey, String table, long remoteKey) throws Exception {
- String tableName = getTableName(clazz);
- DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
- long uniqueSQLID = -1;
- // real add in the BDD:
- try {
- // prepare the request:
- String query = "INSERT INTO " + tableName + "_link_" + table + " (create_date, modify_date, " + tableName + "_id, " + table + "_id)" +
- " VALUES (" + getDBNow() + ", " + getDBNow() + ", ?, ?)";
- PreparedStatement ps = entry.connection.prepareStatement(query,
- Statement.RETURN_GENERATED_KEYS);
- int iii = 1;
- ps.setLong(iii++, localKey);
- ps.setLong(iii++, remoteKey);
- // execute the request
- int affectedRows = ps.executeUpdate();
- if (affectedRows == 0) {
- throw new SQLException("Creating data failed, no rows affected.");
- }
- // retrieve uid inserted
- try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
- if (generatedKeys.next()) {
- uniqueSQLID = generatedKeys.getLong(1);
- } else {
- throw new SQLException("Creating user failed, no ID obtained (1).");
- }
- } catch (Exception ex) {
- LOGGER.debug("Can not get the UID key inserted ... ");
- ex.printStackTrace();
- throw new SQLException("Creating user failed, no ID obtained (2).");
- }
- } catch (SQLException ex) {
- ex.printStackTrace();
- throw new ExceptionDBInterface(500, "SQL error: " + ex.getMessage());
- } finally {
- entry.close();
- entry = null;
- }
- }
- public static void removeLink(Class> clazz, long localKey, String table, long remoteKey) throws Exception {
- String tableName = getTableName(clazz);
- DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
- String query = "UPDATE `" + tableName + "_link_" + table + "` SET `modify_date`=" + getDBNow() + ", `deleted`=true WHERE `" + tableName + "_id` = ? AND `" + table + "_id` = ?";
- try {
- PreparedStatement ps = entry.connection.prepareStatement(query);
- int iii = 1;
- ps.setLong(iii++, localKey);
- ps.setLong(iii++, remoteKey);
- ps.executeUpdate();
- } catch (SQLException ex) {
- ex.printStackTrace();
- throw new ExceptionDBInterface(500, "SQL error: " + ex.getMessage());
- } finally {
- entry.close();
- entry = null;
- }
- }
-
- /**
- * extract a list of "-" separated element from a SQL input data.
- * @param rs Result Set of the BDD
- * @param iii Id in the result set
- * @return The list of Long value
- * @throws SQLException if an error is generated in the sql request.
- */
- protected static List getListOfIds(ResultSet rs, int iii) throws SQLException {
- String trackString = rs.getString(iii);
- if (rs.wasNull()) {
- return null;
- }
- List out = new ArrayList<>();
- String[] elements = trackString.split("-");
- for (String elem : elements) {
- Long tmp = Long.parseLong(elem);
- out.add(tmp);
- }
- return out;
- }
- /**
- * Convert the list if external id in a string '-' separated
- * @param ids List of value (null are removed)
- * @return '-' string separated
- */
- protected static String getStringOfIds(List ids) {
- List tmp = new ArrayList<>();
- for (Long elem : ids) {
- tmp.add(elem);
- }
- return tmp.stream().map(x->String.valueOf(x)).collect(Collectors.joining("-"));
- }
-
-
- public static void delete(Class> clazz, long id) throws Exception {
+ public static void delete(final Class> clazz, final long id) throws Exception {
// TODO: I am not sure this is a real good idea.
}
- public static int setDelete(Class> clazz, long id) throws Exception {
- return setDeleteWhere(clazz, List.of(
- new WhereCondition("id", "=", id)
- ));
+
+ public static int setDelete(final Class> clazz, final long id) throws Exception {
+ return setDeleteWhere(clazz, new QuerryCondition("id", "=", id));
}
+
public static String getDBNow() {
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
return "now(3)";
}
return "DATE()";
}
- public static int setDeleteWhere(Class> clazz, List condition) throws Exception {
- String tableName = getTableName(clazz);
- DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
- StringBuilder query = new StringBuilder();
- query.append("UPDATE `");
- query.append(tableName);
- query.append("` SET `modify_date`=");
- query.append(getDBNow());
- query.append(", `deleted`=true ");
- whereAppendQuery(query, tableName, condition, false);
- try {
- PreparedStatement ps = entry.connection.prepareStatement(query.toString());
- whereInjectValue(ps, condition);
- int affectedRows = ps.executeUpdate();
- return affectedRows;
- } finally {
- entry.close();
- entry = null;
- }
- }
-
-
- public static int unsetDelete(Class> clazz, long id) throws Exception {
- return unsetDeleteWhere(clazz, List.of(
- new WhereCondition("id", "=", id)
- ));
- }
-
- public static int unsetDeleteWhere(Class> clazz, List condition) throws Exception {
- String tableName = getTableName(clazz);
- DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
- StringBuilder query = new StringBuilder();
- query.append("UPDATE `");
- query.append(tableName);
- query.append("` SET `modify_date`=");
- query.append(getDBNow());
- query.append(", `deleted`=false ");
- whereAppendQuery(query, tableName, condition, false);
- try {
- PreparedStatement ps = entry.connection.prepareStatement(query.toString());
- whereInjectValue(ps, condition);
- int affectedRows = ps.executeUpdate();
- return affectedRows;
- } finally {
- entry.close();
- entry = null;
- }
+
+ public static int setDeleteWhere(final Class> clazz, final QuerryItem condition) throws Exception {
+ final String tableName = AnnotationTools.getTableName(clazz);
+ DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
+ final StringBuilder querry = new StringBuilder();
+ querry.append("UPDATE `");
+ querry.append(tableName);
+ querry.append("` SET `modify_date`=");
+ querry.append(getDBNow());
+ querry.append(", `deleted`=true ");
+ whereAppendQuery(querry, tableName, condition, false);
+ try {
+ final PreparedStatement ps = entry.connection.prepareStatement(querry.toString());
+ whereInjectValue(ps, condition);
+ final int affectedRows = ps.executeUpdate();
+ return affectedRows;
+ } finally {
+ entry.close();
+ entry = null;
+ }
}
- public static List createTable(Class> clazz) throws Exception {
+ public static int unsetDelete(final Class> clazz, final long id) throws Exception {
+ return unsetDeleteWhere(clazz, new QuerryCondition("id", "=", id));
+ }
+
+ public static int unsetDeleteWhere(final Class> clazz, final QuerryItem condition) throws Exception {
+ final String tableName = AnnotationTools.getTableName(clazz);
+ DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
+ final StringBuilder querry = new StringBuilder();
+ querry.append("UPDATE `");
+ querry.append(tableName);
+ querry.append("` SET `modify_date`=");
+ querry.append(getDBNow());
+ querry.append(", `deleted`=false ");
+ whereAppendQuery(querry, tableName, condition, false);
+ try {
+ final PreparedStatement ps = entry.connection.prepareStatement(querry.toString());
+ whereInjectValue(ps, condition);
+ final int affectedRows = ps.executeUpdate();
+ return affectedRows;
+ } finally {
+ entry.close();
+ entry = null;
+ }
+ }
+
+ public static List createTable(final Class> clazz) throws Exception {
return createTable(clazz, true);
}
- public static List createTable(Class> clazz, boolean createDrop) throws Exception {
- String tableName = getTableName(clazz);
- boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
- List outList = new ArrayList<>();
- StringBuilder out = new StringBuilder();
+
+ public static void createTablesSpecificType(final String tableName, final Field elem, final StringBuilder mainTableBuilder, final List ListOtherTables, final boolean createIfNotExist,
+ final boolean createDrop, final int fieldId, final Class> classModel) throws Exception {
+ final String name = elem.getName();
+ final Integer limitSize = AnnotationTools.getLimitSize(elem);
+ final boolean notNull = AnnotationTools.getNotNull(elem);
+
+ final boolean primaryKey = AnnotationTools.isPrimaryKey(elem);
+ final GenerationType strategy = AnnotationTools.getStrategy(elem);
+
+ final boolean createTime = elem.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0;
+ final boolean updateTime = elem.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0;
+ final String comment = AnnotationTools.getComment(elem);
+ final String defaultValue = AnnotationTools.getDefault(elem);
+
+ if (fieldId == 0) {
+ mainTableBuilder.append("\n\t\t`");
+ } else {
+ mainTableBuilder.append(",\n\t\t`");
+ }
+ mainTableBuilder.append(name);
+ mainTableBuilder.append("` ");
+ String typeValue = null;
+ typeValue = convertTypeInSQL(classModel);
+ if (typeValue.equals("text") && !ConfigBaseVariable.getDBType().equals("sqlite")) {
+ if (limitSize != null) {
+ mainTableBuilder.append("varchar(");
+ mainTableBuilder.append(limitSize);
+ mainTableBuilder.append(")");
+ } else {
+ mainTableBuilder.append("text");
+ if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
+ mainTableBuilder.append(" CHARACTER SET utf8");
+ }
+ }
+ } else {
+ mainTableBuilder.append(typeValue);
+ }
+ mainTableBuilder.append(" ");
+ if (notNull) {
+ if (!primaryKey || !ConfigBaseVariable.getDBType().equals("sqlite")) {
+ mainTableBuilder.append("NOT NULL ");
+ }
+ if (defaultValue == null) {
+ if (updateTime || createTime) {
+ mainTableBuilder.append("DEFAULT CURRENT_TIMESTAMP");
+ if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
+ mainTableBuilder.append("(3)");
+ }
+ mainTableBuilder.append(" ");
+ }
+ if (updateTime) {
+ if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
+ mainTableBuilder.append("ON UPDATE CURRENT_TIMESTAMP");
+ mainTableBuilder.append("(3)");
+ }
+ mainTableBuilder.append(" ");
+ }
+ } else {
+ mainTableBuilder.append("DEFAULT ");
+ if ("CURRENT_TIMESTAMP(3)".equals(defaultValue) && ConfigBaseVariable.getDBType().equals("sqlite")) {
+ mainTableBuilder.append("CURRENT_TIMESTAMP");
+ } else {
+ mainTableBuilder.append(defaultValue);
+ }
+ mainTableBuilder.append(" ");
+ if (updateTime) {
+ if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
+ mainTableBuilder.append("ON UPDATE CURRENT_TIMESTAMP");
+ mainTableBuilder.append("(3)");
+ }
+ mainTableBuilder.append(" ");
+ }
+ }
+ } else if (defaultValue == null) {
+ if (updateTime || createTime) {
+ if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
+ mainTableBuilder.append("DEFAULT CURRENT_TIMESTAMP ");
+ } else {
+ mainTableBuilder.append("DEFAULT CURRENT_TIMESTAMP(3) ");
+ }
+ } else {
+ mainTableBuilder.append("DEFAULT NULL ");
+ }
+ } else {
+ mainTableBuilder.append("DEFAULT ");
+ mainTableBuilder.append(defaultValue);
+ mainTableBuilder.append(" ");
+
+ }
+ if (primaryKey && ConfigBaseVariable.getDBType().equals("sqlite")) {
+ mainTableBuilder.append("PRIMARY KEY ");
+
+ }
+ if (strategy == GenerationType.IDENTITY) {
+ if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
+ mainTableBuilder.append("AUTO_INCREMENT ");
+ } else {
+ mainTableBuilder.append("AUTOINCREMENT ");
+ }
+ } else if (strategy != null) {
+ throw new Exception("Can not generate a stategy different of IDENTITY");
+ }
+
+ if (comment != null && !ConfigBaseVariable.getDBType().equals("sqlite")) {
+ mainTableBuilder.append("COMMENT '");
+ mainTableBuilder.append(comment.replace('\'', '\''));
+ mainTableBuilder.append("' ");
+ }
+ }
+
+ public static List createTable(final Class> clazz, final boolean createDrop) throws Exception {
+ final String tableName = AnnotationTools.getTableName(clazz);
+ final boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
+ final List outList = new ArrayList<>();
+ final StringBuilder out = new StringBuilder();
// Drop Table
if (createIfNotExist && createDrop) {
- StringBuilder tableTmp = new StringBuilder();
+ final StringBuilder tableTmp = new StringBuilder();
tableTmp.append("DROP TABLE IF EXISTS `");
tableTmp.append(tableName);
tableTmp.append("`;");
@@ -1299,256 +1220,53 @@ public class SqlWrapper {
out.append("CREATE TABLE `");
out.append(tableName);
out.append("` (");
- boolean firstField = true;
+ int fieldId = 0;
LOGGER.debug("===> TABLE `{}`", tableName);
- String primaryKeyValue = null;
- for (Field elem : clazz.getFields()) {
- // static field is only for internal global declaration ==> remove it ..
- if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
- continue;
- }
+ final List primaryKeys = new ArrayList<>();
- String name = elem.getName();
- Integer limitSize = getLimitSize(elem);
- boolean notNull = elem.getDeclaredAnnotationsByType(SQLNotNull.class).length != 0;
- boolean autoIncrement = elem.getDeclaredAnnotationsByType(SQLAutoIncrement.class).length != 0;
-
- boolean primaryKey = elem.getDeclaredAnnotationsByType(SQLPrimaryKey.class).length != 0;
- //boolean sqlNotRead = elem.getDeclaredAnnotationsByType(SQLNotRead.class).length != 0;
- boolean createTime = elem.getDeclaredAnnotationsByType(SQLCreateTime.class).length != 0;
- boolean updateTime = elem.getDeclaredAnnotationsByType(SQLUpdateTime.class).length != 0;
- ModelLink linkGeneric = getLinkMode(elem);
- String comment = getComment(elem);
- String defaultValue = getDefault(elem);
- //logger.debug(" ==> elem `" + name + "` primaryKey=" + primaryKey + " linkGeneric=" + linkGeneric);
-
-
- if (primaryKey) {
- primaryKeyValue = name;
+ for (final Field elem : clazz.getFields()) {
+ // DEtect the primary key (support only one primary key right now...
+ if (AnnotationTools.isPrimaryKey(elem)) {
+ primaryKeys.add(elem.getName());
}
- // special case with external link table:
- if (linkGeneric == ModelLink.EXTERNAL) {
- String localName = name;
- if (name.endsWith("s")) {
- localName = name.substring(0, name.length()-1);
- }
- if (createIfNotExist && createDrop) {
- StringBuilder tableTmp = new StringBuilder();
- tableTmp.append("DROP TABLE IF EXISTS `");
- tableTmp.append(tableName);
- tableTmp.append("_link_");
- tableTmp.append(localName);
- tableTmp.append("`;");
- outList.add(tableTmp.toString());
- }
- StringBuilder otherTable = new StringBuilder();
- otherTable.append("CREATE TABLE `");
- otherTable.append(tableName);
- otherTable.append("_link_");
- otherTable.append(localName);
- otherTable.append("`(\n");
- if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
- otherTable.append("\t\t`id` bigint NOT NULL AUTO_INCREMENT,\n");
- otherTable.append("\t\t`deleted` tinyint(1) NOT NULL DEFAULT '0',\n");
- otherTable.append("\t\t`create_date` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),\n");
- otherTable.append("\t\t`modify_date` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),\n");
+ }
+
+ for (final Field elem : clazz.getFields()) {
+ // static field is only for internal global declaration ==> remove it ..
+ if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
+ continue;
+ }
+ if (isAddOnField(elem)) {
+ final SqlWrapperAddOn addOn = findAddOnforField(elem);
+ LOGGER.info("Create type for: {} ==> {} (ADD-ON)", elem.getName(), elem.getType());
+ if (addOn != null) {
+ addOn.createTables(tableName, elem, out, outList, createIfNotExist, createDrop, fieldId);
} else {
- otherTable.append("\t\t`id` INTEGER PRIMARY KEY AUTOINCREMENT,\n");
- otherTable.append("\t\t`deleted` INTEGER NOT NULL DEFAULT '0',\n");
- otherTable.append("\t\t`create_date` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP,\n");
- otherTable.append("\t\t`modify_date` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP,\n");
+ throw new Exception("Element matked as add-on but add-on does not loaded: table:" + tableName + " field name=" + elem.getName() + " type=" + elem.getType());
}
- otherTable.append("\t\t`");
- otherTable.append(tableName);
- if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
- otherTable.append("_id` bigint NOT NULL,\n");
- } else {
- otherTable.append("_id` INTEGER NOT NULL,\n");
- }
- otherTable.append("\t\t`");
- otherTable.append(localName);
- if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
- otherTable.append("_id` bigint NOT NULL\n");
- } else {
- otherTable.append("_id` INTEGER NOT NULL\n");
- }
- if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
- otherTable.append("\t, PRIMARY KEY (`id`)\n");
- }
- otherTable.append("\t)");
- if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
- otherTable.append(" ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;\n\n");
- }
- otherTable.append(";");
- outList.add(otherTable.toString());
} else {
- if (firstField) {
- out.append("\n\t\t`");
- firstField = false;
- } else {
- out.append(",\n\t\t`");
+ LOGGER.info("Create type for: {} ==> {}", elem.getName(), elem.getType());
+ SqlWrapper.createTablesSpecificType(tableName, elem, out, outList, createIfNotExist, createDrop, fieldId, elem.getType());
+ }
+ fieldId++;
+ }
+ if (primaryKeys.size() != 0 && !ConfigBaseVariable.getDBType().equals("sqlite")) {
+ out.append(",\n\tPRIMARY KEY (`");
+ for (int iii = 0; iii < primaryKeys.size(); iii++) {
+ if (iii != 0) {
+ out.append(",");
}
- out.append(name);
- out.append("` ");
- String typeValue = null;
- if (linkGeneric == ModelLink.INTERNAL) {
- typeValue = convertTypeInSQL(String.class);
- out.append(typeValue);
- } else {
- typeValue = convertTypeInSQL(elem.getType());
- if (typeValue.equals("text") && !ConfigBaseVariable.getDBType().equals("sqlite")) {
- if (limitSize != null) {
- out.append("varchar(");
- out.append(limitSize);
- out.append(")");
- } else {
- out.append("text");
- if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
- out.append(" CHARACTER SET utf8");
- }
- }
- } else {
- out.append(typeValue);
- }
- }
- out.append(" ");
- if (notNull) {
- if (!name.equals(primaryKeyValue) || !ConfigBaseVariable.getDBType().equals("sqlite")) {
- out.append("NOT NULL ");
- }
- if (defaultValue == null) {
- if (updateTime || createTime) {
- out.append("DEFAULT CURRENT_TIMESTAMP");
- if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
- out.append("(3)");
- }
- out.append(" ");
- }
- if (updateTime) {
- if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
- out.append("ON UPDATE CURRENT_TIMESTAMP");
- out.append("(3)");
- }
- out.append(" ");
- }
- } else {
- out.append("DEFAULT ");
- if ("CURRENT_TIMESTAMP(3)".equals(defaultValue) && ConfigBaseVariable.getDBType().equals("sqlite")) {
- out.append("CURRENT_TIMESTAMP");
- } else {
- out.append(defaultValue);
- }
- out.append(" ");
- if (updateTime) {
- if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
- out.append("ON UPDATE CURRENT_TIMESTAMP");
- out.append("(3)");
- }
- out.append(" ");
- }
- }
- } else if (defaultValue == null) {
- if (updateTime || createTime) {
- if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
- out.append("DEFAULT CURRENT_TIMESTAMP ");
- }else {
- out.append("DEFAULT CURRENT_TIMESTAMP(3) ");
- }
- } else {
- out.append("DEFAULT NULL ");
- }
- } else {
- out.append("DEFAULT ");
- out.append(defaultValue);
- out.append(" ");
-
- }
- if (name.equals(primaryKeyValue) && ConfigBaseVariable.getDBType().equals("sqlite")) {
- out.append("PRIMARY KEY ");
-
- }
- if (autoIncrement) {
- if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
- out.append("AUTO_INCREMENT ");
- } else {
- out.append("AUTOINCREMENT ");
- }
- }
-
- if (comment != null && !ConfigBaseVariable.getDBType().equals("sqlite")) {
- out.append("COMMENT '");
- out.append(comment.replaceAll("'", "\'"));
- out.append("' ");
- }
- }
- }
- if (primaryKeyValue != null && !ConfigBaseVariable.getDBType().equals("sqlite")) {
- out.append(",\n\tPRIMARY KEY (`");
- out.append(primaryKeyValue);
- out.append("`)");
- }
- out.append("\n\t)");
- if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
- out.append(" ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci");
- }
- out.append(";");
- outList.add( out.toString());
- return outList;
+ out.append(primaryKeys.get(iii));
+ }
+ out.append("`)");
+ }
+ out.append("\n\t)");
+ if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
+ out.append(" ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci");
+ }
+ out.append(";");
+ outList.add(out.toString());
+ return outList;
}
-
-
- public static String getTableName(final Class> element) throws Exception {
- final Annotation[] annotation = element.getDeclaredAnnotationsByType(SQLTableName.class);
- if (annotation.length == 0) {
- return null;
- }
- if (annotation.length > 1) {
- throw new Exception("Must not have more than 1 element @AknotDescription on " + element.getClass().getCanonicalName());
- }
- final String tmp = ((SQLTableName) annotation[0]).value();
- if (tmp == null) {
- return null;
- }
- return tmp;
- }
- public static String getComment(final Field element) throws Exception {
- final Annotation[] annotation = element.getDeclaredAnnotationsByType(SQLComment.class);
- if (annotation.length == 0) {
- return null;
- }
- if (annotation.length > 1) {
- throw new Exception("Must not have more than 1 element @AknotDescription on " + element.getClass().getCanonicalName());
- }
- final String tmp = ((SQLComment) annotation[0]).value();
- if (tmp == null) {
- return null;
- }
- return tmp;
- }
- public static String getDefault(final Field element) throws Exception {
- final Annotation[] annotation = element.getDeclaredAnnotationsByType(SQLDefault.class);
- if (annotation.length == 0) {
- return null;
- }
- if (annotation.length > 1) {
- throw new Exception("Must not have more than 1 element @AknotDescription on " + element.getClass().getCanonicalName());
- }
- final String tmp = ((SQLDefault) annotation[0]).value();
- if (tmp == null) {
- return null;
- }
- return tmp;
- }
- public static Integer getLimitSize(final Field element) throws Exception {
- final Annotation[] annotation = element.getDeclaredAnnotationsByType(SQLLimitSize.class);
- if (annotation.length == 0) {
- return null;
- }
- if (annotation.length > 1) {
- throw new Exception("Must not have more than 1 element @AknotDescription on " + element.getClass().getCanonicalName());
- }
- return ((SQLLimitSize) annotation[0]).value();
- }
-
}
\ No newline at end of file
diff --git a/src/org/kar/archidata/sqlWrapper/SqlWrapperAddOn.java b/src/org/kar/archidata/sqlWrapper/SqlWrapperAddOn.java
index 35ad376..f35a266 100644
--- a/src/org/kar/archidata/sqlWrapper/SqlWrapperAddOn.java
+++ b/src/org/kar/archidata/sqlWrapper/SqlWrapperAddOn.java
@@ -1,6 +1,10 @@
package org.kar.archidata.sqlWrapper;
import java.lang.reflect.Field;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
public interface SqlWrapperAddOn {
/**
@@ -8,12 +12,14 @@ public interface SqlWrapperAddOn {
* @return The annotation class
*/
Class> getAnnotationClass();
+
/**
* Get the SQL type that is needed to declare for the specific Field Type.
* @param elem Field to declare.
* @return SQL type to create.
*/
String getSQLFieldType(Field elem);
+
/**
* Check if the field is manage by the local add-on
* @param elem Field to inspect.
@@ -21,4 +27,17 @@ public interface SqlWrapperAddOn {
*/
boolean isCompatibleField(Field elem);
+ int insertData(PreparedStatement ps, Object data, int iii) throws SQLException;
+
+ // External mean that the type of the object is absolutely not obvious...
+ boolean isExternal();
+
+ int generateQuerry(String tableName, Field elem, StringBuilder querry, String name, List autoClasify);
+
+ int fillFromQuerry(ResultSet rs, Field elem, Object data, int count) throws SQLException, IllegalArgumentException, IllegalAccessException;
+
+ boolean canUpdate();
+
+ void createTables(String tableName, Field elem, StringBuilder mainTableBuilder, List ListOtherTables, boolean createIfNotExist, boolean createDrop, int fieldId) throws Exception;
+
}
diff --git a/src/org/kar/archidata/sqlWrapper/StateLoad.java b/src/org/kar/archidata/sqlWrapper/StateLoad.java
new file mode 100644
index 0000000..08f6519
--- /dev/null
+++ b/src/org/kar/archidata/sqlWrapper/StateLoad.java
@@ -0,0 +1,5 @@
+package org.kar.archidata.sqlWrapper;
+
+public enum StateLoad {
+ DISABLE, NORMAL, ARRAY
+}
\ No newline at end of file
diff --git a/src/org/kar/archidata/sqlWrapper/WhereCondition.java b/src/org/kar/archidata/sqlWrapper/WhereCondition.java
deleted file mode 100644
index 86f7f5b..0000000
--- a/src/org/kar/archidata/sqlWrapper/WhereCondition.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.kar.archidata.sqlWrapper;
-
-public record WhereCondition(
- String key,
- String comparator,
- Object Value) {
-
-}
diff --git a/src/org/kar/archidata/sqlWrapper/addOn/AddOnSQLTableExternalForeinKeyAsList.java b/src/org/kar/archidata/sqlWrapper/addOn/AddOnSQLTableExternalForeinKeyAsList.java
new file mode 100644
index 0000000..c347f4d
--- /dev/null
+++ b/src/org/kar/archidata/sqlWrapper/addOn/AddOnSQLTableExternalForeinKeyAsList.java
@@ -0,0 +1,115 @@
+package org.kar.archidata.sqlWrapper.addOn;
+
+import java.lang.reflect.Field;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.kar.archidata.annotation.addOn.SQLTableExternalLink;
+import org.kar.archidata.sqlWrapper.SqlWrapper;
+import org.kar.archidata.sqlWrapper.SqlWrapperAddOn;
+import org.kar.archidata.sqlWrapper.StateLoad;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AddOnSQLTableExternalForeinKeyAsList implements SqlWrapperAddOn {
+ static final Logger LOGGER = LoggerFactory.getLogger(AddOnSQLTableExternalLink.class);
+
+ /**
+ * Convert the list if external id in a string '-' separated
+ * @param ids List of value (null are removed)
+ * @return '-' string separated
+ */
+ protected static String getStringOfIds(List ids) {
+ List tmp = new ArrayList<>();
+ for (Long elem : ids) {
+ tmp.add(elem);
+ }
+ return tmp.stream().map(x -> String.valueOf(x)).collect(Collectors.joining("-"));
+ }
+
+ /**
+ * extract a list of "-" separated element from a SQL input data.
+ * @param rs Result Set of the BDD
+ * @param iii Id in the result set
+ * @return The list of Long value
+ * @throws SQLException if an error is generated in the sql request.
+ */
+ protected static List getListOfIds(ResultSet rs, int iii) throws SQLException {
+ String trackString = rs.getString(iii);
+ if (rs.wasNull()) {
+ return null;
+ }
+ List out = new ArrayList<>();
+ String[] elements = trackString.split("-");
+ for (String elem : elements) {
+ Long tmp = Long.parseLong(elem);
+ out.add(tmp);
+ }
+ return out;
+ }
+
+ @Override
+ public Class> getAnnotationClass() {
+ return SQLTableExternalLink.class;
+ }
+
+ public String getSQLFieldType(Field elem) {
+ return "STRING";
+ }
+
+ public boolean isCompatibleField(Field elem) {
+ SQLTableExternalLink decorators = elem.getDeclaredAnnotation(SQLTableExternalLink.class);
+ return decorators != null;
+ }
+
+ public int insertData(PreparedStatement ps, Object data, int iii) throws SQLException {
+ if (data == null) {
+ ps.setNull(iii++, Types.BIGINT);
+ } else {
+ @SuppressWarnings("unchecked")
+ String dataTmp = getStringOfIds((List) data);
+ ps.setString(iii++, dataTmp);
+ }
+ return iii++;
+ }
+
+ @Override
+ public boolean isExternal() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public int generateQuerry(String tableName, Field elem, StringBuilder querry, String name, List autoClasify) {
+ autoClasify.add(StateLoad.ARRAY);
+ querry.append(" ");
+ querry.append(tableName);
+ querry.append(".");
+ querry.append(name);
+ return 1;
+ }
+
+ @Override
+ public int fillFromQuerry(ResultSet rs, Field elem, Object data, int count) throws SQLException, IllegalArgumentException, IllegalAccessException {
+ List idList = getListOfIds(rs, count);
+ elem.set(data, idList);
+ return 1;
+ }
+
+ @Override
+ public boolean canUpdate() {
+ return true;
+ }
+
+ @Override
+ public void createTables(String tableName, Field elem, StringBuilder mainTableBuilder, List ListOtherTables, boolean createIfNotExist, boolean createDrop, int fieldId) throws Exception {
+ // TODO Auto-generated method stub
+
+ SqlWrapper.createTablesSpecificType(tableName, elem, mainTableBuilder, ListOtherTables, createIfNotExist, createDrop, fieldId, String.class);
+ }
+}
diff --git a/src/org/kar/archidata/sqlWrapper/addOn/AddOnSQLTableExternalLink.java b/src/org/kar/archidata/sqlWrapper/addOn/AddOnSQLTableExternalLink.java
new file mode 100644
index 0000000..2285ef4
--- /dev/null
+++ b/src/org/kar/archidata/sqlWrapper/addOn/AddOnSQLTableExternalLink.java
@@ -0,0 +1,265 @@
+package org.kar.archidata.sqlWrapper.addOn;
+
+import java.lang.reflect.Field;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.kar.archidata.GlobalConfiguration;
+import org.kar.archidata.annotation.AnnotationTools;
+import org.kar.archidata.annotation.addOn.SQLTableExternalLink;
+import org.kar.archidata.db.DBEntry;
+import org.kar.archidata.sqlWrapper.SqlWrapper;
+import org.kar.archidata.sqlWrapper.SqlWrapper.ExceptionDBInterface;
+import org.kar.archidata.sqlWrapper.SqlWrapperAddOn;
+import org.kar.archidata.sqlWrapper.StateLoad;
+import org.kar.archidata.util.ConfigBaseVariable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AddOnSQLTableExternalLink implements SqlWrapperAddOn {
+ static final Logger LOGGER = LoggerFactory.getLogger(AddOnSQLTableExternalLink.class);
+
+ /**
+ * Convert the list if external id in a string '-' separated
+ * @param ids List of value (null are removed)
+ * @return '-' string separated
+ */
+ protected static String getStringOfIds(final List ids) {
+ final List tmp = new ArrayList<>(ids);
+ return tmp.stream().map(String::valueOf).collect(Collectors.joining("-"));
+ }
+
+ /**
+ * extract a list of "-" separated element from a SQL input data.
+ * @param rs Result Set of the BDD
+ * @param iii Id in the result set
+ * @return The list of Long value
+ * @throws SQLException if an error is generated in the sql request.
+ */
+ protected static List getListOfIds(final ResultSet rs, final int iii) throws SQLException {
+ final String trackString = rs.getString(iii);
+ if (rs.wasNull()) {
+ return null;
+ }
+ final List out = new ArrayList<>();
+ final String[] elements = trackString.split("-");
+ for (final String elem : elements) {
+ final Long tmp = Long.parseLong(elem);
+ out.add(tmp);
+ }
+ return out;
+ }
+
+ @Override
+ public Class> getAnnotationClass() {
+ return SQLTableExternalLink.class;
+ }
+
+ @Override
+ public String getSQLFieldType(final Field elem) {
+ return "STRING";
+ }
+
+ @Override
+ public boolean isCompatibleField(final Field elem) {
+ final SQLTableExternalLink decorators = elem.getDeclaredAnnotation(SQLTableExternalLink.class);
+ return decorators != null;
+ }
+
+ @Override
+ public int insertData(final PreparedStatement ps, final Object data, int iii) throws SQLException {
+ if (data == null) {
+ ps.setNull(iii++, Types.BIGINT);
+ } else {
+ // TODO: we must check if the model of data in a list of Long ... !!!!
+ @SuppressWarnings("unchecked")
+ final String dataTmp = getStringOfIds((List) data);
+ ps.setString(iii++, dataTmp);
+ }
+ return iii++;
+ }
+
+ @Override
+ public boolean isExternal() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public int generateQuerry(final String tableName, final Field elem, final StringBuilder querry, final String name, final List autoClasify) {
+
+ autoClasify.add(StateLoad.ARRAY);
+ String localName = name;
+ if (name.endsWith("s")) {
+ localName = name.substring(0, name.length() - 1);
+ }
+ final String tmpVariable = "tmp_" + Integer.toString(autoClasify.size());
+ querry.append(" (SELECT GROUP_CONCAT(");
+ querry.append(tmpVariable);
+ querry.append(".");
+ querry.append(localName);
+ querry.append("_id SEPARATOR '-') FROM ");
+ querry.append(tableName);
+ querry.append("_link_");
+ querry.append(localName);
+ querry.append(" ");
+ querry.append(tmpVariable);
+ querry.append(" WHERE ");
+ querry.append(tmpVariable);
+ querry.append(".deleted = false AND ");
+ querry.append(tableName);
+ querry.append(".id = ");
+ querry.append(tmpVariable);
+ querry.append(".");
+ querry.append(tableName);
+ querry.append("_id GROUP BY ");
+ querry.append(tmpVariable);
+ querry.append(".");
+ querry.append(tableName);
+ querry.append("_id ) AS ");
+ querry.append(name);
+ querry.append(" ");
+ /*
+ " (SELECT GROUP_CONCAT(tmp.data_id SEPARATOR '-')" +
+ " FROM cover_link_node tmp" +
+ " WHERE tmp.deleted = false" +
+ " AND node.id = tmp.node_id" +
+ " GROUP BY tmp.node_id) AS covers" +
+ */
+ return 1;
+ }
+
+ @Override
+ public int fillFromQuerry(final ResultSet rs, final Field elem, final Object data, final int count) throws SQLException, IllegalArgumentException, IllegalAccessException {
+ throw new IllegalAccessException("This Add-on has not the capability to insert data directly in DB");
+ }
+
+ @Override
+ public boolean canUpdate() {
+ return false;
+ }
+
+ public static void addLink(final Class> clazz, final long localKey, final String table, final long remoteKey) throws Exception {
+ final String tableName = AnnotationTools.getTableName(clazz);
+ DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
+ long uniqueSQLID = -1;
+ // real add in the BDD:
+ try {
+ // prepare the request:
+ final String querry = "INSERT INTO " + tableName + "_link_" + table + " (create_date, modify_date, " + tableName + "_id, " + table + "_id)" + " VALUES (" + SqlWrapper.getDBNow() + ", "
+ + SqlWrapper.getDBNow() + ", ?, ?)";
+ final PreparedStatement ps = entry.connection.prepareStatement(querry, Statement.RETURN_GENERATED_KEYS);
+ int iii = 1;
+ ps.setLong(iii++, localKey);
+ ps.setLong(iii++, remoteKey);
+ // execute the request
+ final int affectedRows = ps.executeUpdate();
+ if (affectedRows == 0) {
+ throw new SQLException("Creating data failed, no rows affected.");
+ }
+ // retrieve uid inserted
+ try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
+ if (generatedKeys.next()) {
+ uniqueSQLID = generatedKeys.getLong(1);
+ } else {
+ throw new SQLException("Creating user failed, no ID obtained (1).");
+ }
+ } catch (final Exception ex) {
+ LOGGER.debug("Can not get the UID key inserted ... ");
+ ex.printStackTrace();
+ throw new SQLException("Creating user failed, no ID obtained (2).");
+ }
+ } catch (final SQLException ex) {
+ ex.printStackTrace();
+ throw new ExceptionDBInterface(500, "SQL error: " + ex.getMessage());
+ } finally {
+ entry.close();
+ entry = null;
+ }
+ }
+
+ public static void removeLink(final Class> clazz, final long localKey, final String table, final long remoteKey) throws Exception {
+ final String tableName = AnnotationTools.getTableName(clazz);
+ DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
+ final String querry = "UPDATE `" + tableName + "_link_" + table + "` SET `modify_date`=" + SqlWrapper.getDBNow() + ", `deleted`=true WHERE `" + tableName + "_id` = ? AND `" + table
+ + "_id` = ?";
+ try {
+ final PreparedStatement ps = entry.connection.prepareStatement(querry);
+ int iii = 1;
+ ps.setLong(iii++, localKey);
+ ps.setLong(iii++, remoteKey);
+ ps.executeUpdate();
+ } catch (final SQLException ex) {
+ ex.printStackTrace();
+ throw new ExceptionDBInterface(500, "SQL error: " + ex.getMessage());
+ } finally {
+ entry.close();
+ entry = null;
+ }
+ }
+
+ @Override
+ public void createTables(final String tableName, final Field elem, final StringBuilder mainTableBuilder, final List ListOtherTables, final boolean createIfNotExist,
+ final boolean createDrop, final int fieldId) throws Exception {
+ final String name = elem.getName();
+ String localName = name;
+ if (name.endsWith("s")) {
+ localName = name.substring(0, name.length() - 1);
+ }
+ if (createIfNotExist && createDrop) {
+ final StringBuilder tableTmp = new StringBuilder();
+ tableTmp.append("DROP TABLE IF EXISTS `");
+ tableTmp.append(tableName);
+ tableTmp.append("_link_");
+ tableTmp.append(localName);
+ tableTmp.append("`;");
+ ListOtherTables.add(tableTmp.toString());
+ }
+ final StringBuilder otherTable = new StringBuilder();
+ otherTable.append("CREATE TABLE `");
+ otherTable.append(tableName);
+ otherTable.append("_link_");
+ otherTable.append(localName);
+ otherTable.append("`(\n");
+ if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
+ otherTable.append("\t\t`id` bigint NOT NULL AUTO_INCREMENT,\n");
+ otherTable.append("\t\t`deleted` tinyint(1) NOT NULL DEFAULT '0',\n");
+ otherTable.append("\t\t`create_date` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),\n");
+ otherTable.append("\t\t`modify_date` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),\n");
+ } else {
+ otherTable.append("\t\t`id` INTEGER PRIMARY KEY AUTOINCREMENT,\n");
+ otherTable.append("\t\t`deleted` INTEGER NOT NULL DEFAULT '0',\n");
+ otherTable.append("\t\t`create_date` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP,\n");
+ otherTable.append("\t\t`modify_date` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP,\n");
+ }
+ otherTable.append("\t\t`");
+ otherTable.append(tableName);
+ if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
+ otherTable.append("_id` bigint NOT NULL,\n");
+ } else {
+ otherTable.append("_id` INTEGER NOT NULL,\n");
+ }
+ otherTable.append("\t\t`");
+ otherTable.append(localName);
+ if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
+ otherTable.append("_id` bigint NOT NULL\n");
+ } else {
+ otherTable.append("_id` INTEGER NOT NULL\n");
+ }
+ if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
+ otherTable.append("\t, PRIMARY KEY (`id`)\n");
+ }
+ otherTable.append("\t)");
+ if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
+ otherTable.append(" ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;\n\n");
+ }
+ otherTable.append(";");
+ ListOtherTables.add(otherTable.toString());
+ }
+}
diff --git a/src/org/kar/archidata/sqlWrapper/addOn/ExternalLink.java b/src/org/kar/archidata/sqlWrapper/addOn/ExternalLink.java
deleted file mode 100644
index c040a91..0000000
--- a/src/org/kar/archidata/sqlWrapper/addOn/ExternalLink.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.kar.archidata.sqlWrapper.addOn;
-
-import java.lang.reflect.Field;
-
-import org.kar.archidata.annotation.SQLTableLinkGeneric;
-import org.kar.archidata.sqlWrapper.SqlWrapperAddOn;
-
-public class ExternalLink implements SqlWrapperAddOn {
-
- @Override
- public Class> getAnnotationClass() {
- return SQLTableLinkGeneric.class;
- }
- public String getSQLFieldType(Field elem) {
- return "STRING";
- }
- public boolean isCompatibleField(Field elem) {
- SQLTableLinkGeneric decorators = elem.getDeclaredAnnotation(SQLTableLinkGeneric.class);
- return decorators != null;
- }
-}
diff --git a/src/org/kar/archidata/util/ConfigBaseVariable.java b/src/org/kar/archidata/util/ConfigBaseVariable.java
index 511c3d9..e3f1275 100644
--- a/src/org/kar/archidata/util/ConfigBaseVariable.java
+++ b/src/org/kar/archidata/util/ConfigBaseVariable.java
@@ -1,92 +1,94 @@
package org.kar.archidata.util;
public class ConfigBaseVariable {
- static public String tmpDataFolder = System.getenv("DATA_TMP_FOLDER");
- static public String dataFolder = System.getenv("DATA_FOLDER");
- static public String dbType = System.getenv("DB_TYPE");
- static public String dbHost = System.getenv("DB_HOST");
- static public String dbPort = System.getenv("DB_PORT");
- static public String dbUser = System.getenv("DB_USER");
- static public String dbKeepConnected = System.getenv("DB_KEEP_CONNECTED");
- static public String dbPassword = System.getenv("DB_PASSWORD");
- static public String bdDatabase = System.getenv("DB_DATABASE");
- static public String apiAdress = System.getenv("API_ADDRESS");
- static public String ssoAdress = System.getenv("SSO_ADDRESS");
- static public String ssoToken = System.getenv("SSO_TOKEN");
-
- public static String getTmpDataFolder() {
- if (tmpDataFolder == null) {
- return "/application/data/tmp";
- }
- return tmpDataFolder;
- }
-
- public static String getMediaDataFolder() {
- if (dataFolder == null) {
- return "/application/data/media";
- }
- return dataFolder;
- }
-
- public static String getDBType() {
- if (dbType == null) {
- return "mysql";
- }
- return dbType;
- }
-
- public static String getDBHost() {
- if (dbHost == null) {
- return "localhost";
- }
- return dbHost;
- }
-
- public static String getDBPort() {
- if (dbPort == null) {
- return "3306";
- }
- return dbPort;
- }
-
- public static String getDBLogin() {
- if (dbUser == null) {
- return "root";
- }
- return dbUser;
- }
-
- public static String getDBPassword() {
- if (dbPassword == null) {
- return "base_db_password";
- }
- return dbPassword;
- }
-
- public static String getDBName() {
- if (bdDatabase == null) {
- return "unknown";
- }
- return bdDatabase;
- }
-
- public static boolean getDBKeepConnected() {
- if (dbKeepConnected == null) {
- return false;
- }
- return Boolean.parseBoolean(dbKeepConnected);
- }
- public static String getlocalAddress() {
- if (apiAdress == null) {
- return "http://0.0.0.0:80/api/";
- }
- return apiAdress;
- }
-
- public static String getSSOAddress() {
- return ssoAdress;
- }
- public static String ssoToken() {
- return ssoToken;
- }
+ static public String tmpDataFolder = System.getenv("DATA_TMP_FOLDER");
+ static public String dataFolder = System.getenv("DATA_FOLDER");
+ static public String dbType = System.getenv("DB_TYPE");
+ static public String dbHost = System.getenv("DB_HOST");
+ static public String dbPort = System.getenv("DB_PORT");
+ static public String dbUser = System.getenv("DB_USER");
+ static public String dbKeepConnected = System.getenv("DB_KEEP_CONNECTED");
+ static public String dbPassword = System.getenv("DB_PASSWORD");
+ static public String bdDatabase = System.getenv("DB_DATABASE");
+ static public String apiAdress = System.getenv("API_ADDRESS");
+ static public String ssoAdress = System.getenv("SSO_ADDRESS");
+ static public String ssoToken = System.getenv("SSO_TOKEN");
+
+ public static String getTmpDataFolder() {
+ if (tmpDataFolder == null) {
+ return "/application/data/tmp";
+ }
+ return tmpDataFolder;
+ }
+
+ public static String getMediaDataFolder() {
+ if (dataFolder == null) {
+ return "/application/data/media";
+ }
+ return dataFolder;
+ }
+
+ public static String getDBType() {
+ if (dbType == null) {
+ return "mysql";
+ }
+ return dbType;
+ }
+
+ public static String getDBHost() {
+ if (dbHost == null) {
+ return "localhost";
+ }
+ return dbHost;
+ }
+
+ public static String getDBPort() {
+ if (dbPort == null) {
+ return "3306";
+ }
+ return dbPort;
+ }
+
+ public static String getDBLogin() {
+ if (dbUser == null) {
+ return "root";
+ }
+ return dbUser;
+ }
+
+ public static String getDBPassword() {
+ if (dbPassword == null) {
+ return "base_db_password";
+ }
+ return dbPassword;
+ }
+
+ public static String getDBName() {
+ if (bdDatabase == null) {
+ return "unknown";
+ }
+ return bdDatabase;
+ }
+
+ public static boolean getDBKeepConnected() {
+ if (dbKeepConnected == null) {
+ return false;
+ }
+ return Boolean.parseBoolean(dbKeepConnected);
+ }
+
+ public static String getlocalAddress() {
+ if (apiAdress == null) {
+ return "http://0.0.0.0:80/api/";
+ }
+ return apiAdress;
+ }
+
+ public static String getSSOAddress() {
+ return ssoAdress;
+ }
+
+ public static String ssoToken() {
+ return ssoToken;
+ }
}
diff --git a/src/org/kar/archidata/util/DataTools.java b/src/org/kar/archidata/util/DataTools.java
index 5954e4d..e7c5f37 100644
--- a/src/org/kar/archidata/util/DataTools.java
+++ b/src/org/kar/archidata/util/DataTools.java
@@ -11,283 +11,283 @@ import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
-
-import jakarta.ws.rs.core.Response;
+import java.util.List;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.kar.archidata.model.Data;
+import org.kar.archidata.sqlWrapper.QuerryAnd;
+import org.kar.archidata.sqlWrapper.QuerryCondition;
import org.kar.archidata.sqlWrapper.SqlWrapper;
+import org.kar.archidata.sqlWrapper.addOn.AddOnSQLTableExternalLink;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import jakarta.ws.rs.core.Response;
+
public class DataTools {
- static final Logger logger = LoggerFactory.getLogger(DataTools.class);
-
- public final static int CHUNK_SIZE = 1024 * 1024; // 1MB chunks
- public final static int CHUNK_SIZE_IN = 50 * 1024 * 1024; // 1MB chunks
- /**
- * Upload some data
- */
- private static long tmpFolderId = 1;
-
- public static void createFolder(String path) throws IOException {
- if (!Files.exists(java.nio.file.Path.of(path))) {
- logger.info("Create folder: " + path);
- Files.createDirectories(java.nio.file.Path.of(path));
- }
- }
-
- public static long getTmpDataId() {
- return tmpFolderId++;
- }
- public static String getTmpFileInData(long tmpFolderId) {
- String filePath = ConfigBaseVariable.getTmpDataFolder() + File.separator + tmpFolderId;
- try {
- createFolder(ConfigBaseVariable.getTmpDataFolder() + File.separator);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return filePath;
- }
-
- public static String getTmpFolder() {
- String filePath = ConfigBaseVariable.getTmpDataFolder() + File.separator + tmpFolderId++;
- try {
- createFolder(ConfigBaseVariable.getTmpDataFolder() + File.separator);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return filePath;
- }
-
- public static String getFileData(long tmpFolderId) {
- String filePath = ConfigBaseVariable.getMediaDataFolder() + File.separator + tmpFolderId + File.separator + "data";
- try {
- createFolder(ConfigBaseVariable.getMediaDataFolder() + File.separator + tmpFolderId + File.separator);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return filePath;
- }
-
- public static Data getWithSha512(String sha512) {
- try {
- return SqlWrapper.getWhere(Data.class, "sha512", "=", sha512);
+ private final static Logger LOGGER = LoggerFactory.getLogger(DataTools.class);
+
+ public final static int CHUNK_SIZE = 1024 * 1024; // 1MB chunks
+ public final static int CHUNK_SIZE_IN = 50 * 1024 * 1024; // 1MB chunks
+ /**
+ * Upload some data
+ */
+ private static long tmpFolderId = 1;
+
+ public static void createFolder(String path) throws IOException {
+ if (!Files.exists(java.nio.file.Path.of(path))) {
+ LOGGER.info("Create folder: " + path);
+ Files.createDirectories(java.nio.file.Path.of(path));
+ }
+ }
+
+ public static long getTmpDataId() {
+ return tmpFolderId++;
+ }
+
+ public static String getTmpFileInData(long tmpFolderId) {
+ String filePath = ConfigBaseVariable.getTmpDataFolder() + File.separator + tmpFolderId;
+ try {
+ createFolder(ConfigBaseVariable.getTmpDataFolder() + File.separator);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return filePath;
+ }
+
+ public static String getTmpFolder() {
+ String filePath = ConfigBaseVariable.getTmpDataFolder() + File.separator + tmpFolderId++;
+ try {
+ createFolder(ConfigBaseVariable.getTmpDataFolder() + File.separator);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return filePath;
+ }
+
+ public static String getFileData(long tmpFolderId) {
+ String filePath = ConfigBaseVariable.getMediaDataFolder() + File.separator + tmpFolderId + File.separator + "data";
+ try {
+ createFolder(ConfigBaseVariable.getMediaDataFolder() + File.separator + tmpFolderId + File.separator);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return filePath;
+ }
+
+ public static Data getWithSha512(String sha512) {
+ try {
+ return SqlWrapper.getWhere(Data.class, new QuerryCondition("sha512", "=", sha512));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
- return null;
- }
-
- public static Data getWithId(long id) {
- try {
- return SqlWrapper.getWhere(Data.class, "deleted", "=", false, "id", "=", id);
+ return null;
+ }
+
+ public static Data getWithId(long id) {
+ try {
+ return SqlWrapper.getWhere(Data.class, new QuerryAnd(List.of(new QuerryCondition("deleted", "=", false), new QuerryCondition("id", "=", id))));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
- return null;
- }
-
- public static Data createNewData(long tmpUID, String originalFileName, String sha512) throws IOException, SQLException {
- // determine mime type:
- String mimeType = "";
- String extension = originalFileName.substring(originalFileName.lastIndexOf('.') + 1);
- switch (extension.toLowerCase()) {
- case "jpg":
- case "jpeg":
- mimeType = "image/jpeg";
- break;
- case "png":
- mimeType = "image/png";
- break;
- case "webp":
- mimeType = "image/webp";
- break;
- case "mka":
- mimeType = "audio/x-matroska";
- break;
- case "mkv":
- mimeType = "video/x-matroska";
- break;
- case "webm":
- mimeType = "video/webm";
- break;
- default:
- throw new IOException("Can not find the mime type of data input: '" + extension + "'");
- }
- String tmpPath = getTmpFileInData(tmpUID);
- long fileSize = Files.size(Paths.get(tmpPath));
- Data out = new Data();;
- try {
- out.sha512 = sha512;
- out.mimeType = mimeType;
- out.size = fileSize;
- out = SqlWrapper.insert(out);
- } catch (SQLException ex) {
- ex.printStackTrace();
- return null;
- } catch (Exception e) {
+ return null;
+ }
+
+ public static Data createNewData(long tmpUID, String originalFileName, String sha512) throws IOException, SQLException {
+ // determine mime type:
+ String mimeType = "";
+ String extension = originalFileName.substring(originalFileName.lastIndexOf('.') + 1);
+ switch (extension.toLowerCase()) {
+ case "jpg":
+ case "jpeg":
+ mimeType = "image/jpeg";
+ break;
+ case "png":
+ mimeType = "image/png";
+ break;
+ case "webp":
+ mimeType = "image/webp";
+ break;
+ case "mka":
+ mimeType = "audio/x-matroska";
+ break;
+ case "mkv":
+ mimeType = "video/x-matroska";
+ break;
+ case "webm":
+ mimeType = "video/webm";
+ break;
+ default:
+ throw new IOException("Can not find the mime type of data input: '" + extension + "'");
+ }
+ String tmpPath = getTmpFileInData(tmpUID);
+ long fileSize = Files.size(Paths.get(tmpPath));
+ Data out = new Data();
+ ;
+ try {
+ out.sha512 = sha512;
+ out.mimeType = mimeType;
+ out.size = fileSize;
+ out = SqlWrapper.insert(out);
+ } catch (SQLException ex) {
+ ex.printStackTrace();
+ return null;
+ } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
- return null;
+ return null;
}
-
- String mediaPath = getFileData(out.id);
- logger.info("src = {}", tmpPath);
- logger.info("dst = {}", mediaPath);
- Files.move(Paths.get(tmpPath), Paths.get(mediaPath), StandardCopyOption.ATOMIC_MOVE);
-
- logger.info("Move done");
- // all is done the file is correctly installed...
- return out;
- }
-
- public static void undelete(Long id) {
+
+ String mediaPath = getFileData(out.id);
+ LOGGER.info("src = {}", tmpPath);
+ LOGGER.info("dst = {}", mediaPath);
+ Files.move(Paths.get(tmpPath), Paths.get(mediaPath), StandardCopyOption.ATOMIC_MOVE);
+
+ LOGGER.info("Move done");
+ // all is done the file is correctly installed...
+ return out;
+ }
+
+ public static void undelete(Long id) {
try {
SqlWrapper.unsetDelete(Data.class, id);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
- }
-
- public static String saveTemporaryFile(InputStream uploadedInputStream, long idData) {
- return saveFile(uploadedInputStream, getTmpFileInData(idData));
- }
-
- public static void removeTemporaryFile(long idData) {
- String filepath = getTmpFileInData(idData);
- if (Files.exists(Paths.get(filepath))) {
- try {
- Files.delete(Paths.get(filepath));
- } catch (IOException e) {
- logger.info("can not delete temporary file : {}", Paths.get(filepath));
- e.printStackTrace();
- }
- }
- }
-
- // save uploaded file to a defined location on the server
- public static String saveFile(InputStream uploadedInputStream, String serverLocation) {
- String out = "";
- try {
- OutputStream outpuStream = new FileOutputStream(new File(
- serverLocation));
- int read = 0;
- byte[] bytes = new byte[CHUNK_SIZE_IN];
- MessageDigest md = MessageDigest.getInstance("SHA-512");
-
- outpuStream = new FileOutputStream(new File(serverLocation));
- while ((read = uploadedInputStream.read(bytes)) != -1) {
- //logger.debug("write {}", read);
- md.update(bytes, 0, read);
- outpuStream.write(bytes, 0, read);
- }
- logger.info("Flush input stream ... {}", serverLocation);
- outpuStream.flush();
- outpuStream.close();
- // create the end of sha512
- byte[] sha512Digest = md.digest();
- // convert in hexadecimal
- out = bytesToHex(sha512Digest);
- uploadedInputStream.close();
- } catch (IOException ex) {
- logger.error("Can not write in temporary file ... ");
- ex.printStackTrace();
- } catch (NoSuchAlgorithmException ex) {
- logger.error("Can not find sha512 algorithms");
- ex.printStackTrace();
- }
- return out;
- }
-
- // curl http://localhost:9993/api/users/3
- //@Secured
- /*
- @GET
- @Path("{id}")
- //@RolesAllowed("GUEST")
- @Produces(MediaType.APPLICATION_OCTET_STREAM)
- public Response retriveData(@HeaderParam("Range") String range, @PathParam("id") Long id) throws Exception {
- return retriveDataFull(range, id, "no-name");
- }
- */
-
- public static String bytesToHex(byte[] bytes) {
- StringBuilder sb = new StringBuilder();
- for (byte b : bytes) {
- sb.append(String.format("%02x", b));
- }
- return sb.toString();
- }
-
+ }
+
+ public static String saveTemporaryFile(InputStream uploadedInputStream, long idData) {
+ return saveFile(uploadedInputStream, getTmpFileInData(idData));
+ }
+
+ public static void removeTemporaryFile(long idData) {
+ String filepath = getTmpFileInData(idData);
+ if (Files.exists(Paths.get(filepath))) {
+ try {
+ Files.delete(Paths.get(filepath));
+ } catch (IOException e) {
+ LOGGER.info("can not delete temporary file : {}", Paths.get(filepath));
+ e.printStackTrace();
+ }
+ }
+ }
+
+ // save uploaded file to a defined location on the server
+ public static String saveFile(InputStream uploadedInputStream, String serverLocation) {
+ String out = "";
+ try {
+ OutputStream outpuStream = new FileOutputStream(new File(serverLocation));
+ int read = 0;
+ byte[] bytes = new byte[CHUNK_SIZE_IN];
+ MessageDigest md = MessageDigest.getInstance("SHA-512");
+
+ outpuStream = new FileOutputStream(new File(serverLocation));
+ while ((read = uploadedInputStream.read(bytes)) != -1) {
+ //logger.debug("write {}", read);
+ md.update(bytes, 0, read);
+ outpuStream.write(bytes, 0, read);
+ }
+ LOGGER.info("Flush input stream ... {}", serverLocation);
+ outpuStream.flush();
+ outpuStream.close();
+ // create the end of sha512
+ byte[] sha512Digest = md.digest();
+ // convert in hexadecimal
+ out = bytesToHex(sha512Digest);
+ uploadedInputStream.close();
+ } catch (IOException ex) {
+ LOGGER.error("Can not write in temporary file ... ");
+ ex.printStackTrace();
+ } catch (NoSuchAlgorithmException ex) {
+ LOGGER.error("Can not find sha512 algorithms");
+ ex.printStackTrace();
+ }
+ return out;
+ }
+
+ // curl http://localhost:9993/api/users/3
+ //@Secured
+ /*
+ @GET
+ @Path("{id}")
+ //@RolesAllowed("GUEST")
+ @Produces(MediaType.APPLICATION_OCTET_STREAM)
+ public Response retriveData(@HeaderParam("Range") String range, @PathParam("id") Long id) throws Exception {
+ return retriveDataFull(range, id, "no-name");
+ }
+ */
+
+ public static String bytesToHex(byte[] bytes) {
+ StringBuilder sb = new StringBuilder();
+ for (byte b : bytes) {
+ sb.append(String.format("%02x", b));
+ }
+ return sb.toString();
+ }
+
public static String multipartCorrection(String data) {
- if (data == null) {
- return null;
- }
- if (data.isEmpty()) {
- return null;
- }
- if (data.contentEquals("null")) {
- return null;
- }
- return data;
- }
-
- public static Response uploadCover(Class clazz,
- Long id,
- String fileName,
- InputStream fileInputStream,
- FormDataContentDisposition fileMetaData
- ) {
- try {
- // correct input string stream :
- fileName = multipartCorrection(fileName);
-
- //public NodeSmall uploadFile(final FormDataMultiPart form) {
- logger.info("Upload media file: {}", fileMetaData);
- logger.info(" - id: {}", id);
- logger.info(" - file_name: ", fileName);
- logger.info(" - fileInputStream: {}", fileInputStream);
- logger.info(" - fileMetaData: {}", fileMetaData);
- T media = SqlWrapper.get(clazz, id);
- if (media == null) {
- return Response.notModified("Media Id does not exist or removed...").build();
- }
-
- long tmpUID = getTmpDataId();
- String sha512 = saveTemporaryFile(fileInputStream, tmpUID);
- Data data = getWithSha512(sha512);
- if (data == null) {
- logger.info("Need to add the data in the BDD ... ");
- try {
- data = createNewData(tmpUID, fileName, sha512);
- } catch (IOException ex) {
- removeTemporaryFile(tmpUID);
- ex.printStackTrace();
- return Response.notModified("can not create input media").build();
- } catch (SQLException ex) {
- ex.printStackTrace();
- removeTemporaryFile(tmpUID);
- return Response.notModified("Error in SQL insertion ...").build();
- }
- } else if (data.deleted == true) {
- logger.error("Data already exist but deleted");
- undelete(data.id);
- data.deleted = false;
- } else {
- logger.error("Data already exist ... all good");
- }
- // Fist step: retrieve all the Id of each parents:...
- logger.info("Find typeNode");
- SqlWrapper.addLink(clazz, id, "cover", data.id);
- return Response.ok(SqlWrapper.get(clazz, id)).build();
- } catch (Exception ex) {
- System.out.println("Cat ann unexpected error ... ");
- ex.printStackTrace();
- }
- return Response.serverError().build();
- }
+ if (data == null) {
+ return null;
+ }
+ if (data.isEmpty()) {
+ return null;
+ }
+ if (data.contentEquals("null")) {
+ return null;
+ }
+ return data;
+ }
+
+ public static Response uploadCover(Class clazz, Long id, String fileName, InputStream fileInputStream, FormDataContentDisposition fileMetaData) {
+ try {
+ // correct input string stream :
+ fileName = multipartCorrection(fileName);
+
+ //public NodeSmall uploadFile(final FormDataMultiPart form) {
+ LOGGER.info("Upload media file: {}", fileMetaData);
+ LOGGER.info(" - id: {}", id);
+ LOGGER.info(" - file_name: ", fileName);
+ LOGGER.info(" - fileInputStream: {}", fileInputStream);
+ LOGGER.info(" - fileMetaData: {}", fileMetaData);
+ T media = SqlWrapper.get(clazz, id);
+ if (media == null) {
+ return Response.notModified("Media Id does not exist or removed...").build();
+ }
+
+ long tmpUID = getTmpDataId();
+ String sha512 = saveTemporaryFile(fileInputStream, tmpUID);
+ Data data = getWithSha512(sha512);
+ if (data == null) {
+ LOGGER.info("Need to add the data in the BDD ... ");
+ try {
+ data = createNewData(tmpUID, fileName, sha512);
+ } catch (IOException ex) {
+ removeTemporaryFile(tmpUID);
+ ex.printStackTrace();
+ return Response.notModified("can not create input media").build();
+ } catch (SQLException ex) {
+ ex.printStackTrace();
+ removeTemporaryFile(tmpUID);
+ return Response.notModified("Error in SQL insertion ...").build();
+ }
+ } else if (data.deleted == true) {
+ LOGGER.error("Data already exist but deleted");
+ undelete(data.id);
+ data.deleted = false;
+ } else {
+ LOGGER.error("Data already exist ... all good");
+ }
+ // Fist step: retrieve all the Id of each parents:...
+ LOGGER.info("Find typeNode");
+ AddOnSQLTableExternalLink.addLink(clazz, id, "cover", data.id);
+ return Response.ok(SqlWrapper.get(clazz, id)).build();
+ } catch (Exception ex) {
+ System.out.println("Cat ann unexpected error ... ");
+ ex.printStackTrace();
+ }
+ return Response.serverError().build();
+ }
}
diff --git a/src/org/kar/archidata/util/JWTWrapper.java b/src/org/kar/archidata/util/JWTWrapper.java
index 26addbd..29c12f6 100644
--- a/src/org/kar/archidata/util/JWTWrapper.java
+++ b/src/org/kar/archidata/util/JWTWrapper.java
@@ -32,53 +32,54 @@ public class JWTWrapper {
private static RSAKey rsaJWK = null;;
private static RSAKey rsaPublicJWK = null;
-
+
public static class PublicKey {
public String key;
-
+
public PublicKey(String key) {
this.key = key;
}
- public PublicKey() {
- }
+
+ public PublicKey() {}
}
- public static void initLocalTokenRemote(String ssoUri, String application) throws IOException, ParseException {
- // check Token:
- URL obj = new URL(ssoUri + "public_key");
- //logger.debug("Request token from: {}", obj);
- HttpURLConnection con = (HttpURLConnection) obj.openConnection();
- con.setRequestMethod("GET");
- con.setRequestProperty("User-Agent", application);
- con.setRequestProperty("Cache-Control", "no-cache");
- con.setRequestProperty("Content-Type", "application/json");
- con.setRequestProperty("Accept", "application/json");
- String ssoToken = ConfigBaseVariable.ssoToken();
- if (ssoToken != null) {
- con.setRequestProperty("Authorization", "Zota " + ssoToken);
- }
- int responseCode = con.getResponseCode();
-
- //logger.debug("GET Response Code :: {}", responseCode);
- if (responseCode == HttpURLConnection.HTTP_OK) { // success
- BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
-
- String inputLine;
- StringBuffer response = new StringBuffer();
- while ((inputLine = in.readLine()) != null) {
- response.append(inputLine);
- }
- in.close();
- // print result
- //logger.debug(response.toString());
- ObjectMapper mapper = new ObjectMapper();
- PublicKey values = mapper.readValue(response.toString(), PublicKey.class);
- rsaPublicJWK = RSAKey.parse(values.key);
- return;
- }
- logger.debug("GET JWT validator token not worked response code {} from {} ", responseCode, obj);
- }
-
- public static void initLocalToken(String baseUUID) throws Exception{
+
+ public static void initLocalTokenRemote(String ssoUri, String application) throws IOException, ParseException {
+ // check Token:
+ URL obj = new URL(ssoUri + "public_key");
+ //logger.debug("Request token from: {}", obj);
+ HttpURLConnection con = (HttpURLConnection) obj.openConnection();
+ con.setRequestMethod("GET");
+ con.setRequestProperty("User-Agent", application);
+ con.setRequestProperty("Cache-Control", "no-cache");
+ con.setRequestProperty("Content-Type", "application/json");
+ con.setRequestProperty("Accept", "application/json");
+ String ssoToken = ConfigBaseVariable.ssoToken();
+ if (ssoToken != null) {
+ con.setRequestProperty("Authorization", "Zota " + ssoToken);
+ }
+ int responseCode = con.getResponseCode();
+
+ //logger.debug("GET Response Code :: {}", responseCode);
+ if (responseCode == HttpURLConnection.HTTP_OK) { // success
+ BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
+
+ String inputLine;
+ StringBuffer response = new StringBuffer();
+ while ((inputLine = in.readLine()) != null) {
+ response.append(inputLine);
+ }
+ in.close();
+ // print result
+ //logger.debug(response.toString());
+ ObjectMapper mapper = new ObjectMapper();
+ PublicKey values = mapper.readValue(response.toString(), PublicKey.class);
+ rsaPublicJWK = RSAKey.parse(values.key);
+ return;
+ }
+ logger.debug("GET JWT validator token not worked response code {} from {} ", responseCode, obj);
+ }
+
+ public static void initLocalToken(String baseUUID) throws Exception {
// RSA signatures require a public and private RSA key pair, the public key
// must be made known to the JWS recipient in order to verify the signatures
try {
@@ -111,12 +112,14 @@ public class JWTWrapper {
}
}
+
public static String getPublicKeyJson() {
if (rsaPublicJWK == null) {
return null;
}
return rsaPublicJWK.toJSONString();
}
+
public static java.security.interfaces.RSAPublicKey getPublicKeyJava() throws JOSEException {
if (rsaPublicJWK == null) {
return null;
@@ -146,21 +149,16 @@ public class JWTWrapper {
*/
try {
// Create RSA-signer with the private key
- JWSSigner signer = new RSASSASigner(rsaJWK);
-
- logger.warn("timeOutInMunites= {}", timeOutInMunites);
- Date now = new Date();
- logger.warn("now = {}", now);
- Date expiration = new Date(new Date().getTime() - 60 * timeOutInMunites * 1000 /* millisecond */);
-
- logger.warn("expiration= {}", expiration);
- JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder()
- .subject(Long.toString(userID))
- .claim("login", userLogin)
- .claim("application", application)
- .issuer(isuer)
- .issueTime(now)
- .expirationTime(expiration); // Do not ask why we need a "-" here ... this have no meaning
+ JWSSigner signer = new RSASSASigner(rsaJWK);
+
+ logger.warn("timeOutInMunites= {}", timeOutInMunites);
+ Date now = new Date();
+ logger.warn("now = {}", now);
+ Date expiration = new Date(new Date().getTime() - 60 * timeOutInMunites * 1000 /* millisecond */);
+
+ logger.warn("expiration= {}", expiration);
+ JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder().subject(Long.toString(userID)).claim("login", userLogin).claim("application", application).issuer(isuer).issueTime(now)
+ .expirationTime(expiration); // Do not ask why we need a "-" here ... this have no meaning
// add right if needed:
if (rights != null && !rights.isEmpty()) {
builder.claim("right", rights);
@@ -168,7 +166,7 @@ public class JWTWrapper {
// Prepare JWT with claims set
JWTClaimsSet claimsSet = builder.build();
SignedJWT signedJWT = new SignedJWT(new JWSHeader.Builder(JWSAlgorithm.RS256).type(JOSEObjectType.JWT)/*.keyID(rsaJWK.getKeyID())*/.build(), claimsSet);
-
+
// Compute the RSA signature
signedJWT.sign(signer);
// serialize the output...
@@ -178,7 +176,7 @@ public class JWTWrapper {
}
return null;
}
-
+
public static JWTClaimsSet validateToken(String signedToken, String isuer, String application) {
if (rsaPublicJWK == null) {
logger.warn("JWT public key is not present !!!");
@@ -187,18 +185,18 @@ public class JWTWrapper {
try {
// On the consumer side, parse the JWS and verify its RSA signature
SignedJWT signedJWT = SignedJWT.parse(signedToken);
-
+
JWSVerifier verifier = new RSASSAVerifier(rsaPublicJWK);
if (!signedJWT.verify(verifier)) {
logger.error("JWT token is NOT verified ");
return null;
}
if (!new Date().before(signedJWT.getJWTClaimsSet().getExpirationTime())) {
- logger.error("JWT token is expired now = " + new Date() + " with=" + signedJWT.getJWTClaimsSet().getExpirationTime() );
+ logger.error("JWT token is expired now = " + new Date() + " with=" + signedJWT.getJWTClaimsSet().getExpirationTime());
return null;
}
if (!isuer.equals(signedJWT.getJWTClaimsSet().getIssuer())) {
- logger.error("JWT issuer is wong: '" + isuer + "' != '" + signedJWT.getJWTClaimsSet().getIssuer() + "'" );
+ logger.error("JWT issuer is wong: '" + isuer + "' != '" + signedJWT.getJWTClaimsSet().getIssuer() + "'");
return null;
}
if (application != null) {
diff --git a/src/org/kar/archidata/util/PublicKey.java b/src/org/kar/archidata/util/PublicKey.java
index f6968be..440d3eb 100644
--- a/src/org/kar/archidata/util/PublicKey.java
+++ b/src/org/kar/archidata/util/PublicKey.java
@@ -1,9 +1,8 @@
package org.kar.archidata.util;
-
public class PublicKey {
public String key;
-
+
public PublicKey(String key) {
this.key = key;
}
diff --git a/src/org/kar/archidata/util/RESTApi.java b/src/org/kar/archidata/util/RESTApi.java
index 93f15d8..f826fa5 100644
--- a/src/org/kar/archidata/util/RESTApi.java
+++ b/src/org/kar/archidata/util/RESTApi.java
@@ -31,6 +31,7 @@ public class RESTApi {
public void setToken(String token) {
this.token = token;
}
+
public List gets(Class clazz, String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient();
@@ -44,9 +45,10 @@ public class RESTApi {
RESTErrorResponseExeption out = mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
throw out;
}
- List out = mapper.readValue(httpResponse.body(), new TypeReference>(){});
+ List out = mapper.readValue(httpResponse.body(), new TypeReference>() {});
return out;
}
+
public T get(Class clazz, String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient();
@@ -59,20 +61,21 @@ public class RESTApi {
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
//LOGGER.error("catch error from REST API: {}", httpResponse.body());
RESTErrorResponseExeption out = mapper.readValue(httpResponse.body(), RESTErrorResponseExeption.class);
- throw new RESTErrorResponseExeption(out.uuid, out.time, out.error, out.message, out.status,out.statusMessage);
+ throw new RESTErrorResponseExeption(out.uuid, out.time, out.error, out.message, out.status, out.statusMessage);
}
//LOGGER.error("status code: {}", httpResponse.statusCode());
//LOGGER.error("data: {}", httpResponse.body());
if (clazz.equals(String.class)) {
- return (T)httpResponse.body();
+ return (T) httpResponse.body();
}
T out = mapper.readValue(httpResponse.body(), clazz);
return out;
}
+
public T post(Class clazz, String urlOffset, U data) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient();
- String body = mapper.writeValueAsString(data);
+ String body = mapper.writeValueAsString(data);
Builder requestBuilding = HttpRequest.newBuilder().uri(URI.create(this.baseUrl + urlOffset));
if (token != null) {
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Yota " + token);
@@ -87,15 +90,16 @@ public class RESTApi {
throw out;
}
if (clazz.equals(String.class)) {
- return (T)httpResponse.body();
+ return (T) httpResponse.body();
}
T out = mapper.readValue(httpResponse.body(), clazz);
return out;
}
+
public T postMap(Class clazz, String urlOffset, Map data) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient();
- String body = mapper.writeValueAsString(data);
+ String body = mapper.writeValueAsString(data);
Builder requestBuilding = HttpRequest.newBuilder().uri(URI.create(this.baseUrl + urlOffset));
if (token != null) {
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Yota " + token);
@@ -108,15 +112,16 @@ public class RESTApi {
throw out;
}
if (clazz.equals(String.class)) {
- return (T)httpResponse.body();
+ return (T) httpResponse.body();
}
T out = mapper.readValue(httpResponse.body(), clazz);
return out;
}
+
public T put(Class clazz, String urlOffset, U data) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient();
- String body = mapper.writeValueAsString(data);
+ String body = mapper.writeValueAsString(data);
Builder requestBuilding = HttpRequest.newBuilder().uri(URI.create(this.baseUrl + urlOffset));
if (token != null) {
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Yota " + token);
@@ -129,15 +134,16 @@ public class RESTApi {
throw out;
}
if (clazz.equals(String.class)) {
- return (T)httpResponse.body();
+ return (T) httpResponse.body();
}
T out = mapper.readValue(httpResponse.body(), clazz);
return out;
}
+
public T putMap(Class clazz, String urlOffset, Map data) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient();
- String body = mapper.writeValueAsString(data);
+ String body = mapper.writeValueAsString(data);
Builder requestBuilding = HttpRequest.newBuilder().uri(URI.create(this.baseUrl + urlOffset));
if (token != null) {
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Yota " + token);
@@ -150,11 +156,12 @@ public class RESTApi {
throw out;
}
if (clazz.equals(String.class)) {
- return (T)httpResponse.body();
+ return (T) httpResponse.body();
}
T out = mapper.readValue(httpResponse.body(), clazz);
return out;
}
+
public T delete(Class clazz, String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException {
ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient();
@@ -169,7 +176,7 @@ public class RESTApi {
throw out;
}
if (clazz.equals(String.class)) {
- return (T)httpResponse.body();
+ return (T) httpResponse.body();
}
T out = mapper.readValue(httpResponse.body(), clazz);
return out;
diff --git a/test/src/test/kar/archidata/TestBase.java b/test/src/test/kar/archidata/TestBase.java
new file mode 100644
index 0000000..0e03170
--- /dev/null
+++ b/test/src/test/kar/archidata/TestBase.java
@@ -0,0 +1,44 @@
+package test.kar.archidata;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.kar.archidata.sqlWrapper.SqlWrapper;
+import org.kar.archidata.util.RESTApi;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+public class TestBase {
+ final static Logger logger = LoggerFactory.getLogger(TestBase.class);
+
+ static RESTApi api = null;
+
+ @BeforeAll
+ public static void configureWebServer() throws Exception {
+ logger.info("Create DB");
+ final String dbName = "sdfsdfsdfsfsdfsfsfsfsdfsdfsd";
+ boolean data = SqlWrapper.isDBExist(dbName);
+ logger.error("exist: {}", data);
+ data = SqlWrapper.createDB(dbName);
+ logger.error("create: {}", data);
+ data = SqlWrapper.isDBExist(dbName);
+ logger.error("exist: {}", data);
+ }
+
+ @AfterAll
+ public static void stopWebServer() throws InterruptedException {
+ logger.info("Kill the web server");
+ // TODO: do it better...
+ }
+
+ @Order(1)
+ @Test
+ public void checkSimpleTestError() throws Exception {
+ Assertions.assertEquals("lkjlkjlkjlk", "alive and kicking");
+ }
+}