roomplan persistence
This commit is contained in:
26
src/main/java/de/mbremer/image/Image.java
Normal file
26
src/main/java/de/mbremer/image/Image.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package de.mbremer.image;
|
||||
|
||||
import io.quarkus.hibernate.orm.panache.PanacheEntity;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Entity
|
||||
public class Image extends PanacheEntity {
|
||||
@NotNull
|
||||
@Column(nullable = false)
|
||||
private String name;
|
||||
@NotNull
|
||||
@Column(nullable = false)
|
||||
private byte[] data;
|
||||
}
|
||||
57
src/main/java/de/mbremer/image/ImageService.java
Normal file
57
src/main/java/de/mbremer/image/ImageService.java
Normal file
@@ -0,0 +1,57 @@
|
||||
package de.mbremer.image;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import javax.enterprise.context.ApplicationScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.transaction.Transactional;
|
||||
import javax.validation.ValidationException;
|
||||
|
||||
@ApplicationScoped
|
||||
public class ImageService {
|
||||
|
||||
private static final String ROOMPLAN_NAME = "roomplan";
|
||||
private static final int MAX_PLANSIZE_IN_BYTES = 1000 * 1024;
|
||||
|
||||
@Inject
|
||||
Logger log;
|
||||
|
||||
public byte[] getRoomplan() {
|
||||
try {
|
||||
Image image = Image.find("name", ROOMPLAN_NAME).singleResult();
|
||||
return image.getData();
|
||||
} catch (NoResultException e) {
|
||||
return new byte[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
private void validate(byte[] data) {
|
||||
if (data.length > MAX_PLANSIZE_IN_BYTES) {
|
||||
throw new ValidationException("Bild ist zu groß: " + data.length + " Bytes. Maximal " + MAX_PLANSIZE_IN_BYTES + " Bytes " +
|
||||
"erlaubt.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
@Transactional
|
||||
public void persistRoomplan(byte[] data) {
|
||||
validate(data);
|
||||
boolean exists = Image.count("name", ROOMPLAN_NAME) > 0;
|
||||
log.info("Persist Roomplan:" + data.length + " Bytes" );
|
||||
|
||||
if (exists) {
|
||||
Image.update("data=?1 where name=?2", data, ROOMPLAN_NAME);
|
||||
} else {
|
||||
Image roomplan = new Image(ROOMPLAN_NAME, data);
|
||||
roomplan.persist();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package de.mbremer.kalender;
|
||||
import de.mbremer.secutity.User;
|
||||
import io.quarkus.hibernate.orm.panache.PanacheEntity;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
@@ -13,7 +13,7 @@ import java.time.LocalDate;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@RequiredArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Entity
|
||||
public class KalenderTag extends PanacheEntity {
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
package de.mbremer.room;
|
||||
|
||||
import de.mbremer.image.ImageService;
|
||||
import io.quarkus.qute.Template;
|
||||
import io.quarkus.qute.TemplateInstance;
|
||||
import io.quarkus.security.identity.SecurityIdentity;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;
|
||||
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
import javax.enterprise.context.ApplicationScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.validation.ValidationException;
|
||||
import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
@@ -16,21 +17,18 @@ import java.io.IOException;
|
||||
|
||||
@Path("/room")
|
||||
@ApplicationScoped
|
||||
@RolesAllowed({"USER", "ADMIN"})
|
||||
public class RoomResource {
|
||||
|
||||
public static final int MAX_PLANSIZE_IN_BYTES = 1000 * 1024;
|
||||
@Inject
|
||||
Logger log;
|
||||
@Inject
|
||||
SecurityIdentity identity;
|
||||
@Inject
|
||||
ImageService imageService;
|
||||
@Inject
|
||||
Template room;
|
||||
|
||||
private byte[] roomPlan = new byte[0];
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.TEXT_HTML)
|
||||
@RolesAllowed({"USER", "ADMIN"})
|
||||
public TemplateInstance getRoom() {
|
||||
return room
|
||||
.data("is_admin", identity.hasRole("ADMIN"));
|
||||
@@ -43,15 +41,12 @@ public class RoomResource {
|
||||
@RolesAllowed({"ADMIN"})
|
||||
public TemplateInstance uploadRoomplan(@MultipartForm RoomFileForm roomFileForm) throws IOException {
|
||||
byte[] newRoomPlan = roomFileForm.file.readAllBytes();
|
||||
int newPlanSize = newRoomPlan.length;
|
||||
|
||||
TemplateInstance room = getRoom();
|
||||
// validate
|
||||
log.info("Uploaded " + newPlanSize + " Bytes Roomplan" );
|
||||
if (newPlanSize > MAX_PLANSIZE_IN_BYTES) {
|
||||
room.data("error", "Raumplan ist zu groß: " + newPlanSize + " Bytes. Maximal " + MAX_PLANSIZE_IN_BYTES + " Bytes erlaubt.");
|
||||
} else {
|
||||
roomPlan = newRoomPlan;
|
||||
try {
|
||||
imageService.persistRoomplan(newRoomPlan);
|
||||
} catch (ValidationException e) {
|
||||
room.data("error", e.getMessage());
|
||||
}
|
||||
return room;
|
||||
}
|
||||
@@ -59,9 +54,8 @@ public class RoomResource {
|
||||
@GET
|
||||
@Path("/plan")
|
||||
@Produces("image/*")
|
||||
@RolesAllowed({"USER", "ADMIN"})
|
||||
public Response getImage(@PathParam("image") String image) {
|
||||
|
||||
return roomPlan.length < 1 ? Response.noContent().build() : Response.ok(roomPlan).build();
|
||||
byte[] roomplan = imageService.getRoomplan();
|
||||
return roomplan.length == 0 ? Response.noContent().build() : Response.ok(roomplan).build();
|
||||
}
|
||||
}
|
||||
5
src/main/resources/db/migration/V0002__image.sql
Normal file
5
src/main/resources/db/migration/V0002__image.sql
Normal file
@@ -0,0 +1,5 @@
|
||||
create table image (
|
||||
id bigint not null primary key,
|
||||
name varchar not null unique,
|
||||
data bytea not null
|
||||
);
|
||||
@@ -2,11 +2,15 @@
|
||||
{#room_active}active{/}
|
||||
{#contents}
|
||||
|
||||
<div class="mt-2">
|
||||
<img src="/room/plan" alt="kein Raumplan vorhanden">
|
||||
</div>
|
||||
|
||||
{#if is_admin}
|
||||
<div class="mt-2">
|
||||
<form action="/room/plan" method="POST" enctype="multipart/form-data">
|
||||
<label id="filelabel" class="btn btn-secondary" for="fileinput">
|
||||
Raumplan auswählen...
|
||||
neuen Raumplan auswählen...
|
||||
</label>
|
||||
<input id="fileinput" type="file" name="file" accept="image/*" hidden
|
||||
onchange="document.getElementById('filelabel').innerHTML = 'Datei: ' + this.files[0].name;" />
|
||||
|
||||
Reference in New Issue
Block a user