From b42c8fb356c6bf3d6bfd1bd55b8c5ee1d859e99c Mon Sep 17 00:00:00 2001 From: rkv Date: Thu, 11 Apr 2013 07:48:38 +0000 Subject: [PATCH] Added checking of a document state when replacing a source file. Exception is thrown now if the state is not Extern or inWork. --- .../src/conf/log-messages.properties | 1 + .../src/conf/log-messages_en.properties | 1 + .../common/properties/MessageKeyEnum.java | 4 + .../org/splat/service/PublicationService.java | 8 +- .../splat/service/PublicationServiceImpl.java | 70 +++++++----- .../splat/service/TestPublicationService.java | 101 +++++++++++++++--- 6 files changed, 142 insertions(+), 43 deletions(-) diff --git a/Workspace/Siman-Common/src/conf/log-messages.properties b/Workspace/Siman-Common/src/conf/log-messages.properties index 17eee64..9c63877 100644 --- a/Workspace/Siman-Common/src/conf/log-messages.properties +++ b/Workspace/Siman-Common/src/conf/log-messages.properties @@ -20,5 +20,6 @@ SCT-000002=Simulation context type name could not be blank DCT-000001=Document type "{0}" already exists DCT-000002=Can not delete the document "{0}" because it is used by other documents. DCT-000003=Can not save a document in {0} state. Check the validation cycle. +DCT-000004=The source file can not be replaced. The document must be external or in In-Work state. PRM-000001=Parameter {0} is invalid with value: {1} IDT-000001=Incompatible data: X-units or Y-units are not the same for all comparable studies. \ No newline at end of file diff --git a/Workspace/Siman-Common/src/conf/log-messages_en.properties b/Workspace/Siman-Common/src/conf/log-messages_en.properties index 17eee64..9c63877 100644 --- a/Workspace/Siman-Common/src/conf/log-messages_en.properties +++ b/Workspace/Siman-Common/src/conf/log-messages_en.properties @@ -20,5 +20,6 @@ SCT-000002=Simulation context type name could not be blank DCT-000001=Document type "{0}" already exists DCT-000002=Can not delete the document "{0}" because it is used by other documents. DCT-000003=Can not save a document in {0} state. Check the validation cycle. +DCT-000004=The source file can not be replaced. The document must be external or in In-Work state. PRM-000001=Parameter {0} is invalid with value: {1} IDT-000001=Incompatible data: X-units or Y-units are not the same for all comparable studies. \ No newline at end of file diff --git a/Workspace/Siman-Common/src/org/splat/common/properties/MessageKeyEnum.java b/Workspace/Siman-Common/src/org/splat/common/properties/MessageKeyEnum.java index 5faf78f..f8b0840 100644 --- a/Workspace/Siman-Common/src/org/splat/common/properties/MessageKeyEnum.java +++ b/Workspace/Siman-Common/src/org/splat/common/properties/MessageKeyEnum.java @@ -101,6 +101,10 @@ public enum MessageKeyEnum { * DCT-000003=Can not save a document in {0} state. Check the validation cycle. */ DCT_000003("DCT-000003"), + /** + * DCT-000004=The source file can not be replaced. The document must be external or in In-Work state. + */ + DCT_000004("DCT-000004"), /** * Parameter {0} is invalid with value: {1}. */ diff --git a/Workspace/Siman-Common/src/org/splat/service/PublicationService.java b/Workspace/Siman-Common/src/org/splat/service/PublicationService.java index 0c9d368..1bc4082 100644 --- a/Workspace/Siman-Common/src/org/splat/service/PublicationService.java +++ b/Workspace/Siman-Common/src/org/splat/service/PublicationService.java @@ -24,6 +24,7 @@ import org.splat.dal.bo.som.ProjectElement; import org.splat.dal.bo.som.Publication; import org.splat.dal.bo.som.Study; import org.splat.dal.bo.som.Timestamp; +import org.splat.exception.IncompatibleDataException; import org.splat.exception.InvalidParameterException; import org.splat.kernel.InvalidPropertyException; import org.splat.kernel.MismatchException; @@ -252,7 +253,8 @@ public interface PublicationService { throws InvalidPropertyException; /** - * Replace the document source file. + * Replace the document source file. The document status must be inWORK or
+ * EXTERN to be able to replace the source file. * * @param pub * document publication @@ -261,9 +263,11 @@ public interface PublicationService { * @param modifTime * modification time * @return true if succeeded otherwise return false + * @throws IncompatibleDataException + * if the document status is not valid for replacing */ boolean replace(final Publication pub, final File newFile, - final Date modifTime); + final Date modifTime) throws IncompatibleDataException; /** * Create "Converts" relation for the given document publication and format. diff --git a/Workspace/Siman-Common/src/org/splat/service/PublicationServiceImpl.java b/Workspace/Siman-Common/src/org/splat/service/PublicationServiceImpl.java index 3e0ffac..e2693f6 100644 --- a/Workspace/Siman-Common/src/org/splat/service/PublicationServiceImpl.java +++ b/Workspace/Siman-Common/src/org/splat/service/PublicationServiceImpl.java @@ -38,6 +38,7 @@ import org.splat.dal.bo.som.ValidationStep; import org.splat.dal.dao.som.ProjectElementDAO; import org.splat.dal.dao.som.PublicationDAO; import org.splat.dal.dao.som.TimestampDAO; +import org.splat.exception.IncompatibleDataException; import org.splat.exception.InvalidParameterException; import org.splat.kernel.InvalidPropertyException; import org.splat.kernel.MismatchException; @@ -161,12 +162,7 @@ public class PublicationServiceImpl implements PublicationService { step, dprop.setName(doctitle).setType(type).setFormat( table[table.length - 1]).setAuthor(user)); - updir = addoc.getSourceFile().asFile(); - if (LOG.isInfoEnabled()) { - LOG.info("Moving \"" + upfile.getAbsolutePath() + "\" to \"" - + updir.getPath() + "\"."); - } - upfile.renameTo(updir); + moveFile(upfile, addoc); try { saveAs(addoc, docstate); // May throw FileNotFound if rename was not done } catch (FileNotFoundException saverror) { @@ -181,12 +177,7 @@ public class PublicationServiceImpl implements PublicationService { } addoc = getStepService().assignDocument(step, dprop.setReference(reference).setName(doctitle)); - updir = addoc.getSourceFile().asFile(); - if (LOG.isInfoEnabled()) { - LOG.info("Moving \"" + upfile.getName() + "\" to \"" - + updir.getPath() + "\"."); - } - upfile.renameTo(updir); + moveFile(upfile, addoc); try { if (version.length() > 0) { saveAs(addoc, new Revision(version)); @@ -214,6 +205,23 @@ public class PublicationServiceImpl implements PublicationService { return addoc; } + /** + * Move a file into the repository as a source file of the document. + * + * @param upfile + * the uploaded file to move + * @param addoc + * the document + */ + private void moveFile(final File upfile, final Publication addoc) { + File updir = addoc.getSourceFile().asFile(); + if (LOG.isInfoEnabled()) { + LOG.info("Moving \"" + upfile.getAbsolutePath() + "\" to \"" + + updir.getPath() + "\"."); + } + upfile.renameTo(updir); + } + /** * {@inheritDoc} * @@ -246,12 +254,7 @@ public class PublicationServiceImpl implements PublicationService { } next = getStepService().versionDocument(step, current, dprop.setAuthor(user)); - updir = next.getSourceFile().asFile(); - if (LOG.isInfoEnabled()) { - LOG.info("Moving \"" + upfile.getName() + "\" to \"" - + updir.getPath() + "\"."); - } - upfile.renameTo(updir); + moveFile(upfile, next); try { if (docver.length() == 0) { // Importation of a foreign document @@ -744,19 +747,22 @@ public class PublicationServiceImpl implements PublicationService { getDocumentService().rename(aPublication.value(), title); } - /** + /** * {@inheritDoc} + * * @see org.splat.service.PublicationService#getDocToCompareDTO(long) */ @Transactional(readOnly = true) @Override - public DocToCompareDTO getDocToCompareDTO(final long publicationId) throws InvalidParameterException { + public DocToCompareDTO getDocToCompareDTO(final long publicationId) + throws InvalidParameterException { DocToCompareDTO res = new DocToCompareDTO(); Publication pub = _publicationDAO.get(Long.valueOf(publicationId)); - if(pub == null) { - throw new InvalidParameterException("id", String.valueOf(publicationId)); + if (pub == null) { + throw new InvalidParameterException("id", String + .valueOf(publicationId)); } - + res.setDocumentTitle(pub.value().getTitle()); res.setPathToFile(pub.value().getFile().asFile().getAbsolutePath()); res.setScenarioTitle(pub.getOwner().getTitle()); @@ -976,19 +982,25 @@ public class PublicationServiceImpl implements PublicationService { _userService = userService; } - /** + /** * {@inheritDoc} + * * @see org.splat.service.PublicationService#replace(long, java.io.File) */ @Override @Transactional public boolean replace(final Publication pub, final File newFile, - final Date modifTime) { - Document doc = getDocumentService().selectDocument(pub.value().getIndex()); + final Date modifTime) throws IncompatibleDataException { + if (!(ProgressState.EXTERN.equals(pub.getProgressState()) || ProgressState.inWORK + .equals(pub.getProgressState()))) { + throw new IncompatibleDataException(MessageKeyEnum.DCT_000004 + .toString()); + } + Document doc = getDocumentService().selectDocument( + pub.value().getIndex()); if (LOG.isInfoEnabled()) { LOG.info("Moving \"" + newFile.getName() + "\" to \"" - + doc.getSourceFile().asFile().getAbsolutePath() - + "\"."); + + doc.getSourceFile().asFile().getAbsolutePath() + "\"."); } // Save a temporary copy of the original file as .backup String oldFilePath = doc.getSourceFile().asFile().getAbsolutePath(); @@ -997,7 +1009,7 @@ public class PublicationServiceImpl implements PublicationService { oldFile.renameTo(backupFile); boolean res = newFile.renameTo(oldFile); if (res) { - // Delete the temporary copy of the old file + // Delete the temporary copy of the old file // if the new one is moved into the repository. backupFile.delete(); // Update the document modification date. diff --git a/Workspace/Siman-Common/src/test/splat/service/TestPublicationService.java b/Workspace/Siman-Common/src/test/splat/service/TestPublicationService.java index 98c5620..04f2b07 100644 --- a/Workspace/Siman-Common/src/test/splat/service/TestPublicationService.java +++ b/Workspace/Siman-Common/src/test/splat/service/TestPublicationService.java @@ -42,6 +42,7 @@ import org.splat.dal.dao.som.Database; import org.splat.dal.dao.som.ScenarioDAO; import org.splat.dal.dao.som.StudyDAO; import org.splat.exception.BusinessException; +import org.splat.exception.IncompatibleDataException; import org.splat.kernel.InvalidPropertyException; import org.splat.kernel.MissedPropertyException; import org.splat.kernel.MultiplyDefinedException; @@ -638,18 +639,22 @@ public class TestPublicationService extends BaseTest { * Create a study and a scenario with documents and try to replace source files.
*

* Action :
- * 1. call the method for a document published in the study step.
- * 2. call the method for a document published in the scenario step.
+ * 1. call the method for a document in the status inDRAFT.
+ * 2. call the method for a document in the status inCHECK.
+ * 3. call the method for a document in the status APPROVED.
+ * 4. call the method for an Extern document published in the study step.
+ * 5. call the method for an inWork document published in the scenario step.
* Test data :
* no input parameters
- * no input parameters
* * Outcome results:
* *
    - *
  • The document source file content in the study must be replaced.
    + *
  • 1-3: Exception must be thrown. The document source file content must not be replaced.
    + *
  • + *
  • 4: The document source file content in the study must be replaced.
    *
  • - *
  • The document source file content in the scenario must be replaced.
    + *
  • 5: The document source file content in the scenario must be replaced.
    *
  • *
*
@@ -693,6 +698,15 @@ public class TestPublicationService extends BaseTest { Map stSteps = _projectElementService .getStepsMap(aStudy); org.splat.som.Step aStep = stSteps.get(1); + Publication pub0inDraft = addDoc(aStudy, aStep, "document0indraft", + dtype); + pub0inDraft.value().setProgressState(ProgressState.inDRAFT); + Publication pub0inCheck = addDoc(aStudy, aStep, "document0incheck", + dtype); + pub0inCheck.value().setProgressState(ProgressState.inCHECK); + Publication pub0approved = addDoc(aStudy, aStep, "document0approved", + dtype); + pub0approved.value().setProgressState(ProgressState.APPROVED); Publication pub1 = addDoc(aStudy, aStep, "document1", dtype); String format1 = pub1.value().getFormat(); ht.flush(); @@ -708,28 +722,70 @@ public class TestPublicationService extends BaseTest { String format2 = spub1.value().getFormat(); ht.flush(); - Long id1 = pub1.value().getIndex(), id2 = spub1.value().getIndex(); + // Remember documents ids + Long id0inDraft = pub0inDraft.value().getIndex(), id0inCheck = pub0inCheck + .value().getIndex(), id0approved = pub0approved.value() + .getIndex(), id1 = pub1.value().getIndex(), id2 = spub1.value() + .getIndex(); ht.evict(scen); ht.evict(scen.getOwnerStudy()); ht.clear(); - Assert.assertTrue(ht.find("from File").size() >= 2, + Assert.assertTrue(ht.find("from File").size() >= 3, "Files were not created in the database."); Date modifTime = Calendar.getInstance().getTime(); - // TEST CALL: Replace a file in the study step aStudy = _studyService.selectStudy(studyId); - Publication pub = aStudy.getDocums().toArray(new Publication[] {})[0]; - File newFile = new File(getDownloadPath(goodUser) + "replaced1.ddd"); + File newFile = new File(getDownloadPath(goodUser) + "replaced0.ddd"); + createFile(newFile.getAbsolutePath()); + + // TEST CALL: Try to replace a file for inDraft document + Publication pub = getPublicationByDocId(aStudy, id0inDraft); + try { + _publicationService.replace(pub, newFile, modifTime); + Assert + .fail("IncompatibleDataException is expected for a doucment in the status " + + pub.getProgressState().name()); + } catch (IncompatibleDataException e) { + LOG.debug("Expected exception: ", e); + } + ht.flush(); + // TEST CALL: Try to replace a file for inCheck document + pub = getPublicationByDocId(aStudy, id0inCheck); + try { + _publicationService.replace(pub, newFile, modifTime); + Assert + .fail("IncompatibleDataException is expected for a doucment in the status " + + pub.getProgressState().name()); + } catch (IncompatibleDataException e) { + LOG.debug("Expected exception: ", e); + } + ht.flush(); + // TEST CALL: Try to replace a file for Approved document + pub = getPublicationByDocId(aStudy, id0approved); + try { + _publicationService.replace(pub, newFile, modifTime); + Assert + .fail("IncompatibleDataException is expected for a doucment in the status " + + pub.getProgressState().name()); + } catch (IncompatibleDataException e) { + LOG.debug("Expected exception: ", e); + } + ht.flush(); + newFile.delete(); + + // TEST CALL: Replace a file in the study step + pub = getPublicationByDocId(aStudy, id1); + newFile = new File(getDownloadPath(goodUser) + "replaced1.ddd"); createFile(newFile.getAbsolutePath()); Assert.assertTrue(_publicationService.replace(pub, newFile, modifTime)); ht.flush(); // TEST CALL: Replace a file in the scenario step scen = aStudy.getScenariiList().get(0); - pub = scen.getDocums().toArray(new Publication[] {})[0]; + pub = getPublicationByDocId(scen, id2); newFile = new File(getDownloadPath(goodUser) + "replaced2.ddd"); createFile(newFile.getAbsolutePath()); Assert.assertTrue(_publicationService.replace(pub, newFile, modifTime)); @@ -752,11 +808,32 @@ public class TestPublicationService extends BaseTest { Assert.assertEquals(doc.getFile().getFormat(), format2); Assert.assertTrue(txt.contains("replaced2.ddd")); Assert.assertEquals(doc.getLastModificationDate(), modifTime); - + rollbackNestedTransaction(); LOG.debug(">>>>> END testReplace()"); } + /** + * Find a document publication in the project element. + * + * @param projElem + * the project element to scan + * @param docId + * the document id + * @return the document publication if found, otherwise return null + */ + private Publication getPublicationByDocId(final ProjectElement projElem, + final Long docId) { + Publication res = null; + for (Publication pub : projElem.getDocums()) { + if (docId.equals(pub.value().getIndex())) { + res = pub; + break; + } + } + return res; + } + /** * Get file content as a string. * -- 2.39.2