diff --git a/src/main/java/org/orph2020/pst/apiimpl/rest/ProposalDocumentStore.java b/src/main/java/org/orph2020/pst/apiimpl/rest/ProposalDocumentStore.java index 12da420..5cdf88f 100644 --- a/src/main/java/org/orph2020/pst/apiimpl/rest/ProposalDocumentStore.java +++ b/src/main/java/org/orph2020/pst/apiimpl/rest/ProposalDocumentStore.java @@ -3,6 +3,7 @@ import jakarta.enterprise.context.RequestScoped; import org.apache.commons.io.FileUtils; import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.ivoa.dm.proposal.prop.SupportingDocument; import java.io.File; import java.io.FileWriter; @@ -11,10 +12,15 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; +/** + * This is a convenience class bean to help with file I/O and bookkeeping for the document store + * of individual proposals + */ @RequestScoped public class ProposalDocumentStore { @@ -61,14 +67,22 @@ public void removeStorePath(String proposalDirectory) throws IOException { } /** - * Copies the contents of directory 'source' to the directory 'destination', this includes - * subdirectories and files - * @param source a string representing the source directory - * @param destination a string representing the destination directory + * Copies the contents of directory 'source' to the directory 'destination', this includes subdirectories + * and files (intention is that 'source' and 'destination' are unique identifiers for proposals) + * @param source a string representing the source directory or path (not including the store root) + * @param destination a string representing the destination directory or path (not including the store root) + * @param supportingDocuments list of supporting documents from the CLONED proposal to update + * their 'locations' to use the 'destination' path - can be empty * @throws IOException if copy operation fails */ - public void copyStore(String source, String destination) throws IOException { + public void copyStore(String source, String destination, List supportingDocuments) + throws IOException { FileUtils.copyDirectory(fetchFile(source), fetchFile(destination)); + supportingDocuments.forEach(s -> + s.setLocation(s.getLocation().replace( + "proposals/" + source,"proposals/" + destination + )) + ); } diff --git a/src/main/java/org/orph2020/pst/apiimpl/rest/ProposalResource.java b/src/main/java/org/orph2020/pst/apiimpl/rest/ProposalResource.java index c33b411..1a1e1fe 100644 --- a/src/main/java/org/orph2020/pst/apiimpl/rest/ProposalResource.java +++ b/src/main/java/org/orph2020/pst/apiimpl/rest/ProposalResource.java @@ -207,19 +207,16 @@ public ObservingProposal cloneObservingProposal(@PathParam("proposalCode") long //copy the document store for the new, cloned proposal try { - proposalDocumentStore.copyStore(prop.getId().toString(), clonedProp.getId().toString()); + proposalDocumentStore.copyStore( + prop.getId().toString(), + clonedProp.getId().toString(), + clonedProp.getSupportingDocuments() + ); } catch (IOException e) { throw new WebApplicationException(e); } - //clonedProp now has SupportingDocuments with 'locations' indicating the original proposal, - //these need to be updated with the clone's id. - clonedProp.getSupportingDocuments().forEach( - s -> s.setLocation(s.getLocation().replace( - "proposals/" + prop.getId(),"proposals/" + clonedProp.getId())) - ); - return clonedProp; } diff --git a/src/main/java/org/orph2020/pst/apiimpl/rest/SubmittedProposalResource.java b/src/main/java/org/orph2020/pst/apiimpl/rest/SubmittedProposalResource.java index 957d511..9f81e86 100644 --- a/src/main/java/org/orph2020/pst/apiimpl/rest/SubmittedProposalResource.java +++ b/src/main/java/org/orph2020/pst/apiimpl/rest/SubmittedProposalResource.java @@ -1,6 +1,7 @@ package org.orph2020.pst.apiimpl.rest; +import jakarta.inject.Inject; import jakarta.persistence.Query; import jakarta.persistence.TypedQuery; import jakarta.transaction.Transactional; @@ -18,6 +19,7 @@ import org.orph2020.pst.common.json.ObjectIdentifier; import org.orph2020.pst.common.json.ProposalSynopsis; +import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -27,6 +29,9 @@ @Produces(MediaType.APPLICATION_JSON) public class SubmittedProposalResource extends ObjectResourceBase{ + @Inject + ProposalDocumentStore proposalDocumentStore; + @GET @Operation(summary = "get the identifiers for the SubmittedProposals in the ProposalCycle") public List getSubmittedProposals( @@ -123,6 +128,21 @@ public ProposalSynopsis submitProposal(@PathParam("cycleCode") long cycleId, Sub submittedProposal.updateClonedReferences(); em.persist(submittedProposal); submittedProposal.addToRelatedProposals(new RelatedProposal(proposal)); + + //**** clone the document store of the original proposal **** + //in essence creates a snapshot of the documents at the point of submission + try { + proposalDocumentStore.copyStore( + proposal.getId().toString(), + submittedProposal.getId().toString(), + submittedProposal.getSupportingDocuments() + ); + } catch (IOException e) { + // if we can't copy the store then we need to rollback + throw new WebApplicationException(e); + } + //************************************************************ + cycle.addToSubmittedProposals(submittedProposal); em.merge(cycle);