Skip to content

Commit

Permalink
- ADD: Added endpoints for creating, deleting and updating projects.
Browse files Browse the repository at this point in the history
- FIX: Fixed Flyway checksum calculation.
  • Loading branch information
sebastian-raubach committed Sep 30, 2024
1 parent 981820c commit b85a8c9
Show file tree
Hide file tree
Showing 7 changed files with 402 additions and 16 deletions.
Binary file modified lib/germinate-codegen-4.7.4.jar
Binary file not shown.
41 changes: 41 additions & 0 deletions src/main/java/jhi/germinate/resource/ProjectStats.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package jhi.germinate.resource;

public class ProjectStats
{
private int publicationCount = 0;
private int groupCount = 0;
private int datasetCount = 0;

public int getPublicationCount()
{
return publicationCount;
}

public ProjectStats setPublicationCount(int publicationCount)
{
this.publicationCount = publicationCount;
return this;
}

public int getGroupCount()
{
return groupCount;
}

public ProjectStats setGroupCount(int groupCount)
{
this.groupCount = groupCount;
return this;
}

public int getDatasetCount()
{
return datasetCount;
}

public ProjectStats setDatasetCount(int datasetCount)
{
this.datasetCount = datasetCount;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ public enum ImageType
news,
template,
mapoverlay,
storysteps
storysteps,
projects
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
package jhi.germinate.server.resource.projects;

import jakarta.ws.rs.*;
import jakarta.ws.rs.core.*;
import jhi.germinate.resource.ProjectStats;
import jhi.germinate.resource.enums.*;
import jhi.germinate.server.Database;
import jhi.germinate.server.database.codegen.tables.records.*;
import jhi.germinate.server.resource.images.ImageResource;
import jhi.germinate.server.util.*;
import org.glassfish.jersey.media.multipart.*;
import org.jooq.DSLContext;

import java.io.*;
import java.nio.file.StandardCopyOption;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.UUID;

import static jhi.germinate.server.database.codegen.tables.Datasets.DATASETS;
import static jhi.germinate.server.database.codegen.tables.Experiments.EXPERIMENTS;
import static jhi.germinate.server.database.codegen.tables.Images.IMAGES;
import static jhi.germinate.server.database.codegen.tables.Imagetypes.IMAGETYPES;
import static jhi.germinate.server.database.codegen.tables.Projectgroups.PROJECTGROUPS;
import static jhi.germinate.server.database.codegen.tables.Projectpublications.PROJECTPUBLICATIONS;
import static jhi.germinate.server.database.codegen.tables.Projects.PROJECTS;

@Path("project")
@Secured(UserType.DATA_CURATOR)
public class ProjectResource
{
@GET
@Path("/{projectId:\\d+}/stats")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response getProjectStats(@PathParam("projectId") Integer projectId)
throws SQLException
{
if (projectId == null)
return Response.status(Response.Status.BAD_REQUEST).build();

try (Connection conn = Database.getConnection())
{
DSLContext context = Database.getContext(conn);

ProjectsRecord project = context.selectFrom(PROJECTS).where(PROJECTS.ID.eq(projectId)).fetchAny();

if (project == null)
return Response.status(Response.Status.NOT_FOUND).build();

ProjectStats result = new ProjectStats();
result.setGroupCount(context.selectCount().from(PROJECTGROUPS).where(PROJECTGROUPS.PROJECT_ID.eq(projectId)).fetchOneInto(Integer.class));
result.setDatasetCount(context.selectCount().from(DATASETS).leftJoin(EXPERIMENTS).on(EXPERIMENTS.ID.eq(DATASETS.EXPERIMENT_ID)).where(EXPERIMENTS.PROJECT_ID.eq(projectId)).fetchOneInto(Integer.class));
result.setPublicationCount(context.selectCount().from(PROJECTPUBLICATIONS).where(PROJECTPUBLICATIONS.PROJECT_ID.eq(projectId)).fetchOneInto(Integer.class));

return Response.ok(result).build();
}
}

@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response postProject(@FormDataParam("name") String name,
@FormDataParam("description") String description,
@FormDataParam("pageContent") String pageContent,
@FormDataParam("externalUrl") String externalUrl,
@FormDataParam("startDate") String startDate,
@FormDataParam("endDate") String endDate,
@FormDataParam("image") InputStream image,
@FormDataParam("image") FormDataContentDisposition fileDetails)
throws SQLException, IOException
{
if (StringUtils.isEmpty(name))
return Response.status(Response.Status.BAD_REQUEST).build();

try (Connection conn = Database.getConnection())
{
DSLContext context = Database.getContext(conn);

ProjectsRecord project = context.newRecord(PROJECTS);
project.setName(name);
project.setDescription(description);
project.setExternalUrl(externalUrl);
project.setPageContent(pageContent);

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

if (!StringUtils.isEmpty(startDate))
{
try
{
project.setStartDate(new Timestamp(sdf.parse(startDate).getTime()));
}
catch (Exception e)
{
}
}
if (!StringUtils.isEmpty(startDate))
{
try
{
project.setEndDate(new Timestamp(sdf.parse(endDate).getTime()));
}
catch (Exception e)
{
}
}

project.store();

if (image != null)
{
ImagetypesRecord imageType = context.selectFrom(IMAGETYPES)
.where(IMAGETYPES.REFERENCE_TABLE.eq("projects"))
.fetchAny();

File folder = new File(new File(new File(PropertyWatcher.get(ServerProperty.DATA_DIRECTORY_EXTERNAL), "images"), ImageResource.ImageType.projects.name()), "upload");
folder.mkdirs();

String itemName = fileDetails.getFileName();
String uuid = UUID.randomUUID().toString();
String extension = itemName.substring(itemName.lastIndexOf(".") + 1);
File targetFile = new File(folder, uuid + "." + extension);

if (!FileUtils.isSubDirectory(folder, targetFile))
return Response.status(Response.Status.BAD_REQUEST).build();

java.nio.file.Files.copy(image, targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);

ImagesRecord imagesRecord = context.newRecord(IMAGES);
imagesRecord.setForeignId(project.getId());
imagesRecord.setImagetypeId(imageType.getId());
imagesRecord.setDescription(targetFile.getName());
imagesRecord.setPath("upload/" + targetFile.getName());
imagesRecord.store();

project.setImageId(imagesRecord.getId());
project.store(PROJECTS.IMAGE_ID);
}

return Response.status(Response.Status.OK).build();
}
}

@PATCH
@Path("/{projectId:\\d+}")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response patchProject(@PathParam("projectId") Integer projectId,
@FormDataParam("name") String name,
@FormDataParam("description") String description,
@FormDataParam("pageContent") String pageContent,
@FormDataParam("externalUrl") String externalUrl,
@FormDataParam("startDate") String startDate,
@FormDataParam("endDate") String endDate,
@FormDataParam("image") InputStream image,
@FormDataParam("image") FormDataContentDisposition fileDetails)
throws SQLException, IOException
{
if (projectId == null || StringUtils.isEmpty(name))
return Response.status(Response.Status.BAD_REQUEST).build();

try (Connection conn = Database.getConnection())
{
DSLContext context = Database.getContext(conn);

ProjectsRecord project = context.selectFrom(PROJECTS).where(PROJECTS.ID.eq(projectId)).fetchAny();

if (project == null)
return Response.status(Response.Status.NOT_FOUND).build();

project.setName(name);
project.setDescription(description);
project.setExternalUrl(externalUrl);
project.setPageContent(pageContent);

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

if (!StringUtils.isEmpty(startDate))
{
try
{
project.setStartDate(new Timestamp(sdf.parse(startDate).getTime()));
}
catch (Exception e)
{
project.setStartDate(null);
}
}
else
{
project.setStartDate(null);
}
if (!StringUtils.isEmpty(endDate))
{
try
{
project.setEndDate(new Timestamp(sdf.parse(endDate).getTime()));
}
catch (Exception e)
{
project.setEndDate(null);
}
}
else
{
project.setEndDate(null);
}

if (image != null)
{
ImagetypesRecord imageType = context.selectFrom(IMAGETYPES)
.where(IMAGETYPES.REFERENCE_TABLE.eq("projects"))
.fetchAny();

File folder = new File(new File(new File(PropertyWatcher.get(ServerProperty.DATA_DIRECTORY_EXTERNAL), "images"), ImageResource.ImageType.projects.name()), "upload");
folder.mkdirs();

String itemName = fileDetails.getFileName();
String uuid = UUID.randomUUID().toString();
String extension = itemName.substring(itemName.lastIndexOf(".") + 1);
File targetFile = new File(folder, uuid + "." + extension);

if (!FileUtils.isSubDirectory(folder, targetFile))
return Response.status(Response.Status.BAD_REQUEST).build();

java.nio.file.Files.copy(image, targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);

ImagesRecord imagesRecord = context.newRecord(IMAGES);
imagesRecord.setForeignId(project.getId());
imagesRecord.setImagetypeId(imageType.getId());
imagesRecord.setDescription(targetFile.getName());
imagesRecord.setPath("upload/" + targetFile.getName());
imagesRecord.store();

project.setImageId(imagesRecord.getId());
}
else
{
project.setImageId(null);
}

project.store();

return Response.status(Response.Status.OK).build();
}
}

@DELETE
@Path("/{projectId:\\d+}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response deleteProject(@PathParam("projectId") Integer projectId)
throws SQLException
{
if (projectId == null)
return Response.status(Response.Status.BAD_REQUEST).build();

try (Connection conn = Database.getConnection())
{
DSLContext context = Database.getContext(conn);

return Response.ok(context.deleteFrom(PROJECTS).where(PROJECTS.ID.eq(projectId)).execute() > 0).build();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package jhi.germinate.server.util;

import org.flywaydb.core.api.FlywayException;
import org.flywaydb.core.internal.util.StringUtils;
import org.flywaydb.core.internal.util.*;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.zip.CRC32;

/**
Expand All @@ -11,9 +14,9 @@
public class FlywayChecksumGenerator
{
public static void main(String[] args)
throws IOException
throws IOException
{
System.out.println(getChecksum(new File("src/main/resources/jhi/germinate/server/util/database/migration/V4.24.09.04__update.sql")));
System.out.println(getChecksum(new File("src/main/resources/jhi/germinate/server/util/database/migration/V4.24.09.27__update.sql")));
}

/**
Expand All @@ -24,20 +27,37 @@ public static void main(String[] args)
* @throws IOException Thrown if the interaction with the file fails
*/
public static int getChecksum(File file)
throws IOException
throws IOException
{
// Read the file as UTF8
try (BufferedReader br = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8))
final CRC32 crc32 = new CRC32();

BufferedReader bufferedReader = null;
try
{
// Create a new checksum
CRC32 crc32 = new CRC32();
bufferedReader = new BufferedReader(new FileReader(file), 4096);

// Add each line trimmed
for (String line; ((line = br.readLine()) != null); )
crc32.update(line.trim().getBytes(StandardCharsets.UTF_8));
String line = bufferedReader.readLine();

// Return value
return (int) crc32.getValue();
if (line != null)
{
line = BomFilter.FilterBomFromString(line);

do
{
//noinspection Since15
crc32.update(StringUtils.trimLineBreak(line).getBytes(StandardCharsets.UTF_8));
} while ((line = bufferedReader.readLine()) != null);
}
}
catch (IOException e)
{
throw new FlywayException("Unable to calculate checksum of " + file.getName() + "\r\n" + e.getMessage(), e);
}
finally
{
IOUtils.close(bufferedReader);
}

return (int) crc32.getValue();
}
}
Loading

0 comments on commit b85a8c9

Please sign in to comment.