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 de.mbremer.secutity.User;
|
||||||
import io.quarkus.hibernate.orm.panache.PanacheEntity;
|
import io.quarkus.hibernate.orm.panache.PanacheEntity;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
@@ -13,7 +13,7 @@ import java.time.LocalDate;
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@RequiredArgsConstructor
|
@NoArgsConstructor
|
||||||
@Entity
|
@Entity
|
||||||
public class KalenderTag extends PanacheEntity {
|
public class KalenderTag extends PanacheEntity {
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
package de.mbremer.room;
|
package de.mbremer.room;
|
||||||
|
|
||||||
|
import de.mbremer.image.ImageService;
|
||||||
import io.quarkus.qute.Template;
|
import io.quarkus.qute.Template;
|
||||||
import io.quarkus.qute.TemplateInstance;
|
import io.quarkus.qute.TemplateInstance;
|
||||||
import io.quarkus.security.identity.SecurityIdentity;
|
import io.quarkus.security.identity.SecurityIdentity;
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;
|
import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;
|
||||||
|
|
||||||
import javax.annotation.security.RolesAllowed;
|
import javax.annotation.security.RolesAllowed;
|
||||||
import javax.enterprise.context.ApplicationScoped;
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.validation.ValidationException;
|
||||||
import javax.ws.rs.*;
|
import javax.ws.rs.*;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
@@ -16,21 +17,18 @@ import java.io.IOException;
|
|||||||
|
|
||||||
@Path("/room")
|
@Path("/room")
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
|
@RolesAllowed({"USER", "ADMIN"})
|
||||||
public class RoomResource {
|
public class RoomResource {
|
||||||
|
|
||||||
public static final int MAX_PLANSIZE_IN_BYTES = 1000 * 1024;
|
|
||||||
@Inject
|
|
||||||
Logger log;
|
|
||||||
@Inject
|
@Inject
|
||||||
SecurityIdentity identity;
|
SecurityIdentity identity;
|
||||||
@Inject
|
@Inject
|
||||||
|
ImageService imageService;
|
||||||
|
@Inject
|
||||||
Template room;
|
Template room;
|
||||||
|
|
||||||
private byte[] roomPlan = new byte[0];
|
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.TEXT_HTML)
|
@Produces(MediaType.TEXT_HTML)
|
||||||
@RolesAllowed({"USER", "ADMIN"})
|
|
||||||
public TemplateInstance getRoom() {
|
public TemplateInstance getRoom() {
|
||||||
return room
|
return room
|
||||||
.data("is_admin", identity.hasRole("ADMIN"));
|
.data("is_admin", identity.hasRole("ADMIN"));
|
||||||
@@ -43,15 +41,12 @@ public class RoomResource {
|
|||||||
@RolesAllowed({"ADMIN"})
|
@RolesAllowed({"ADMIN"})
|
||||||
public TemplateInstance uploadRoomplan(@MultipartForm RoomFileForm roomFileForm) throws IOException {
|
public TemplateInstance uploadRoomplan(@MultipartForm RoomFileForm roomFileForm) throws IOException {
|
||||||
byte[] newRoomPlan = roomFileForm.file.readAllBytes();
|
byte[] newRoomPlan = roomFileForm.file.readAllBytes();
|
||||||
int newPlanSize = newRoomPlan.length;
|
|
||||||
|
|
||||||
TemplateInstance room = getRoom();
|
TemplateInstance room = getRoom();
|
||||||
// validate
|
try {
|
||||||
log.info("Uploaded " + newPlanSize + " Bytes Roomplan" );
|
imageService.persistRoomplan(newRoomPlan);
|
||||||
if (newPlanSize > MAX_PLANSIZE_IN_BYTES) {
|
} catch (ValidationException e) {
|
||||||
room.data("error", "Raumplan ist zu groß: " + newPlanSize + " Bytes. Maximal " + MAX_PLANSIZE_IN_BYTES + " Bytes erlaubt.");
|
room.data("error", e.getMessage());
|
||||||
} else {
|
|
||||||
roomPlan = newRoomPlan;
|
|
||||||
}
|
}
|
||||||
return room;
|
return room;
|
||||||
}
|
}
|
||||||
@@ -59,9 +54,8 @@ public class RoomResource {
|
|||||||
@GET
|
@GET
|
||||||
@Path("/plan")
|
@Path("/plan")
|
||||||
@Produces("image/*")
|
@Produces("image/*")
|
||||||
@RolesAllowed({"USER", "ADMIN"})
|
|
||||||
public Response getImage(@PathParam("image") String image) {
|
public Response getImage(@PathParam("image") String image) {
|
||||||
|
byte[] roomplan = imageService.getRoomplan();
|
||||||
return roomPlan.length < 1 ? Response.noContent().build() : Response.ok(roomPlan).build();
|
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{/}
|
{#room_active}active{/}
|
||||||
{#contents}
|
{#contents}
|
||||||
|
|
||||||
|
<div class="mt-2">
|
||||||
|
<img src="/room/plan" alt="kein Raumplan vorhanden">
|
||||||
|
</div>
|
||||||
|
|
||||||
{#if is_admin}
|
{#if is_admin}
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<form action="/room/plan" method="POST" enctype="multipart/form-data">
|
<form action="/room/plan" method="POST" enctype="multipart/form-data">
|
||||||
<label id="filelabel" class="btn btn-secondary" for="fileinput">
|
<label id="filelabel" class="btn btn-secondary" for="fileinput">
|
||||||
Raumplan auswählen...
|
neuen Raumplan auswählen...
|
||||||
</label>
|
</label>
|
||||||
<input id="fileinput" type="file" name="file" accept="image/*" hidden
|
<input id="fileinput" type="file" name="file" accept="image/*" hidden
|
||||||
onchange="document.getElementById('filelabel').innerHTML = 'Datei: ' + this.files[0].name;" />
|
onchange="document.getElementById('filelabel').innerHTML = 'Datei: ' + this.files[0].name;" />
|
||||||
|
|||||||
Reference in New Issue
Block a user