Compare commits
11 Commits
9cbeee66c9
...
c9b9d38efe
Author | SHA1 | Date | |
---|---|---|---|
c9b9d38efe | |||
cd3a6a1d8b | |||
|
5c1b7cd193 | ||
|
9ed09d4fed | ||
|
33665d47b8 | ||
|
b907d2212a | ||
a0f4680271 | |||
d9e118afaa | |||
9f43ebc782 | |||
8b831522dc | |||
4f5d55bb01 |
2
pom.xml
2
pom.xml
@ -3,7 +3,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>kangaroo-and-rabbit</groupId>
|
<groupId>kangaroo-and-rabbit</groupId>
|
||||||
<artifactId>archidata</artifactId>
|
<artifactId>archidata</artifactId>
|
||||||
<version>0.14.2</version>
|
<version>0.16.0</version>
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>21</java.version>
|
<java.version>21</java.version>
|
||||||
<maven.compiler.version>3.1</maven.compiler.version>
|
<maven.compiler.version>3.1</maven.compiler.version>
|
||||||
|
19
src/org/kar/archidata/annotation/ARCHIVE.java
Normal file
19
src/org/kar/archidata/annotation/ARCHIVE.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
import jakarta.ws.rs.HttpMethod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the annotated method responds to HTTP ARCHIVE requests.
|
||||||
|
*
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @see HttpMethod
|
||||||
|
*/
|
||||||
|
@Target({ ElementType.METHOD })
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@HttpMethod("ARCHIVE")
|
||||||
|
public @interface ARCHIVE {}
|
19
src/org/kar/archidata/annotation/RESTORE.java
Normal file
19
src/org/kar/archidata/annotation/RESTORE.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
import jakarta.ws.rs.HttpMethod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the annotated method responds to HTTP RESTORE requests.
|
||||||
|
*
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @see HttpMethod
|
||||||
|
*/
|
||||||
|
@Target({ ElementType.METHOD })
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@HttpMethod("RESTORE")
|
||||||
|
public @interface RESTORE {}
|
@ -304,9 +304,11 @@ public class DataResource {
|
|||||||
// logger.info("===================================================");
|
// logger.info("===================================================");
|
||||||
final Data value = getSmall(uuid);
|
final Data value = getSmall(uuid);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
|
LOGGER.warn("Request data that does not exist : {}", uuid);
|
||||||
return Response.status(404).entity("media NOT FOUND: " + uuid).type("text/plain").build();
|
return Response.status(404).entity("media NOT FOUND: " + uuid).type("text/plain").build();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
LOGGER.warn("Generate stream : {}", uuid);
|
||||||
return buildStream(getFileData(uuid), range,
|
return buildStream(getFileData(uuid), range,
|
||||||
value.mimeType == null ? "application/octet-stream" : value.mimeType);
|
value.mimeType == null ? "application/octet-stream" : value.mimeType);
|
||||||
} catch (final Exception ex) {
|
} catch (final Exception ex) {
|
||||||
@ -478,8 +480,9 @@ public class DataResource {
|
|||||||
to = file.length() - 1;
|
to = file.length() - 1;
|
||||||
}
|
}
|
||||||
final String responseRange = String.format("bytes %d-%d/%d", from, to, file.length());
|
final String responseRange = String.format("bytes %d-%d/%d", from, to, file.length());
|
||||||
// logger.info("responseRange: {}", responseRange);
|
// LOGGER.info("responseRange: {}", responseRange);
|
||||||
try (final RandomAccessFile raf = new RandomAccessFile(file, "r")) {
|
try {
|
||||||
|
final RandomAccessFile raf = new RandomAccessFile(file, "r");
|
||||||
raf.seek(from);
|
raf.seek(from);
|
||||||
|
|
||||||
final long len = to - from + 1;
|
final long len = to - from + 1;
|
||||||
|
@ -58,5 +58,4 @@ public class MediaStreamer implements StreamingOutput {
|
|||||||
public long getLenth() {
|
public long getLenth() {
|
||||||
return this.length;
|
return this.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ public class WebApplicationExceptionCatcher implements ExceptionMapper<WebApplic
|
|||||||
}
|
}
|
||||||
|
|
||||||
private RestErrorResponse build(final WebApplicationException exception) {
|
private RestErrorResponse build(final WebApplicationException exception) {
|
||||||
|
exception.printStackTrace();
|
||||||
return new RestErrorResponse(exception.getResponse().getStatusInfo().toEnum(), "Catch system exception",
|
return new RestErrorResponse(exception.getResponse().getStatusInfo().toEnum(), "Catch system exception",
|
||||||
exception.getMessage());
|
exception.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,8 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
final String tmpVariable = "tmp_" + Integer.toString(count.value);
|
final String tmpVariable = "tmp_" + Integer.toString(count.value);
|
||||||
querySelect.append(" (SELECT GROUP_CONCAT(");
|
querySelect.append(" (SELECT GROUP_CONCAT(");
|
||||||
querySelect.append(tmpVariable);
|
querySelect.append(tmpVariable);
|
||||||
if (manyToMany.mappedBy() == null || manyToMany.mappedBy().length() == 0) {
|
final boolean mode = manyToMany.mappedBy() == null || manyToMany.mappedBy().length() == 0;
|
||||||
|
if (mode) {
|
||||||
querySelect.append(".object2Id ");
|
querySelect.append(".object2Id ");
|
||||||
} else {
|
} else {
|
||||||
querySelect.append(".object1Id ");
|
querySelect.append(".object1Id ");
|
||||||
@ -128,6 +129,7 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
if ("sqlite".equals(ConfigBaseVariable.getDBType())) {
|
if ("sqlite".equals(ConfigBaseVariable.getDBType())) {
|
||||||
querySelect.append(", ");
|
querySelect.append(", ");
|
||||||
} else {
|
} else {
|
||||||
|
querySelect.append("ORDER BY uuid ASC ");
|
||||||
querySelect.append("SEPARATOR ");
|
querySelect.append("SEPARATOR ");
|
||||||
}
|
}
|
||||||
querySelect.append("'");
|
querySelect.append("'");
|
||||||
@ -153,7 +155,7 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
querySelect.append(" = ");
|
querySelect.append(" = ");
|
||||||
querySelect.append(tmpVariable);
|
querySelect.append(tmpVariable);
|
||||||
querySelect.append(".");
|
querySelect.append(".");
|
||||||
if (manyToMany.mappedBy() == null || manyToMany.mappedBy().length() == 0) {
|
if (mode) {
|
||||||
querySelect.append("object1Id ");
|
querySelect.append("object1Id ");
|
||||||
} else {
|
} else {
|
||||||
querySelect.append("object2Id ");
|
querySelect.append("object2Id ");
|
||||||
@ -161,7 +163,7 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
if (!"sqlite".equals(ConfigBaseVariable.getDBType())) {
|
if (!"sqlite".equals(ConfigBaseVariable.getDBType())) {
|
||||||
querySelect.append(" GROUP BY ");
|
querySelect.append(" GROUP BY ");
|
||||||
querySelect.append(tmpVariable);
|
querySelect.append(tmpVariable);
|
||||||
if (manyToMany.mappedBy() == null || manyToMany.mappedBy().length() == 0) {
|
if (mode) {
|
||||||
querySelect.append(".object1Id");
|
querySelect.append(".object1Id");
|
||||||
} else {
|
} else {
|
||||||
querySelect.append(".object2Id");
|
querySelect.append(".object2Id");
|
||||||
|
@ -7,8 +7,10 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
|
import org.kar.archidata.annotation.ARCHIVE;
|
||||||
import org.kar.archidata.annotation.AsyncType;
|
import org.kar.archidata.annotation.AsyncType;
|
||||||
import org.kar.archidata.annotation.FormDataOptional;
|
import org.kar.archidata.annotation.FormDataOptional;
|
||||||
|
import org.kar.archidata.annotation.RESTORE;
|
||||||
import org.kar.archidata.annotation.TypeScriptProgress;
|
import org.kar.archidata.annotation.TypeScriptProgress;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@ -107,6 +109,12 @@ public class ApiTool {
|
|||||||
if (element.getDeclaredAnnotationsByType(DELETE.class).length == 1) {
|
if (element.getDeclaredAnnotationsByType(DELETE.class).length == 1) {
|
||||||
return "DELETE";
|
return "DELETE";
|
||||||
}
|
}
|
||||||
|
if (element.getDeclaredAnnotationsByType(RESTORE.class).length == 1) {
|
||||||
|
return "RESTORE";
|
||||||
|
}
|
||||||
|
if (element.getDeclaredAnnotationsByType(ARCHIVE.class).length == 1) {
|
||||||
|
return "ARCHIVE";
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,6 +134,12 @@ public class ApiTool {
|
|||||||
if (element.getDeclaredAnnotationsByType(DELETE.class).length == 1) {
|
if (element.getDeclaredAnnotationsByType(DELETE.class).length == 1) {
|
||||||
return RestTypeRequest.DELETE;
|
return RestTypeRequest.DELETE;
|
||||||
}
|
}
|
||||||
|
if (element.getDeclaredAnnotationsByType(RESTORE.class).length == 1) {
|
||||||
|
return RestTypeRequest.RESTORE;
|
||||||
|
}
|
||||||
|
if (element.getDeclaredAnnotationsByType(ARCHIVE.class).length == 1) {
|
||||||
|
return RestTypeRequest.ARCHIVE;
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
package org.kar.archidata.externalRestApi.model;
|
package org.kar.archidata.externalRestApi.model;
|
||||||
|
|
||||||
public enum RestTypeRequest {
|
public enum RestTypeRequest {
|
||||||
GET, POST, PUT, PATCH, DELETE
|
GET, POST, PUT, PATCH, DELETE, RESTORE, ARCHIVE
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,12 @@ public class CORSFilter implements ContainerResponseFilter {
|
|||||||
// System.err.println("filter cors ..." + request.toString());
|
// System.err.println("filter cors ..." + request.toString());
|
||||||
|
|
||||||
response.getHeaders().add("Access-Control-Allow-Origin", "*");
|
response.getHeaders().add("Access-Control-Allow-Origin", "*");
|
||||||
|
response.getHeaders().add("Access-Control-Allow-Range", "bytes");
|
||||||
|
response.getHeaders().add("access-control-expose-headers", "range");
|
||||||
response.getHeaders().add("Access-Control-Allow-Headers",
|
response.getHeaders().add("Access-Control-Allow-Headers",
|
||||||
"Origin, content-type, Content-type, Accept, Authorization, mime-type, filename");
|
"Origin, content-type, Content-type, Accept, Authorization, mime-type, filename, Range");
|
||||||
response.getHeaders().add("Access-Control-Allow-Credentials", "true");
|
response.getHeaders().add("Access-Control-Allow-Credentials", "true");
|
||||||
response.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD");
|
response.getHeaders().add("Access-Control-Allow-Methods",
|
||||||
|
"GET, POST, PUT, PATCH, DELETE, ARCHIVE, RESTORE, OPTIONS, HEAD");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,6 +259,9 @@ public class DataTools {
|
|||||||
if (data.contentEquals("null")) {
|
if (data.contentEquals("null")) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (data.contentEquals("undefined")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,13 +222,66 @@ public class RESTApi {
|
|||||||
*/
|
*/
|
||||||
public <T> T delete(final Class<T> clazz, final String urlOffset)
|
public <T> T delete(final Class<T> clazz, final String urlOffset)
|
||||||
throws RESTErrorResponseExeption, IOException, InterruptedException {
|
throws RESTErrorResponseExeption, IOException, InterruptedException {
|
||||||
|
return simpleRequest("DELETE", clazz, urlOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call an ARCHIVE on a REST API
|
||||||
|
* @param urlOffset Offset to call the API
|
||||||
|
*/
|
||||||
|
public void archive(final String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException {
|
||||||
|
archive(Void.class, urlOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call a ARCHIVE on a REST API with retrieving some data
|
||||||
|
* @param <T> Type of data that might be received.
|
||||||
|
* @param clazz Class model of the data that might be parsed.
|
||||||
|
* @param urlOffset Offset to call the API
|
||||||
|
* @return The parsed object received.
|
||||||
|
*/
|
||||||
|
public <T> T archive(final Class<T> clazz, final String urlOffset)
|
||||||
|
throws RESTErrorResponseExeption, IOException, InterruptedException {
|
||||||
|
return simpleRequest("ARCHIVE", clazz, urlOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call an RESTORE on a REST API
|
||||||
|
* @param urlOffset Offset to call the API
|
||||||
|
*/
|
||||||
|
public void restore(final String urlOffset) throws RESTErrorResponseExeption, IOException, InterruptedException {
|
||||||
|
restore(Void.class, urlOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call a RESTORE on a REST API with retrieving some data
|
||||||
|
* @param <T> Type of data that might be received.
|
||||||
|
* @param clazz Class model of the data that might be parsed.
|
||||||
|
* @param urlOffset Offset to call the API
|
||||||
|
* @return The parsed object received.
|
||||||
|
*/
|
||||||
|
public <T> T restore(final Class<T> clazz, final String urlOffset)
|
||||||
|
throws RESTErrorResponseExeption, IOException, InterruptedException {
|
||||||
|
return simpleRequest("RESTORE", clazz, urlOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call a key on a REST API with retrieving some data
|
||||||
|
* @param <T> Type of data that might be received.
|
||||||
|
* @param model name of the key for the REST call
|
||||||
|
* @param clazz Class model of the data that might be parsed.
|
||||||
|
* @param urlOffset Offset to call the API
|
||||||
|
* @return The parsed object received.
|
||||||
|
*/
|
||||||
|
public <T> T simpleRequest(final String model, final Class<T> clazz, final String urlOffset)
|
||||||
|
throws RESTErrorResponseExeption, IOException, InterruptedException {
|
||||||
final HttpClient client = HttpClient.newHttpClient();
|
final HttpClient client = HttpClient.newHttpClient();
|
||||||
Builder requestBuilding = HttpRequest.newBuilder().version(Version.HTTP_1_1)
|
Builder requestBuilding = HttpRequest.newBuilder().version(Version.HTTP_1_1)
|
||||||
.uri(URI.create(this.baseUrl + urlOffset));
|
.uri(URI.create(this.baseUrl + urlOffset));
|
||||||
if (this.token != null) {
|
if (this.token != null) {
|
||||||
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Bearer " + this.token);
|
requestBuilding = requestBuilding.header(HttpHeaders.AUTHORIZATION, "Bearer " + this.token);
|
||||||
}
|
}
|
||||||
final HttpRequest request = requestBuilding.DELETE().build();
|
final HttpRequest request = requestBuilding.method(model, BodyPublishers.ofString("")).build();
|
||||||
final HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
|
final HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
|
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
|
||||||
try {
|
try {
|
||||||
|
@ -7,11 +7,15 @@
|
|||||||
import { RestErrorResponse, isRestErrorResponse } from "./model";
|
import { RestErrorResponse, isRestErrorResponse } from "./model";
|
||||||
|
|
||||||
export enum HTTPRequestModel {
|
export enum HTTPRequestModel {
|
||||||
|
ARCHIVE = "ARCHIVE",
|
||||||
DELETE = "DELETE",
|
DELETE = "DELETE",
|
||||||
|
HEAD = "HEAD",
|
||||||
GET = "GET",
|
GET = "GET",
|
||||||
|
OPTION = "OPTION",
|
||||||
PATCH = "PATCH",
|
PATCH = "PATCH",
|
||||||
POST = "POST",
|
POST = "POST",
|
||||||
PUT = "PUT",
|
PUT = "PUT",
|
||||||
|
RESTORE = "RESTORE",
|
||||||
}
|
}
|
||||||
export enum HTTPMimeType {
|
export enum HTTPMimeType {
|
||||||
ALL = "*/*",
|
ALL = "*/*",
|
||||||
@ -248,9 +252,14 @@ export function RESTRequest({
|
|||||||
if (restModel.accept !== undefined) {
|
if (restModel.accept !== undefined) {
|
||||||
headers["Accept"] = restModel.accept;
|
headers["Accept"] = restModel.accept;
|
||||||
}
|
}
|
||||||
if (restModel.requestType !== HTTPRequestModel.GET) {
|
if (restModel.requestType !== HTTPRequestModel.GET &&
|
||||||
|
restModel.requestType !== HTTPRequestModel.ARCHIVE &&
|
||||||
|
restModel.requestType !== HTTPRequestModel.RESTORE
|
||||||
|
) {
|
||||||
// if Get we have not a content type, the body is empty
|
// if Get we have not a content type, the body is empty
|
||||||
if (restModel.contentType !== HTTPMimeType.MULTIPART) {
|
if (restModel.contentType !== HTTPMimeType.MULTIPART &&
|
||||||
|
restModel.contentType !== undefined
|
||||||
|
) {
|
||||||
// special case of multi-part ==> no content type otherwise the browser does not set the ";bundary=--****"
|
// special case of multi-part ==> no content type otherwise the browser does not set the ";bundary=--****"
|
||||||
headers["Content-Type"] = restModel.contentType;
|
headers["Content-Type"] = restModel.contentType;
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
0.14.2
|
0.16.0
|
||||||
|
Loading…
Reference in New Issue
Block a user