diff --git a/core/src/main/java/se/su/dsv/scipro/file/FileDescription.java b/core/src/main/java/se/su/dsv/scipro/file/FileDescription.java index 7b4060922b..ac42cab487 100755 --- a/core/src/main/java/se/su/dsv/scipro/file/FileDescription.java +++ b/core/src/main/java/se/su/dsv/scipro/file/FileDescription.java @@ -33,25 +33,40 @@ public class FileDescription extends DomainObject { public static final int FILES_PER_SUBDIRECTORY = 1000; public static final String FILE_ROOT = "/scipro-files"; + // ---------------------------------------------------------------------------------- + // Basic JPA-mappings + // ---------------------------------------------------------------------------------- @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column + @Basic + @Column(name = "name") private String name; - @Column + @Basic + @Column(name = "mime_type") private String mimeType; - @Column - private String identifier; - - @ManyToOne - @JoinColumn(name = "userId") - private User uploader; - + @Basic + @Column(name = "size") private long size; + @Basic + @Column(name = "file_identifier") + private String identifier; + + // ---------------------------------------------------------------------------------- + // JPA-mappings of foreign keys in this table (file_description) referencing + // other tables. + // ---------------------------------------------------------------------------------- + @ManyToOne + @JoinColumn(name = "user_id", referencedColumnName = "id") + private User uploader; + + // ---------------------------------------------------------------------------------- + // JPA lifecycle methods + // ---------------------------------------------------------------------------------- @PostRemove void removeActualData() { try { @@ -63,6 +78,96 @@ public class FileDescription extends DomainObject { } } + // ---------------------------------------------------------------------------------- + // Properties (Getters and Setters) + // ---------------------------------------------------------------------------------- + @Override + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getMimeType() { + return this.mimeType; + } + + public void setMimeType(String mimeType) { + this.mimeType = mimeType; + } + + public long getSize() { + return this.size; + } + + public void setSize(long size) { + this.size = size; + } + + public String getIdentifier() { + return this.identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public User getUploader() { + return this.uploader; + } + + public void setUploader(User uploader) { + this.uploader = uploader; + } + + // ---------------------------------------------------------------------------------- + // Methods Common To All Objects + // ---------------------------------------------------------------------------------- + @Override + public boolean equals(final Object o) { + if (o == this) return true; + if (!(o instanceof FileDescription)) return false; + final FileDescription other = (FileDescription) o; + return other.canEqual(this) + && Objects.equals(this.getId(), other.getId()); + } + + @Override + public int hashCode() { + final int PRIME = 59; + int result = 1; + final Object $id = this.getId(); + result = result * PRIME + ($id == null ? 43 : $id.hashCode()); + return result; + } + + // Todo + @Override + public String toString() { + if (name != null) { + return name; + } else { + return super.toString(); + } + } + + // ---------------------------------------------------------------------------------- + // Other methods + // ---------------------------------------------------------------------------------- + protected boolean canEqual(final Object other) { + return other instanceof FileDescription; + } + public Path getPath0() { return FileSystems.getDefault().getPath(FILE_ROOT, getSubdirectory(), Long.toString(id)); } @@ -78,85 +183,4 @@ public class FileDescription extends DomainObject { public InputStream getData() throws IOException { return Files.newInputStream(getPath0()); } - - public String getName() { - return name; - } - - // Todo - @Override - public String toString() { - if (name != null) { - return name; - } else { - return super.toString(); - } - } - - @Override - public Long getId() { - return this.id; - } - - public String getMimeType() { - return this.mimeType; - } - - public String getIdentifier() { - return this.identifier; - } - - public User getUploader() { - return this.uploader; - } - - public long getSize() { - return this.size; - } - - public void setId(Long id) { - this.id = id; - } - - public void setName(String name) { - this.name = name; - } - - public void setMimeType(String mimeType) { - this.mimeType = mimeType; - } - - public void setIdentifier(String identifier) { - this.identifier = identifier; - } - - public void setUploader(User uploader) { - this.uploader = uploader; - } - - public void setSize(long size) { - this.size = size; - } - - @Override - public boolean equals(final Object o) { - if (o == this) return true; - if (!(o instanceof FileDescription)) return false; - final FileDescription other = (FileDescription) o; - return other.canEqual(this) - && Objects.equals(this.getId(), other.getId()); - } - - protected boolean canEqual(final Object other) { - return other instanceof FileDescription; - } - - @Override - public int hashCode() { - final int PRIME = 59; - int result = 1; - final Object $id = this.getId(); - result = result * PRIME + ($id == null ? 43 : $id.hashCode()); - return result; - } } diff --git a/core/src/main/java/se/su/dsv/scipro/file/FileReference.java b/core/src/main/java/se/su/dsv/scipro/file/FileReference.java index 34f7ce0beb..4858d090db 100644 --- a/core/src/main/java/se/su/dsv/scipro/file/FileReference.java +++ b/core/src/main/java/se/su/dsv/scipro/file/FileReference.java @@ -9,7 +9,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import java.io.Serializable; -import java.util.*; +import java.util.Objects; /** * A reference to a file. @@ -29,7 +29,7 @@ public class FileReference implements Serializable { private Long id; @ManyToOne(cascade = CascadeType.PERSIST) - @JoinColumn(name = "file_description_id") + @JoinColumn(name = "file_description_id", referencedColumnName = "id") private FileDescription fileDescription; public Long getId() { diff --git a/core/src/main/java/se/su/dsv/scipro/file/ProjectFile.java b/core/src/main/java/se/su/dsv/scipro/file/ProjectFile.java index d63c05d4d0..ba57470626 100644 --- a/core/src/main/java/se/su/dsv/scipro/file/ProjectFile.java +++ b/core/src/main/java/se/su/dsv/scipro/file/ProjectFile.java @@ -1,71 +1,88 @@ package se.su.dsv.scipro.file; +import jakarta.persistence.Basic; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.system.DomainObject; -import jakarta.persistence.*; import java.util.Objects; @Entity @Table(name = "project_file") public class ProjectFile extends DomainObject { + // ---------------------------------------------------------------------------------- + // Basic JPA-mappings + // ---------------------------------------------------------------------------------- @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ManyToOne - private Project project; - + @Basic + @Column(name = "file_source") @Enumerated(EnumType.STRING) private FileSource fileSource = FileSource.FILES; + // ---------------------------------------------------------------------------------- + // JPA-mappings of foreign keys in this table (project_file) referencing other tables. + // ---------------------------------------------------------------------------------- + @ManyToOne + @JoinColumn(name = "project_id", referencedColumnName = "id") + private Project project; + @OneToOne - @JoinColumn(name = "file_reference_id") + @JoinColumn(name = "file_reference_id", referencedColumnName = "id") private FileReference fileReference; + // ---------------------------------------------------------------------------------- + // Properties (Getters and Setters) + // ---------------------------------------------------------------------------------- @Override public Long getId() { return this.id; } - public Project getProject() { - return this.project; - } - - public FileSource getFileSource() { - return this.fileSource; - } - - public FileDescription getFileDescription() { - return this.fileReference.getFileDescription(); - } - public void setId(Long id) { this.id = id; } - public void setProject(Project project) { - this.project = project; + public FileSource getFileSource() { + return this.fileSource; } public void setFileSource(FileSource fileSource) { this.fileSource = fileSource; } - public void setFileReference(FileReference fileReference) { - this.fileReference = fileReference; - } - public FileReference getFileReference() { return this.fileReference; } - @Override - public String toString() { - return "ProjectFile(id=" + this.getId() + ", project=" + this.getProject() + ", fileSource=" + this.getFileSource() + ", fileDescription=" + this.getFileDescription() + ")"; + public void setFileReference(FileReference fileReference) { + this.fileReference = fileReference; } + public Project getProject() { + return this.project; + } + + public void setProject(Project project) { + this.project = project; + } + + // ---------------------------------------------------------------------------------- + // Methods Common To All Objects + // ---------------------------------------------------------------------------------- @Override public boolean equals(final Object o) { if (o == this) return true; @@ -79,12 +96,24 @@ public class ProjectFile extends DomainObject { && Objects.equals(this.getFileDescription(), other.getFileDescription()); } - protected boolean canEqual(final Object other) { - return other instanceof ProjectFile; - } - @Override public int hashCode() { return Objects.hash(this.getId(), this.getProject(), this.getFileSource(), this.getFileDescription()); } + + @Override + public String toString() { + return "ProjectFile(id=" + this.getId() + ", project=" + this.getProject() + ", fileSource=" + this.getFileSource() + ", fileDescription=" + this.getFileDescription() + ")"; + } + + // ---------------------------------------------------------------------------------- + // Other methods + // ---------------------------------------------------------------------------------- + protected boolean canEqual(final Object other) { + return other instanceof ProjectFile; + } + + public FileDescription getFileDescription() { + return this.fileReference.getFileDescription(); + } } diff --git a/core/src/main/java/se/su/dsv/scipro/finalthesis/FinalThesis.java b/core/src/main/java/se/su/dsv/scipro/finalthesis/FinalThesis.java index 894e798a5f..c238089a33 100644 --- a/core/src/main/java/se/su/dsv/scipro/finalthesis/FinalThesis.java +++ b/core/src/main/java/se/su/dsv/scipro/finalthesis/FinalThesis.java @@ -21,50 +21,67 @@ import jakarta.persistence.Table; import java.time.Instant; import java.time.LocalDate; import java.time.ZoneId; -import java.util.*; +import java.util.Date; +import java.util.Objects; @Entity -@Table +@Table(name = "final_thesis") public class FinalThesis extends DomainObject { - public enum Status { - APPROVED, REJECTED, NO_DECISION - } - + // ---------------------------------------------------------------------------------- + // Basic JPA-mappings + // ---------------------------------------------------------------------------------- @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ManyToOne(optional = false) - @JoinColumn(name = "document_reference_id") - private FileReference document; + @Basic + @Column(name = "english_title") + private String englishTitle; - @ManyToOne(optional = true) - @JoinColumn(name = "text_matching_document_reference_id") - private FileReference textMatchingDocument; + @Basic + @Column(name = "swedish_title") + private String swedishTitle; + + @Basic + @Column(name = "status") + @Enumerated(EnumType.STRING) + private Status status = Status.NO_DECISION; + + @Basic + @Column(name = "date_approved") + private Date dateApproved; + + @Basic + @Column(name = "date_rejected") + private Date dateRejected; + + @Basic + @Column(name = "rejection_comment") + private String rejectionComment; @Basic @Column(name = "text_matching_analysis") private String textMatchingAnalysis; + // ---------------------------------------------------------------------------------- + // JPA-mappings of foreign keys in this table (final_thesis) referencing other tables. + // ---------------------------------------------------------------------------------- + @ManyToOne(optional = true) + @JoinColumn(name = "text_matching_document_reference_id", referencedColumnName = "id") + private FileReference textMatchingDocument; + @ManyToOne(optional = false) - @JoinColumn(name = "project_id") + @JoinColumn(name = "document_reference_id", referencedColumnName = "id") + private FileReference document; + + @ManyToOne(optional = false) + @JoinColumn(name = "project_id", referencedColumnName = "id") private Project project; - @Enumerated(EnumType.STRING) - private Status status = Status.NO_DECISION; - - private Date dateApproved; - - private Date dateRejected; - - private String englishTitle; - - private String swedishTitle; - - @Column(name = "rejection_comment") - private String rejectionComment; - + // ---------------------------------------------------------------------------------- + // JPA lifecycle method + // ---------------------------------------------------------------------------------- @PrePersist @PreUpdate void cleanTitle() { @@ -72,6 +89,126 @@ public class FinalThesis extends DomainObject { this.swedishTitle = clean(this.swedishTitle); } + + + // ---------------------------------------------------------------------------------- + // Properties (Getters and Setters) + // ---------------------------------------------------------------------------------- + @Override + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getEnglishTitle() { + return this.englishTitle; + } + + public void setEnglishTitle(String englishTitle) { + this.englishTitle = englishTitle; + } + + public String getSwedishTitle() { + return this.swedishTitle; + } + + public void setSwedishTitle(String swedishTitle) { + this.swedishTitle = swedishTitle; + } + + public Status getStatus() { + return this.status; + } + + public void setStatus(Status status) { + this.status = status; + } + + public Date getDateApproved() { + return dateApproved; + } + + public void setDateApproved(Date dateApproved) { + this.dateApproved = dateApproved; + } + + public Date getDateRejected() { + return dateRejected; + } + + public void setDateRejected(Date dateRejected) { + this.dateRejected = dateRejected; + } + + public String getRejectionComment() { + return rejectionComment; + } + + public void setRejectionComment(String rejectionComment) { + this.rejectionComment = rejectionComment; + } + + public String getTextMatchingAnalysis() { + return textMatchingAnalysis; + } + + public void setTextMatchingAnalysis(String textMatchingAnalysis) { + this.textMatchingAnalysis = textMatchingAnalysis; + } + + public FileReference getTextMatchingDocument() { + return this.textMatchingDocument; + } + + public void setTextMatchingDocument(FileReference textMatchingDocument) { + this.textMatchingDocument = textMatchingDocument; + } + + public FileReference getDocument() { + return this.document; + } + + public void setDocument(FileReference fileDescription) { + this.document = fileDescription; + } + + public Project getProject() { + return this.project; + } + + public void setProject(Project project) { + this.project = project; + } + + // ---------------------------------------------------------------------------------- + // Methods Common To All Objects + // ---------------------------------------------------------------------------------- + @Override + public boolean equals(final Object o) { + if (o == this) return true; + if (!(o instanceof FinalThesis)) return false; + final FinalThesis other = (FinalThesis) o; + return other.canEqual(this) + && Objects.equals(this.getDocument(), other.getDocument()) + && Objects.equals(this.getProject(), other.getProject()); + } + + @Override + public int hashCode() { + return Objects.hash(this.getDocument(), this.getProject()); + } + + @Override + public String toString() { + return "FinalThesis(id=" + this.getId() + ", fileDescription=" + this.getDocument() + ", textMatchingDocument=" + this.getTextMatchingDocument() + ", project=" + this.getProject() + ", status=" + this.getStatus() + ", dateApproved=" + this.getDateApproved() + ", dateRejected=" + this.getDateRejected() + ", englishTitle=" + this.getEnglishTitle() + ", swedishTitle=" + this.getSwedishTitle() + ")"; + } + + // ---------------------------------------------------------------------------------- + // Other methods + // ---------------------------------------------------------------------------------- private String clean(String str) { if (str == null) { return null; @@ -83,125 +220,23 @@ public class FinalThesis extends DomainObject { .trim(); } - @Override - public Long getId() { - return this.id; - } - - public FileReference getDocument() { - return this.document; - } - - public FileReference getTextMatchingDocument() { - return this.textMatchingDocument; - } - - public Project getProject() { - return this.project; - } - - public Status getStatus() { - return this.status; - } - - public String getEnglishTitle() { - return this.englishTitle; - } - - public String getSwedishTitle() { - return this.swedishTitle; - } - - public void setId(Long id) { - this.id = id; - } - - public void setDocument(FileReference fileDescription) { - this.document = fileDescription; - } - - public void setTextMatchingDocument(FileReference textMatchingDocument) { - this.textMatchingDocument = textMatchingDocument; - } - - public void setProject(Project project) { - this.project = project; - } - - public void setStatus(Status status) { - this.status = status; - } - - public void setDateApproved(Date dateApproved) { - this.dateApproved = dateApproved; - } - - public void setDateRejected(Date dateRejected) { - this.dateRejected = dateRejected; - } - - public void setEnglishTitle(String englishTitle) { - this.englishTitle = englishTitle; - } - - public void setSwedishTitle(String swedishTitle) { - this.swedishTitle = swedishTitle; - } - - public String getTextMatchingAnalysis() { - return textMatchingAnalysis; - } - - public void setTextMatchingAnalysis(String textMatchingAnalysis) { - this.textMatchingAnalysis = textMatchingAnalysis; - } - - public String getRejectionComment() { - return rejectionComment; - } - - public void setRejectionComment(String rejectionComment) { - this.rejectionComment = rejectionComment; - } - - @Override - public String toString() { - return "FinalThesis(id=" + this.getId() + ", fileDescription=" + this.getDocument() + ", textMatchingDocument=" + this.getTextMatchingDocument() + ", project=" + this.getProject() + ", status=" + this.getStatus() + ", dateApproved=" + this.getDateApproved() + ", dateRejected=" + this.getDateRejected() + ", englishTitle=" + this.getEnglishTitle() + ", swedishTitle=" + this.getSwedishTitle() + ")"; - } - - @Override - public boolean equals(final Object o) { - if (o == this) return true; - if (!(o instanceof FinalThesis)) return false; - final FinalThesis other = (FinalThesis) o; - return other.canEqual(this) - && Objects.equals(this.getDocument(), other.getDocument()) - && Objects.equals(this.getProject(), other.getProject()); - } - protected boolean canEqual(final Object other) { return other instanceof FinalThesis; } - @Override - public int hashCode() { - return Objects.hash(this.getDocument(), this.getProject()); - } - - public boolean isRejected() { - return getStatus() == Status.REJECTED; - } - - public Date getDateRejected() { - return dateRejected; - } - - public Date getDateApproved() { - return dateApproved; - } - public LocalDate getUploadDate() { Instant instant = document.getFileDescription().getDateCreated().toInstant(); return instant.atZone(ZoneId.systemDefault()).toLocalDate(); } + + public boolean isRejected() { + return getStatus() == Status.REJECTED; + } + + // ---------------------------------------------------------------------------------- + // Nested types + // ---------------------------------------------------------------------------------- + public enum Status { + APPROVED, REJECTED, NO_DECISION + } } diff --git a/core/src/main/resources/db/migration/V389__harmonize_table_attribute_name.sql b/core/src/main/resources/db/migration/V389__harmonize_table_attribute_name.sql index 42fe6ed70c..6a115da106 100644 --- a/core/src/main/resources/db/migration/V389__harmonize_table_attribute_name.sql +++ b/core/src/main/resources/db/migration/V389__harmonize_table_attribute_name.sql @@ -2613,8 +2613,105 @@ alter table `grade` foreign key (reported_by_user_id) references user (id) on delete cascade on update cascade; +/* + * Step 17: file_reference & file_description, FinalThesis and project_file + */ +-- table: file_description +alter table `file_description` drop foreign key `file_description_user`; + +alter table `file_description` drop key `file_description_user`; +alter table `file_description` drop key `file_description_identifier_index`; + +alter table `file_description` change `version` `version` int(4) not null default 0 after `last_modified`; +alter table `file_description` change `name` `name` varchar(255) default null after `version`; +alter table `file_description` change `mimeType` `mime_type` varchar(255) default null after `name`; +alter table `file_description` change `size` `size` bigint(20) default null after `mime_type`; +alter table `file_description` change `identifier` `file_identifier` varchar(255) default null after `size`; +alter table `file_description` change `type` `type` varchar(255) default null after `file_identifier`; +alter table `file_description` change `userId` `user_id` bigint(20) default null after `type`; + +alter table `file_description` + add constraint fk_file_description_user_id + foreign key (user_id) references user (id) + on delete cascade on update cascade; + +-- table: file_reference + +alter table file_reference drop foreign key `FK_file_reference_file_description`; + +alter table file_reference drop key `FK_file_reference_file_description`; + +alter table file_reference + add constraint fk_file_reference_file_description_id + foreign key (file_description_id) references file_description (id) + on delete cascade on update cascade; + +-- table: FinalThesis + +alter table FinalThesis drop foreign key `FK_final_thesis_text_matching_document_reference`; +alter table FinalThesis drop foreign key `FK_final_thesis_project`; +alter table FinalThesis drop foreign key `FK_final_thesis_document_reference`; + +alter table FinalThesis drop key `FK_final_thesis_text_matching_document_reference`; +alter table FinalThesis drop key `FK_final_thesis_project`; + +rename table FinalThesis to `final_thesis`; + +alter table `final_thesis` change `englishTitle` `english_title` varchar(255) default null after `version`; +alter table `final_thesis` change `swedishTitle` `swedish_title` varchar(255) default null after `english_title`; +alter table `final_thesis` change `status` `status` varchar(32) not null after `swedish_title`; +alter table `final_thesis` change `dateApproved` `date_approved` date default null after `status`; +alter table `final_thesis` change `dateRejected` `date_rejected` date default null after `date_approved`; +alter table `final_thesis` change `rejection_comment` `rejection_comment` text default null after `date_rejected`; +alter table `final_thesis` change `text_matching_analysis` `text_matching_analysis` text default null after `rejection_comment`; +alter table `final_thesis` change `text_matching_document_reference_id` `text_matching_document_reference_id` bigint(20) default null after `text_matching_analysis`; +alter table `final_thesis` change `project_id` `project_id` bigint(20) not null after `document_reference_id`; + +alter table `final_thesis` + add constraint fk_final_thesis_text_matching_document_reference_id + foreign key (text_matching_document_reference_id) references file_reference (id) + on delete cascade on update cascade; + +alter table `final_thesis` + add constraint fk_final_thesis_document_reference_id + foreign key (document_reference_id) references file_reference (id) + on delete cascade on update cascade; + +alter table `final_thesis` + add constraint fk_final_thesis_project_id + foreign key (project_id) references project (id) + on delete cascade on update cascade; + +-- table: project_file + +alter table `project_file` drop foreign key project_file_ibfk_2; +alter table `project_file` drop foreign key FK_project_file_file; + +alter table `project_file` drop key FK_project_file_file; +alter table `project_file` drop key FK_project_file_project; + +alter table `project_file` change `fileSource` `file_source` varchar(255) not null after `version`; +alter table `project_file` change `project_id` `project_id` bigint(20) not null after `file_reference_id`; + +alter table `project_file` + add constraint fk_project_file_file_reference_id + foreign key (file_reference_id) references file_reference (id) + on delete cascade on update cascade; + +alter table `project_file` + add constraint fk_project_file_project_id + foreign key (project_id) references project (id) + on delete cascade on update cascade; + +/* + * Step 18: Decision & ReviewerApproval + */ + +-- todo: table: Decision + +-- todo: table: ReviewerApproval /* Useful SQL