From 63fc0b5e2569beea55e1690464869e3d18625540 Mon Sep 17 00:00:00 2001 From: qqmyers Date: Thu, 26 May 2022 16:08:37 -0400 Subject: [PATCH 1/6] archival status UI with single-version semantics --- .../edu/harvard/iq/dataverse/DatasetPage.java | 61 +++++++++++++++++++ src/main/java/propertyFiles/Bundle.properties | 6 ++ src/main/webapp/dataset-versions.xhtml | 21 ++++++- 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index b9a34dac2ea..d6038b2fe0b 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -63,6 +63,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -5561,6 +5563,65 @@ public void archiveVersion(Long id) { } } } + + public boolean isArchivable() { + String className = settingsWrapper.getValueForKey(SettingsServiceBean.Key.ArchiverClassName, null); + if (className != null) { + try { + Class clazz = Class.forName(className); + Method m = clazz.getMethod("isArchivable", Dataset.class, SettingsWrapper.class); + Object[] params = { dataset, settingsWrapper }; + return (Boolean) m.invoke(null, params); + } catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException | NoSuchMethodException | SecurityException e) { + logger.warning("Failed to call is Archivable on configured archiver class: " + className); + e.printStackTrace(); + } + } + return false; + } + + public boolean isVersionArchivable() { + // If this dataset isn't in an archivable collection return false + if (isArchivable()) { + boolean checkForArchivalCopy = false; + // Otherwise, we need to know if the archiver is single-version-only + // If it is, we have to check for an existing archived version to answer the + // question + String className = settingsWrapper.getValueForKey(SettingsServiceBean.Key.ArchiverClassName, null); + if (className != null) { + try { + Class clazz = Class.forName(className); + Method m = clazz.getMethod("isSingleVersion", SettingsWrapper.class); + Object[] params = { settingsWrapper }; + checkForArchivalCopy = (Boolean) m.invoke(null, params); + } catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException | NoSuchMethodException | SecurityException e) { + logger.warning("Failed to call is Archivable on configured archiver class: " + className); + e.printStackTrace(); + } + if (checkForArchivalCopy) { + // If we have to check (single version archiving), we can't allow archiving if + // one version is already archived (or attempted - any non-null status) + return !isSomeVersionArchived(); + } + // If we allow multiple versions or didn't find one that has had archiving run + // on it, we can archive, so return true + return true; + } + } + //not in an archivable collection + return false; + } + + public boolean isSomeVersionArchived() { + for (DatasetVersion dv : dataset.getVersions()) { + if (dv.getArchivalCopyLocation() != null) { + return true; + } + } + return false; + } private static Date getFileDateToCompare(FileMetadata fileMetadata) { DataFile datafile = fileMetadata.getDataFile(); diff --git a/src/main/java/propertyFiles/Bundle.properties b/src/main/java/propertyFiles/Bundle.properties index a7c40be7ec8..87c8736ff04 100644 --- a/src/main/java/propertyFiles/Bundle.properties +++ b/src/main/java/propertyFiles/Bundle.properties @@ -1868,6 +1868,12 @@ file.dataFilesTab.versions.headers.summary=Summary file.dataFilesTab.versions.headers.contributors=Contributors file.dataFilesTab.versions.headers.contributors.withheld=Contributor name(s) withheld file.dataFilesTab.versions.headers.published=Published on +file.dataFilesTab.versions.headers.archived=Archival Status +file.dataFilesTab.versions.headers.archived.success=Archived +file.dataFilesTab.versions.headers.archived.pending=Pending +file.dataFilesTab.versions.headers.archived.failure=Failed +file.dataFilesTab.versions.headers.archived.notarchived=Not Archived +file.dataFilesTab.versions.headers.archived.submit=Submit file.dataFilesTab.versions.viewDiffBtn=View Differences file.dataFilesTab.versions.citationMetadata=Citation Metadata: file.dataFilesTab.versions.added=Added diff --git a/src/main/webapp/dataset-versions.xhtml b/src/main/webapp/dataset-versions.xhtml index 936c43d07a7..ddd305c50f7 100644 --- a/src/main/webapp/dataset-versions.xhtml +++ b/src/main/webapp/dataset-versions.xhtml @@ -131,7 +131,7 @@ - + @@ -147,6 +147,25 @@ + + + + + + + + + + + + + + + + + + From 193f906193d17b2cc38ee7fc5aa89a6e46659730 Mon Sep 17 00:00:00 2001 From: qqmyers Date: Fri, 22 Jul 2022 15:29:57 -0400 Subject: [PATCH 2/6] add caching per review --- .../edu/harvard/iq/dataverse/DatasetPage.java | 93 +++++++++++-------- 1 file changed, 53 insertions(+), 40 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index 6ccca16ee11..c2d8f0a90d2 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -345,6 +345,10 @@ public void setSelectedHostDataverse(Dataverse selectedHostDataverse) { private boolean versionHasTabular = false; private boolean showIngestSuccess; + + private Boolean archivable = null; + private Boolean versionArchivable = null; + private Boolean someVersionArchived = null; public boolean isShowIngestSuccess() { return showIngestSuccess; @@ -5572,62 +5576,71 @@ public void archiveVersion(Long id) { } public boolean isArchivable() { - String className = settingsWrapper.getValueForKey(SettingsServiceBean.Key.ArchiverClassName, null); - if (className != null) { - try { - Class clazz = Class.forName(className); - Method m = clazz.getMethod("isArchivable", Dataset.class, SettingsWrapper.class); - Object[] params = { dataset, settingsWrapper }; - return (Boolean) m.invoke(null, params); - } catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException - | InvocationTargetException | NoSuchMethodException | SecurityException e) { - logger.warning("Failed to call is Archivable on configured archiver class: " + className); - e.printStackTrace(); - } - } - return false; - } - - public boolean isVersionArchivable() { - // If this dataset isn't in an archivable collection return false - if (isArchivable()) { - boolean checkForArchivalCopy = false; - // Otherwise, we need to know if the archiver is single-version-only - // If it is, we have to check for an existing archived version to answer the - // question + if (archivable == null) { String className = settingsWrapper.getValueForKey(SettingsServiceBean.Key.ArchiverClassName, null); if (className != null) { try { Class clazz = Class.forName(className); - Method m = clazz.getMethod("isSingleVersion", SettingsWrapper.class); - Object[] params = { settingsWrapper }; - checkForArchivalCopy = (Boolean) m.invoke(null, params); + Method m = clazz.getMethod("isArchivable", Dataset.class, SettingsWrapper.class); + Object[] params = { dataset, settingsWrapper }; + archivable = ((Boolean) m.invoke(null, params) == true); } catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { logger.warning("Failed to call is Archivable on configured archiver class: " + className); e.printStackTrace(); } - if (checkForArchivalCopy) { - // If we have to check (single version archiving), we can't allow archiving if - // one version is already archived (or attempted - any non-null status) - return !isSomeVersionArchived(); + } + archivable = false; + } + return archivable; + } + + public boolean isVersionArchivable() { + if (versionArchivable == null) { + // If this dataset isn't in an archivable collection return false + if (isArchivable()) { + boolean checkForArchivalCopy = false; + // Otherwise, we need to know if the archiver is single-version-only + // If it is, we have to check for an existing archived version to answer the + // question + String className = settingsWrapper.getValueForKey(SettingsServiceBean.Key.ArchiverClassName, null); + if (className != null) { + try { + Class clazz = Class.forName(className); + Method m = clazz.getMethod("isSingleVersion", SettingsWrapper.class); + Object[] params = { settingsWrapper }; + checkForArchivalCopy = (Boolean) m.invoke(null, params); + } catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException | NoSuchMethodException | SecurityException e) { + logger.warning("Failed to call is Archivable on configured archiver class: " + className); + e.printStackTrace(); + } + if (checkForArchivalCopy) { + // If we have to check (single version archiving), we can't allow archiving if + // one version is already archived (or attempted - any non-null status) + versionArchivable = !isSomeVersionArchived(); + } + // If we allow multiple versions or didn't find one that has had archiving run + // on it, we can archive, so return true + versionArchivable = true; } - // If we allow multiple versions or didn't find one that has had archiving run - // on it, we can archive, so return true - return true; } + // not in an archivable collection + versionArchivable = false; } - //not in an archivable collection - return false; + return versionArchivable; } - + public boolean isSomeVersionArchived() { - for (DatasetVersion dv : dataset.getVersions()) { - if (dv.getArchivalCopyLocation() != null) { - return true; + if (someVersionArchived == null) { + for (DatasetVersion dv : dataset.getVersions()) { + if (dv.getArchivalCopyLocation() != null) { + someVersionArchived = true; + } } + someVersionArchived = false; } - return false; + return someVersionArchived; } private static Date getFileDateToCompare(FileMetadata fileMetadata) { From 91f492dd46e2a5e9bcb2897e960fd9d7b404e843 Mon Sep 17 00:00:00 2001 From: qqmyers Date: Fri, 22 Jul 2022 15:31:07 -0400 Subject: [PATCH 3/6] remove done todo --- src/main/webapp/dataset-versions.xhtml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/webapp/dataset-versions.xhtml b/src/main/webapp/dataset-versions.xhtml index ddd305c50f7..f22eb449c6a 100644 --- a/src/main/webapp/dataset-versions.xhtml +++ b/src/main/webapp/dataset-versions.xhtml @@ -147,7 +147,6 @@ - From 537b1d9ec6ce7bc421696d489c0399be2a63bc08 Mon Sep 17 00:00:00 2001 From: qqmyers Date: Thu, 28 Jul 2022 11:33:48 -0400 Subject: [PATCH 4/6] remove extra script --- .../db/migration/V5.10.1.3__8605-support-archival-status.sql | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 src/main/resources/db/migration/V5.10.1.3__8605-support-archival-status.sql diff --git a/src/main/resources/db/migration/V5.10.1.3__8605-support-archival-status.sql b/src/main/resources/db/migration/V5.10.1.3__8605-support-archival-status.sql deleted file mode 100644 index cf708ad0ea9..00000000000 --- a/src/main/resources/db/migration/V5.10.1.3__8605-support-archival-status.sql +++ /dev/null @@ -1,2 +0,0 @@ -UPDATE datasetversion SET archivalCopyLocation = CONCAT('{"status":"success", "message":"', archivalCopyLocation,'"}') where archivalCopyLocation is not null and not archivalCopyLocation='Attempted'; -UPDATE datasetversion SET archivalCopyLocation = CONCAT('{"status":"failure", "message":"Attempted"}') where archivalCopyLocation='Attempted'; From 26853a4634211ca386d32e4272a7e037c63b045f Mon Sep 17 00:00:00 2001 From: qqmyers Date: Thu, 28 Jul 2022 13:33:39 -0400 Subject: [PATCH 5/6] fix logic after review changes/caching --- .../edu/harvard/iq/dataverse/DatasetPage.java | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index 61913a66979..b56c3197ea8 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -5577,6 +5577,7 @@ public void archiveVersion(Long id) { public boolean isArchivable() { if (archivable == null) { + archivable = false; String className = settingsWrapper.getValueForKey(SettingsServiceBean.Key.ArchiverClassName, null); if (className != null) { try { @@ -5590,7 +5591,6 @@ public boolean isArchivable() { e.printStackTrace(); } } - archivable = false; } return archivable; } @@ -5598,6 +5598,7 @@ public boolean isArchivable() { public boolean isVersionArchivable() { if (versionArchivable == null) { // If this dataset isn't in an archivable collection return false + versionArchivable = false; if (isArchivable()) { boolean checkForArchivalCopy = false; // Otherwise, we need to know if the archiver is single-version-only @@ -5610,35 +5611,35 @@ public boolean isVersionArchivable() { Method m = clazz.getMethod("isSingleVersion", SettingsWrapper.class); Object[] params = { settingsWrapper }; checkForArchivalCopy = (Boolean) m.invoke(null, params); + + if (checkForArchivalCopy) { + // If we have to check (single version archiving), we can't allow archiving if + // one version is already archived (or attempted - any non-null status) + versionArchivable = !isSomeVersionArchived(); + } else { + // If we allow multiple versions or didn't find one that has had archiving run + // on it, we can archive, so return true + versionArchivable = true; + } } catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { logger.warning("Failed to call is Archivable on configured archiver class: " + className); e.printStackTrace(); } - if (checkForArchivalCopy) { - // If we have to check (single version archiving), we can't allow archiving if - // one version is already archived (or attempted - any non-null status) - versionArchivable = !isSomeVersionArchived(); - } - // If we allow multiple versions or didn't find one that has had archiving run - // on it, we can archive, so return true - versionArchivable = true; } } - // not in an archivable collection - versionArchivable = false; } return versionArchivable; } public boolean isSomeVersionArchived() { if (someVersionArchived == null) { + someVersionArchived = false; for (DatasetVersion dv : dataset.getVersions()) { if (dv.getArchivalCopyLocation() != null) { someVersionArchived = true; } } - someVersionArchived = false; } return someVersionArchived; } From 87181ecf145902fce0f3225c1d09a1c1182662a8 Mon Sep 17 00:00:00 2001 From: qqmyers Date: Thu, 28 Jul 2022 14:52:56 -0400 Subject: [PATCH 6/6] fix display logic --- src/main/webapp/dataset-versions.xhtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/webapp/dataset-versions.xhtml b/src/main/webapp/dataset-versions.xhtml index f22eb449c6a..b1612a314fc 100644 --- a/src/main/webapp/dataset-versions.xhtml +++ b/src/main/webapp/dataset-versions.xhtml @@ -161,7 +161,7 @@ action="#{DatasetPage.archiveVersion(versionTab.id)}"> - +