Skip to content

Commit

Permalink
Finalise download
Browse files Browse the repository at this point in the history
  • Loading branch information
sven1103 committed Oct 18, 2024
1 parent c989fd0 commit 9c795a7
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
import org.springframework.stereotype.Component;

/**
* <b><class short description - 1 Line!></b>
*
* <p><More detailed description - When to use, what it solves, etc.></p>
* <b>Temporary Director</b>
* <p>
* Provides a temporary directory for the application to use when files need to be created for
* exporting them.
*
* @since <version tag>
*/
Expand All @@ -23,15 +24,15 @@ public TempDirectory(@Value("${service.host.temp.dir}") String tempDirectoryPath
throws IOException {
Path tempDirPath = Path.of(tempDirectoryPath);
if (!Files.exists(tempDirPath)) {
throw new IOException(tempDirectoryPath + " does not exist");
}
if (!Files.isWritable(tempDirPath)) {
throw new IOException(tempDirectoryPath + " is not writable");
}
if (!Files.isExecutable(tempDirPath)) {
throw new IOException(tempDirectoryPath + " is not executable");
}
tempDir = tempDirPath;
throw new IOException(tempDirectoryPath + " does not exist");
}
if (!Files.isWritable(tempDirPath)) {
throw new IOException(tempDirectoryPath + " is not writable");
}
if (!Files.isExecutable(tempDirPath)) {
throw new IOException(tempDirectoryPath + " is not executable");
}
tempDir = tempDirPath;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package life.qbic.datamanager.export.docx;

import java.io.File;
import java.util.List;
import life.qbic.datamanager.export.Formatter;
import life.qbic.datamanager.export.model.ContactPoint;
import life.qbic.datamanager.export.model.ResearchProject;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;

/**
* <b><class short description - 1 Line!></b>
Expand All @@ -23,12 +26,39 @@ public static DocxFormatter create() {
public File from(String fileName, ResearchProject researchProject) {
try {
var wordPackage = WordprocessingMLPackage.createPackage();
wordPackage.getMainDocumentPart().addParagraphOfText(researchProject.name());
var mainDocument = wordPackage.getMainDocumentPart();
addTitle(mainDocument, researchProject);
addProjectId(mainDocument, researchProject);
addSection(mainDocument, "Description", researchProject.description());
addSectionTitle(mainDocument, "Contact Points");
researchProject.contactPoint().forEach(contactPoint -> addContactPoint(mainDocument, contactPoint));
File file = new File(fileName);
wordPackage.save(file);
return file;
} catch (Docx4JException e) {
throw new FormatException("Creating docx package failed. ", e);
}
}

private void addTitle(MainDocumentPart mainDocumentPart, ResearchProject researchProject) {
mainDocumentPart.addStyledParagraphOfText("Title", researchProject.name());
}

private void addProjectId(MainDocumentPart mainDocumentPart, ResearchProject researchProject) {
mainDocumentPart.addStyledParagraphOfText("Subtitle", "Project ID: " + researchProject.identifier());
}

private void addSection(MainDocumentPart mainDocumentPart, String sectionTitle, String sectionContent) {
mainDocumentPart.addStyledParagraphOfText("Heading1", sectionTitle);
mainDocumentPart.addParagraphOfText(sectionContent);
}

private void addSectionTitle(MainDocumentPart mainDocumentPart, String title) {
mainDocumentPart.addStyledParagraphOfText("Heading1", title);
}

private void addContactPoint(MainDocumentPart mainDocumentPart, ContactPoint contactPoint) {
var contactPointFormatted = "%s (%s) - %s".formatted(contactPoint.name(), contactPoint.contactType(), contactPoint.email());
mainDocumentPart.addParagraphOfText(contactPointFormatted);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,36 @@
*/
public class ContactPoint {

@JsonProperty(value = "@type", defaultValue = "ContactPoint")
private String type;
@JsonProperty(value = "@type")
private final String type = "ContactPoint";

@JsonProperty(value = "name")
private String name;

@JsonProperty(value = "email")
private String email;

public static ContactPoint from(String name, String email) {
@JsonProperty(value = "contactType")
private String contactType;

public static ContactPoint from(String name, String email, String contactType) {
ContactPoint contactPoint = new ContactPoint();
contactPoint.name = name;
contactPoint.email = email;
contactPoint.contactType = contactType;
return contactPoint;
}

public String name() {
return name;
}

public String email() {
return email;
}

public String contactType() {
return contactType;
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package life.qbic.datamanager.export.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;

/**
* A schema.org <a href="https://schema.org/ResearchProject">ResearchProject</a> representation in Java.
Expand All @@ -10,7 +11,7 @@
public class ResearchProject {

@JsonProperty(value = "@type")
private String type = "ResearchProject";
private final String type = "ResearchProject";

@JsonProperty(value = "name")
private String name;
Expand All @@ -21,11 +22,15 @@ public class ResearchProject {
@JsonProperty(value = "description")
private String description;

public static ResearchProject from(String name, String identifier, String description) {
@JsonProperty(value = "contactPoint")
private List<ContactPoint> contactPoint;

public static ResearchProject from(String name, String identifier, String description, List<ContactPoint> contactPoint) {
ResearchProject project = new ResearchProject();
project.name = name;
project.identifier = identifier;
project.description = description;
project.contactPoint = contactPoint.stream().toList();
return project;
}

Expand All @@ -37,4 +42,12 @@ public String identifier() {
return identifier;
}

public String description() {
return description;
}

public List<ContactPoint> contactPoint() {
return contactPoint.stream().toList();
}

}
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
package life.qbic.datamanager.export.rocrate;

import static life.qbic.datamanager.export.rocrate.ROCreateBuilder.ResearchProjectConstants.SUMMARY_FILENAME_DOCX;
import static life.qbic.datamanager.export.rocrate.ROCreateBuilder.ResearchProjectConstants.SUMMARY_FILENAME_YAML;

import edu.kit.datamanager.ro_crate.RoCrate;
import edu.kit.datamanager.ro_crate.entities.data.FileEntity;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Objects;
import life.qbic.datamanager.export.TempDirectory;
import life.qbic.datamanager.export.docx.DocxFormatter;
import life.qbic.datamanager.export.model.ContactPoint;
import life.qbic.datamanager.export.model.ResearchProject;
import life.qbic.datamanager.export.yaml.YamlFormatter;
import life.qbic.projectmanagement.domain.model.project.Contact;
import life.qbic.projectmanagement.domain.model.project.Project;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
* <b><class short description - 1 Line!></b>
*
* <p><More detailed description - When to use, what it solves, etc.></p>
* <b>RO-Crate Builder</b>
* <p>
* Builder class that helps to build a RO-Crate based on various QBiC data manager project
* information.
*
* @since <version tag>
* @since 1.6.0
*/
@Component
public class ROCreateBuilder {
Expand All @@ -32,32 +39,32 @@ public ROCreateBuilder(TempDirectory tempDir) {

private static RoCrate buildRoCrate(Path buildDir, ResearchProject researchProject) {
var projectInfoDocx = DocxFormatter.create()
.from(buildDir.resolve("project-information.docx").toString(), researchProject);
.from(buildDir.resolve(SUMMARY_FILENAME_DOCX.value()).toString(), researchProject);
var projectInfoYaml = YamlFormatter.create()
.from(buildDir.resolve("project-information.yml").toString(), researchProject);
.from(buildDir.resolve(SUMMARY_FILENAME_YAML.value()).toString(), researchProject);
return new RoCrate.RoCrateBuilder(
"QBiC-project-%s-ro-crate".formatted(researchProject.identifier()),
"Description of the project %s with the title '%s', managed on the Data Manager, Quantitative Biology Center, University of Tübingen.".formatted(
researchProject.identifier(), researchProject.name()))
.addDataEntity(
new FileEntity.FileEntityBuilder()
.setSource(projectInfoDocx)
.setId("project-information.docx")
.addProperty("name", "Project Information")
.setId(SUMMARY_FILENAME_DOCX.value())
.addProperty("name", "Project Summary")
.addProperty("encodingFormat",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document")
MimeTypes.DOCX.value())
.build())
.addDataEntity(
new FileEntity.FileEntityBuilder()
.setSource(projectInfoYaml)
.setId("project-information.yml")
.addProperty("name", "Project Information")
.addProperty("encodingFormat", "application/yaml")
.setId(SUMMARY_FILENAME_YAML.value())
.addProperty("name", "Project Summary")
.addProperty("encodingFormat", MimeTypes.YAML.value())
.build())
.build();
}

public RoCrate projectInformation(Project project) throws ROCrateBuildException {
public RoCrate projectSummary(Project project) throws ROCrateBuildException {
var researchProject = convertToResearchProject(project);
try {
var assignedBuildDirectory = tempDirectory.createDirectory();
Expand All @@ -69,8 +76,57 @@ public RoCrate projectInformation(Project project) throws ROCrateBuildException
}

private ResearchProject convertToResearchProject(Project project) {
var contactPoints = new ArrayList<ContactPoint>();
contactPoints.add(toContactPoint(project.getPrincipalInvestigator(), "Principal Investigator"));
contactPoints.add(toContactPoint(project.getProjectManager(), "Project Manager"));
if (project.getResponsiblePerson().isPresent()) {
contactPoints.add(toContactPoint(project.getResponsiblePerson().get(), "Responsible Person"));
}
return ResearchProject.from(project.getProjectIntent().projectTitle().title(),
project.getProjectCode().value(), project.getProjectIntent().objective().objective());
project.getProjectCode().value(), project.getProjectIntent().objective().objective(),
contactPoints);
}

private ContactPoint toContactPoint(Contact contact, String contactType) {
return ContactPoint.from(contact.fullName(), contact.emailAddress(), contactType);
}

enum ResearchProjectConstants implements Value {

SUMMARY_FILENAME_DOCX("project-summary.docx"),
SUMMARY_FILENAME_YAML("project-summary.yml");

private final String value;

ResearchProjectConstants(String value) {
this.value = value;
}

public String value() {
return value;
}
}

enum MimeTypes implements Value {

DOCX("application/vnd.openxmlformats-officedocument.wordprocessingml.document"),
YAML("application/yaml");

private final String value;

MimeTypes(String value) {
this.value = value;
}

@Override
public String value() {
return value;
}
}

interface Value {

String value();
}

public static class ROCrateBuildException extends RuntimeException {
Expand All @@ -83,5 +139,4 @@ public ROCrateBuildException(String message, Throwable cause) {
super(message, cause);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
* <b>Project Edit Event</b>
* <p>
* Event that indicates that the user wants to edit a project via the
* {@link ProjectDetailsComponent}
* {@link ProjectSummaryComponent}
*
* @since 1.0.0
*/
public class ProjectEditEvent extends ComponentEvent<ProjectDetailsComponent> {
public class ProjectEditEvent extends ComponentEvent<ProjectSummaryComponent> {

@Serial
private static final long serialVersionUID = -4045489562991683868L;
Expand All @@ -27,7 +27,7 @@ public class ProjectEditEvent extends ComponentEvent<ProjectDetailsComponent> {
* @param fromClient <code>true</code> if the event originated from the client
* side, <code>false</code> otherwise
*/
public ProjectEditEvent(ProjectDetailsComponent source, ProjectId projectId,
public ProjectEditEvent(ProjectSummaryComponent source, ProjectId projectId,
boolean fromClient) {
super(source, fromClient);
this.projectId = projectId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public class ProjectInformationMain extends Main implements BeforeEnterObserver
private final transient ProjectPurchaseService projectPurchaseService;
private final transient QualityControlService qualityControlService;
private final transient UserPermissions userPermissions;
private final ProjectDetailsComponent projectDetailsComponent;
private final ProjectSummaryComponent projectSummaryComponent;
private final ExperimentListComponent experimentListComponent;
private final OfferDownload offerDownload;
private final QualityControlDownload qualityControlDownload;
Expand All @@ -95,7 +95,7 @@ public class ProjectInformationMain extends Main implements BeforeEnterObserver
private final TerminologyService terminologyService;
private Context context;

public ProjectInformationMain(@Autowired ProjectDetailsComponent projectDetailsComponent,
public ProjectInformationMain(@Autowired ProjectSummaryComponent projectSummaryComponent,
@Autowired ExperimentListComponent experimentListComponent,
@Autowired UserPermissions userPermissions,
@Autowired AddExperimentToProjectService addExperimentToProjectService,
Expand All @@ -106,7 +106,7 @@ public ProjectInformationMain(@Autowired ProjectDetailsComponent projectDetailsC
@Autowired TerminologyService terminologyService,
CancelConfirmationDialogFactory cancelConfirmationDialogFactory,
MessageSourceNotificationFactory messageSourceNotificationFactory) {
this.projectDetailsComponent = requireNonNull(projectDetailsComponent,
this.projectSummaryComponent = requireNonNull(projectSummaryComponent,
"projectDetailsComponent must not be null");
this.experimentListComponent = requireNonNull(experimentListComponent,
"experimentListComponent must not be null");
Expand Down Expand Up @@ -140,7 +140,7 @@ public ProjectInformationMain(@Autowired ProjectDetailsComponent projectDetailsC
this.experimentListComponent.addExperimentSelectionListener(this::onExperimentSelectionEvent);
this.experimentListComponent.addAddButtonListener(this::onAddExperimentClicked);
addClassName("project");
add(projectDetailsComponent, offerListComponent, offerDownload, experimentListComponent,
add(projectSummaryComponent, offerListComponent, offerDownload, experimentListComponent,
qualityControlListComponent, qualityControlDownload);
this.terminologyService = terminologyService;
}
Expand Down Expand Up @@ -300,7 +300,7 @@ private void onExperimentSelectionEvent(ExperimentSelectionEvent event) {

private void setContext(Context context) {
this.context = context;
projectDetailsComponent.setContext(context);
projectSummaryComponent.setContext(context);
experimentListComponent.setContext(context);
refreshOffers(projectPurchaseService, context.projectId().orElseThrow().value(),
offerListComponent);
Expand Down
Loading

0 comments on commit 9c795a7

Please sign in to comment.