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>
|
||||
<groupId>kangaroo-and-rabbit</groupId>
|
||||
<artifactId>archidata</artifactId>
|
||||
<version>0.14.2</version>
|
||||
<version>0.16.0</version>
|
||||
<properties>
|
||||
<java.version>21</java.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("===================================================");
|
||||
final Data value = getSmall(uuid);
|
||||
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();
|
||||
}
|
||||
try {
|
||||
LOGGER.warn("Generate stream : {}", uuid);
|
||||
return buildStream(getFileData(uuid), range,
|
||||
value.mimeType == null ? "application/octet-stream" : value.mimeType);
|
||||
} catch (final Exception ex) {
|
||||
@ -478,8 +480,9 @@ public class DataResource {
|
||||
to = file.length() - 1;
|
||||
}
|
||||
final String responseRange = String.format("bytes %d-%d/%d", from, to, file.length());
|
||||
// logger.info("responseRange: {}", responseRange);
|
||||
try (final RandomAccessFile raf = new RandomAccessFile(file, "r")) {
|
||||
// LOGGER.info("responseRange: {}", responseRange);
|
||||
try {
|
||||
final RandomAccessFile raf = new RandomAccessFile(file, "r");
|
||||
raf.seek(from);
|
||||
|
||||
final long len = to - from + 1;
|
||||
|
@ -58,5 +58,4 @@ public class MediaStreamer implements StreamingOutput {
|
||||
public long getLenth() {
|
||||
return this.length;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ public class WebApplicationExceptionCatcher implements ExceptionMapper<WebApplic
|
||||
}
|
||||
|
||||
private RestErrorResponse build(final WebApplicationException exception) {
|
||||
exception.printStackTrace();
|
||||
return new RestErrorResponse(exception.getResponse().getStatusInfo().toEnum(), "Catch system exception",
|
||||
exception.getMessage());
|
||||
}
|
||||
|
@ -120,7 +120,8 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
||||
final String tmpVariable = "tmp_" + Integer.toString(count.value);
|
||||
querySelect.append(" (SELECT GROUP_CONCAT(");
|
||||
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 ");
|
||||
} else {
|
||||
querySelect.append(".object1Id ");
|
||||
@ -128,6 +129,7 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
||||
if ("sqlite".equals(ConfigBaseVariable.getDBType())) {
|
||||
querySelect.append(", ");
|
||||
} else {
|
||||
querySelect.append("ORDER BY uuid ASC ");
|
||||
querySelect.append("SEPARATOR ");
|
||||
}
|
||||
querySelect.append("'");
|
||||
@ -153,7 +155,7 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
||||
querySelect.append(" = ");
|
||||
querySelect.append(tmpVariable);
|
||||
querySelect.append(".");
|
||||
if (manyToMany.mappedBy() == null || manyToMany.mappedBy().length() == 0) {
|
||||
if (mode) {
|
||||
querySelect.append("object1Id ");
|
||||
} else {
|
||||
querySelect.append("object2Id ");
|
||||
@ -161,7 +163,7 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
||||
if (!"sqlite".equals(ConfigBaseVariable.getDBType())) {
|
||||
querySelect.append(" GROUP BY ");
|
||||
querySelect.append(tmpVariable);
|
||||
if (manyToMany.mappedBy() == null || manyToMany.mappedBy().length() == 0) {
|
||||
if (mode) {
|
||||
querySelect.append(".object1Id");
|
||||
} else {
|
||||
querySelect.append(".object2Id");
|
||||
|
@ -7,8 +7,10 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||
import org.kar.archidata.annotation.ARCHIVE;
|
||||
import org.kar.archidata.annotation.AsyncType;
|
||||
import org.kar.archidata.annotation.FormDataOptional;
|
||||
import org.kar.archidata.annotation.RESTORE;
|
||||
import org.kar.archidata.annotation.TypeScriptProgress;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@ -107,6 +109,12 @@ public class ApiTool {
|
||||
if (element.getDeclaredAnnotationsByType(DELETE.class).length == 1) {
|
||||
return "DELETE";
|
||||
}
|
||||
if (element.getDeclaredAnnotationsByType(RESTORE.class).length == 1) {
|
||||
return "RESTORE";
|
||||
}
|
||||
if (element.getDeclaredAnnotationsByType(ARCHIVE.class).length == 1) {
|
||||
return "ARCHIVE";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -126,6 +134,12 @@ public class ApiTool {
|
||||
if (element.getDeclaredAnnotationsByType(DELETE.class).length == 1) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
package org.kar.archidata.externalRestApi.model;
|
||||
|
||||
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());
|
||||
|
||||
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",
|
||||
"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-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")) {
|
||||
return null;
|
||||
}
|
||||
if (data.contentEquals("undefined")) {
|
||||
return null;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -222,13 +222,66 @@ public class RESTApi {
|
||||
*/
|
||||
public <T> T delete(final Class<T> clazz, final String urlOffset)
|
||||
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();
|
||||
Builder requestBuilding = HttpRequest.newBuilder().version(Version.HTTP_1_1)
|
||||
.uri(URI.create(this.baseUrl + urlOffset));
|
||||
if (this.token != null) {
|
||||
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());
|
||||
if (httpResponse.statusCode() < 200 || httpResponse.statusCode() >= 300) {
|
||||
try {
|
||||
|
@ -7,11 +7,15 @@
|
||||
import { RestErrorResponse, isRestErrorResponse } from "./model";
|
||||
|
||||
export enum HTTPRequestModel {
|
||||
ARCHIVE = "ARCHIVE",
|
||||
DELETE = "DELETE",
|
||||
HEAD = "HEAD",
|
||||
GET = "GET",
|
||||
OPTION = "OPTION",
|
||||
PATCH = "PATCH",
|
||||
POST = "POST",
|
||||
PUT = "PUT",
|
||||
RESTORE = "RESTORE",
|
||||
}
|
||||
export enum HTTPMimeType {
|
||||
ALL = "*/*",
|
||||
@ -248,9 +252,14 @@ export function RESTRequest({
|
||||
if (restModel.accept !== undefined) {
|
||||
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 (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=--****"
|
||||
headers["Content-Type"] = restModel.contentType;
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
0.14.2
|
||||
0.16.0
|
||||
|
Loading…
Reference in New Issue
Block a user