From 95e60b385f7e940fac46dc59683e4485ca52e7c7 Mon Sep 17 00:00:00 2001
From: bencomp
Date: Mon, 3 Oct 2022 01:58:47 +0200
Subject: [PATCH 01/63] Overload DatasetField method to remove type check
I spotted a TODO near a type check based on a string comparison of the
class name.
---
.../edu/harvard/iq/dataverse/DatasetField.java | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetField.java b/src/main/java/edu/harvard/iq/dataverse/DatasetField.java
index 31d08f84c02..772538aa5cb 100644
--- a/src/main/java/edu/harvard/iq/dataverse/DatasetField.java
+++ b/src/main/java/edu/harvard/iq/dataverse/DatasetField.java
@@ -54,15 +54,18 @@ public int compare(DatasetField o1, DatasetField o2) {
o2.getDatasetFieldType().getDisplayOrder() );
}};
- public static DatasetField createNewEmptyDatasetField(DatasetFieldType dsfType, Object dsv) {
+ public static DatasetField createNewEmptyDatasetField(DatasetFieldType dsfType, DatasetVersion dsv) {
DatasetField dsfv = createNewEmptyDatasetField(dsfType);
- //TODO - a better way to handle this?
- if (dsv.getClass().getName().equals("edu.harvard.iq.dataverse.DatasetVersion")){
- dsfv.setDatasetVersion((DatasetVersion)dsv);
- } else {
- dsfv.setTemplate((Template)dsv);
- }
+ dsfv.setDatasetVersion(dsv);
+
+ return dsfv;
+ }
+
+ public static DatasetField createNewEmptyDatasetField(DatasetFieldType dsfType, Template dsv) {
+
+ DatasetField dsfv = createNewEmptyDatasetField(dsfType);
+ dsfv.setTemplate(dsv);
return dsfv;
}
From daccc0e3f4d4efee653489f249f8a1db9e3828bd Mon Sep 17 00:00:00 2001
From: bencomp
Date: Mon, 3 Oct 2022 12:32:13 +0200
Subject: [PATCH 02/63] Compare types using instanceof
---
src/main/java/edu/harvard/iq/dataverse/DatasetField.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetField.java b/src/main/java/edu/harvard/iq/dataverse/DatasetField.java
index 772538aa5cb..e6a4ca21fea 100644
--- a/src/main/java/edu/harvard/iq/dataverse/DatasetField.java
+++ b/src/main/java/edu/harvard/iq/dataverse/DatasetField.java
@@ -563,7 +563,7 @@ private DatasetField copy(Object version, DatasetFieldCompoundValue parent) {
dsf.setDatasetFieldType(datasetFieldType);
if (version != null) {
- if (version.getClass().getName().equals("edu.harvard.iq.dataverse.DatasetVersion")) {
+ if (version instanceof DatasetVersion) {
dsf.setDatasetVersion((DatasetVersion) version);
} else {
dsf.setTemplate((Template) version);
From bdb62163d8ad4ed01b94943ad3c45f13406a6dae Mon Sep 17 00:00:00 2001
From: bencomp
Date: Mon, 3 Oct 2022 13:07:46 +0200
Subject: [PATCH 03/63] Create type-specific copy methods in DatasetField
Both `copy(DatasetVersion)` and `copy(Template)` still refer to
`copy(Object, DatasetFieldCompoundValue)`, because copying that method
would make the code less DRY.
---
.../edu/harvard/iq/dataverse/DatasetField.java | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetField.java b/src/main/java/edu/harvard/iq/dataverse/DatasetField.java
index e6a4ca21fea..35a8184e45b 100644
--- a/src/main/java/edu/harvard/iq/dataverse/DatasetField.java
+++ b/src/main/java/edu/harvard/iq/dataverse/DatasetField.java
@@ -548,9 +548,12 @@ public String toString() {
return "edu.harvard.iq.dataverse.DatasetField[ id=" + id + " ]";
}
- public DatasetField copy(Object version) {
+ public DatasetField copy(DatasetVersion version) {
return copy(version, null);
}
+ public DatasetField copy(Template template) {
+ return copy(template, null);
+ }
// originally this was an overloaded method, but we renamed it to get around an issue with Bean Validation
// (that looked t overloaded methods, when it meant to look at overriden methods
@@ -558,15 +561,15 @@ public DatasetField copyChild(DatasetFieldCompoundValue parent) {
return copy(null, parent);
}
- private DatasetField copy(Object version, DatasetFieldCompoundValue parent) {
+ private DatasetField copy(Object versionOrTemplate, DatasetFieldCompoundValue parent) {
DatasetField dsf = new DatasetField();
dsf.setDatasetFieldType(datasetFieldType);
- if (version != null) {
- if (version instanceof DatasetVersion) {
- dsf.setDatasetVersion((DatasetVersion) version);
+ if (versionOrTemplate != null) {
+ if (versionOrTemplate instanceof DatasetVersion) {
+ dsf.setDatasetVersion((DatasetVersion) versionOrTemplate);
} else {
- dsf.setTemplate((Template) version);
+ dsf.setTemplate((Template) versionOrTemplate);
}
}
From 4579283f8e5039cbbc6c8df43ac73ee5fd63b967 Mon Sep 17 00:00:00 2001
From: bencomp
Date: Mon, 18 Sep 2023 00:07:16 +0200
Subject: [PATCH 04/63] Add basic DatasetFieldTest
---
.../iq/dataverse/DatasetFieldTest.java | 41 +++++++++++++++++++
1 file changed, 41 insertions(+)
create mode 100644 src/test/java/edu/harvard/iq/dataverse/DatasetFieldTest.java
diff --git a/src/test/java/edu/harvard/iq/dataverse/DatasetFieldTest.java b/src/test/java/edu/harvard/iq/dataverse/DatasetFieldTest.java
new file mode 100644
index 00000000000..23ba2d69fff
--- /dev/null
+++ b/src/test/java/edu/harvard/iq/dataverse/DatasetFieldTest.java
@@ -0,0 +1,41 @@
+package edu.harvard.iq.dataverse;
+
+import edu.harvard.iq.dataverse.DatasetFieldType.FieldType;
+import edu.harvard.iq.dataverse.mocks.MocksFactory;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+
+class DatasetFieldTest {
+ @Test
+ void testCreateNewEmptyDatasetField_withEmptyTemplate() {
+ Template template = new Template();
+
+ DatasetField field = DatasetField.createNewEmptyDatasetField(new DatasetFieldType("subject", FieldType.TEXT, false), template);
+ assertTrue(field.getTemplate() == template);
+ assertTrue(template.getDatasetFields().isEmpty());
+ }
+
+ @Test
+ void testNotEqualDatasetFields() {
+ DatasetField field1 = DatasetField.createNewEmptyDatasetField(new DatasetFieldType("subject", FieldType.TEXT, false), new Template());
+ field1.setId(MocksFactory.nextId());
+ DatasetField field2 = DatasetField.createNewEmptyDatasetField(new DatasetFieldType("subject", FieldType.TEXT, false), new Template());
+ field2.setId(MocksFactory.nextId());
+
+ assertNotEquals(field1, field2);
+ }
+
+ @Test
+ void testEqualDatasetFields() {
+ DatasetField field1 = DatasetField.createNewEmptyDatasetField(new DatasetFieldType("subject", FieldType.TEXT, false), new Template());
+ field1.setId(100L);
+ DatasetField field2 = DatasetField.createNewEmptyDatasetField(new DatasetFieldType("subject", FieldType.TEXT, false), new Template());
+ field2.setId(100L);
+
+ assertEquals(field1, field2);
+ }
+}
\ No newline at end of file
From 87bfe16c6a4390075bd0b481071ebddf2f1c1e5d Mon Sep 17 00:00:00 2001
From: bencomp
Date: Mon, 18 Sep 2023 00:25:52 +0200
Subject: [PATCH 05/63] Test DatasetField identities
---
.../iq/dataverse/DatasetFieldTest.java | 27 +++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/src/test/java/edu/harvard/iq/dataverse/DatasetFieldTest.java b/src/test/java/edu/harvard/iq/dataverse/DatasetFieldTest.java
index 23ba2d69fff..97999af3244 100644
--- a/src/test/java/edu/harvard/iq/dataverse/DatasetFieldTest.java
+++ b/src/test/java/edu/harvard/iq/dataverse/DatasetFieldTest.java
@@ -7,6 +7,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertNull;
class DatasetFieldTest {
@@ -21,12 +22,17 @@ void testCreateNewEmptyDatasetField_withEmptyTemplate() {
@Test
void testNotEqualDatasetFields() {
- DatasetField field1 = DatasetField.createNewEmptyDatasetField(new DatasetFieldType("subject", FieldType.TEXT, false), new Template());
+ DatasetFieldType type1 = new DatasetFieldType("subject", FieldType.TEXT, false);
+ Template template1 = new Template();
+ DatasetField field1 = DatasetField.createNewEmptyDatasetField(type1, template1);
field1.setId(MocksFactory.nextId());
- DatasetField field2 = DatasetField.createNewEmptyDatasetField(new DatasetFieldType("subject", FieldType.TEXT, false), new Template());
+ DatasetFieldType type2 = new DatasetFieldType("subject", FieldType.TEXT, false);
+ Template template2 = new Template();
+ DatasetField field2 = DatasetField.createNewEmptyDatasetField(type2, template2);
field2.setId(MocksFactory.nextId());
assertNotEquals(field1, field2);
+ assertNotEquals(field1, template2);
}
@Test
@@ -34,8 +40,25 @@ void testEqualDatasetFields() {
DatasetField field1 = DatasetField.createNewEmptyDatasetField(new DatasetFieldType("subject", FieldType.TEXT, false), new Template());
field1.setId(100L);
DatasetField field2 = DatasetField.createNewEmptyDatasetField(new DatasetFieldType("subject", FieldType.TEXT, false), new Template());
+
+ // Fields are not equal before both have IDs set
+ assertNotEquals(field1, field2);
+
field2.setId(100L);
assertEquals(field1, field2);
}
+
+ @Test
+ void testCopyDatasetFields() {
+ DatasetField field1 = DatasetField.createNewEmptyDatasetField(new DatasetFieldType("subject", FieldType.TEXT, false), new Template());
+ field1.setId(100L);
+ DatasetField field2 = field1.copy(field1.getTemplate());
+
+ assertNull(field2.getId());
+ // A copy of a field should not be equal
+ assertNotEquals(field1, field2);
+
+ assertEquals(field2.getDatasetFieldType(), field1.getDatasetFieldType());
+ }
}
\ No newline at end of file
From 963a00e96f71936903809e0aa6eb9deb3d312def Mon Sep 17 00:00:00 2001
From: Ben Companjen
Date: Thu, 2 Nov 2023 10:22:36 +0100
Subject: [PATCH 06/63] Return valid JSON from API blocking filters
---
.../edu/harvard/iq/dataverse/api/ApiBlockingFilter.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/main/java/edu/harvard/iq/dataverse/api/ApiBlockingFilter.java b/src/main/java/edu/harvard/iq/dataverse/api/ApiBlockingFilter.java
index 0e5b8226310..b51b1aa2612 100644
--- a/src/main/java/edu/harvard/iq/dataverse/api/ApiBlockingFilter.java
+++ b/src/main/java/edu/harvard/iq/dataverse/api/ApiBlockingFilter.java
@@ -49,7 +49,7 @@ public void doBlock(ServletRequest sr, ServletResponse sr1, FilterChain fc) thro
@Override
public void doBlock(ServletRequest sr, ServletResponse sr1, FilterChain fc) throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) sr1;
- httpResponse.getWriter().println("{ status:\"error\", message:\"Endpoint blocked. Please contact the dataverse administrator\"}" );
+ httpResponse.getWriter().println("{ \"status\":\"error\", \"message\":\"Endpoint blocked. Please contact the dataverse administrator\"}" );
httpResponse.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
httpResponse.setContentType("application/json");
}
@@ -67,7 +67,7 @@ public void doBlock(ServletRequest sr, ServletResponse sr1, FilterChain fc) thro
fc.doFilter(sr, sr1);
} else {
HttpServletResponse httpResponse = (HttpServletResponse) sr1;
- httpResponse.getWriter().println("{ status:\"error\", message:\"Endpoint available from localhost only. Please contact the dataverse administrator\"}" );
+ httpResponse.getWriter().println("{ \"status\":\"error\", \"message\":\"Endpoint available from localhost only. Please contact the dataverse administrator\"}" );
httpResponse.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
httpResponse.setContentType("application/json");
}
@@ -102,7 +102,7 @@ public void doBlock(ServletRequest sr, ServletResponse sr1, FilterChain fc) thro
if ( block ) {
HttpServletResponse httpResponse = (HttpServletResponse) sr1;
- httpResponse.getWriter().println("{ status:\"error\", message:\"Endpoint available using API key only. Please contact the dataverse administrator\"}" );
+ httpResponse.getWriter().println("{ \"status\":\"error\", \"message\":\"Endpoint available using API key only. Please contact the dataverse administrator\"}" );
httpResponse.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
httpResponse.setContentType("application/json");
} else {
From cd154813eea9a4f937d6b71645097f3d04867275 Mon Sep 17 00:00:00 2001
From: Ben Companjen
Date: Thu, 2 Nov 2023 23:52:49 +0100
Subject: [PATCH 07/63] Add PR release notes
---
doc/release-notes/api-blocking-filter-json.md | 3 +++
1 file changed, 3 insertions(+)
create mode 100644 doc/release-notes/api-blocking-filter-json.md
diff --git a/doc/release-notes/api-blocking-filter-json.md b/doc/release-notes/api-blocking-filter-json.md
new file mode 100644
index 00000000000..337ff82dd8b
--- /dev/null
+++ b/doc/release-notes/api-blocking-filter-json.md
@@ -0,0 +1,3 @@
+* When any `ApiBlockingFilter` policy applies to a request, the JSON in the body of the error response is now valid JSON.
+ In case an API client did any special processing to allow it to parse the body, that is no longer necessary.
+ The status code of such responses has not changed.
From 7d17b9a496f52ae7adb979471dcf6c782bb7c400 Mon Sep 17 00:00:00 2001
From: Victoria Lubitch
Date: Mon, 3 Jun 2024 14:21:00 -0400
Subject: [PATCH 08/63] Dataverse with WSL
---
.../source/developers/windows.rst | 88 +++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/doc/sphinx-guides/source/developers/windows.rst b/doc/sphinx-guides/source/developers/windows.rst
index 53578fe980c..91e3d783177 100755
--- a/doc/sphinx-guides/source/developers/windows.rst
+++ b/doc/sphinx-guides/source/developers/windows.rst
@@ -16,3 +16,91 @@ See the `post
+
+You will be asked to create a linux user.
+After installation of Linux check that you have internet connection:
+
+.. code-block:: bash
+
+ ping www.google.com
+
+If you do not have internet connection try add in ``/etc/wsl.conf``
+
+.. code-block:: bash
+
+ [network]
+ generateResolvConf = false
+
+Also in /etc/resolv.conf add
+
+.. code-block:: bash
+
+ nameserver 1.1.1.1
+
+Now you can install all the tools one usually uses in Linux. For example, it is good idea to run update:
+
+.. code-block:: bash
+
+ sudo apt update
+ sudo apt full-upgrade -y
+
+Install Dataverse
+~~~~~~~~~~~~~~~~~
+
+Now you can install Dataverse in WSL following the instructions for :doc:`classic-dev-env`
+At the end check that you have ``-Ddataverse.pid.default-provider=fake`` in jvm-options.
+
+Now you can access dataverse in your windows browser
+
+ - http://localhost:8080
+ - username: dataverseAdmin
+ - password: admin
+
+IDE for Dataverse in Windows
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Files in WSL are accessible from Windows for editing using ``\\wsl.localhost`` or ``\\wsl$`` path. Windows files are accessible in linux in ``/mnt/c/`` directory. Therefore one can use one's favorite editor or IDE to edit dataverse project files. Then one can build using ``mvn`` in WSL and deploy manually in WSL using ``asadmin``.
+
+It is still though possible to use full strength of IDE, the following instructions are for Intelij users.
+
+- Install Intelij in Windows.
+
+You can open the project through ``\\wsl.localhost`` and navigate to dataverse project.
+You can try to build the project in Intelij. You may get a message ``Cannot establish network connection from WSL to Windows host (could be blocked by firewall).`` In that case you can try
+to disable WSL Hyperviser from firewall.
+After that you should be able to build the project in Intelij.
+It seems that at present it is impossible to deploy the glassfish application in Intelij. You can try to add Glassfish plugin through Settings->Plugins and in Run->Edit Configurations configure Application Server from WSL ``/usr/localhost/payara6`` with URL http://localhost:8080 and Server Domain as domian one, but it may fail since Intelij confuses the Windows and Linux paths.
+
+To use the full strength of Intelij with build, deployment and debugging, one will need to use Intelij ``Remote development``. Close all the projects in InteliJ and go to ``Remote development->WSL`` and press ``New Project``. In WSL instance choose your linux distribution and press ``Next``. In ``Prpject Directory`` navigate to WSL dataverse project.Then press ``Download IDE and Connect``. This will install InteliJ in WSL in ``~/.cache/JetBrains/``. Now in InteliJ you should see your project opened in a new InteliJ window. After adding Glassfish plugin and editing configuration you should be able to build the project and run the project.
+
+PgAdmin in Windows for Dataverse
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can access dataverse database from Windows. Install pgAdmin https://www.pgadmin.org/download/pgadmin-4-windows/ In pgAdmin register server using 127.0.0.1 with port 5432, database dvndb and dvnapp as username with secret password. Now you will be able to access and update dataverse database.
+
From 8eeaa31829a2e980cc13387f50a691319d9fb37d Mon Sep 17 00:00:00 2001
From: Victoria Lubitch <43550154+lubitchv@users.noreply.github.com>
Date: Mon, 3 Jun 2024 14:44:29 -0400
Subject: [PATCH 09/63] Update doc/sphinx-guides/source/developers/windows.rst
Co-authored-by: Philip Durbin
---
doc/sphinx-guides/source/developers/windows.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx-guides/source/developers/windows.rst b/doc/sphinx-guides/source/developers/windows.rst
index 91e3d783177..d72ec0e50d2 100755
--- a/doc/sphinx-guides/source/developers/windows.rst
+++ b/doc/sphinx-guides/source/developers/windows.rst
@@ -38,7 +38,7 @@ See the list of possible distributions:
wsl --list --online
-Choose the distribution you would like. Then run the following command. Notice that this installation of dataverse was tried with ubuntu distribution.
+Choose the distribution you would like. Then run the following command. These instructions were tested with Ubuntu.
.. code-block:: powershell
From 88d9854cd0328349c0acf0b96c767b04100d7ec7 Mon Sep 17 00:00:00 2001
From: Victoria Lubitch <43550154+lubitchv@users.noreply.github.com>
Date: Mon, 3 Jun 2024 14:44:53 -0400
Subject: [PATCH 10/63] Update doc/sphinx-guides/source/developers/windows.rst
Co-authored-by: Philip Durbin
---
doc/sphinx-guides/source/developers/windows.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx-guides/source/developers/windows.rst b/doc/sphinx-guides/source/developers/windows.rst
index d72ec0e50d2..6a2fc9155fc 100755
--- a/doc/sphinx-guides/source/developers/windows.rst
+++ b/doc/sphinx-guides/source/developers/windows.rst
@@ -45,7 +45,7 @@ Choose the distribution you would like. Then run the following command. These in
wsl --install -d
You will be asked to create a linux user.
-After installation of Linux check that you have internet connection:
+After the installation of Linux is complete, check that you have an internet connection:
.. code-block:: bash
From 9b5b29cf0eac6fc21f666d05c74f8406e1ddbdbf Mon Sep 17 00:00:00 2001
From: Victoria Lubitch <43550154+lubitchv@users.noreply.github.com>
Date: Mon, 3 Jun 2024 14:45:14 -0400
Subject: [PATCH 11/63] Update doc/sphinx-guides/source/developers/windows.rst
Co-authored-by: Philip Durbin
---
doc/sphinx-guides/source/developers/windows.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx-guides/source/developers/windows.rst b/doc/sphinx-guides/source/developers/windows.rst
index 6a2fc9155fc..8986cc2e875 100755
--- a/doc/sphinx-guides/source/developers/windows.rst
+++ b/doc/sphinx-guides/source/developers/windows.rst
@@ -51,7 +51,7 @@ After the installation of Linux is complete, check that you have an internet con
ping www.google.com
-If you do not have internet connection try add in ``/etc/wsl.conf``
+If you do not have an internet connection try adding it in ``/etc/wsl.conf``
.. code-block:: bash
From 87edbcba66f8c293e2074cfbd758b338da0ad057 Mon Sep 17 00:00:00 2001
From: Victoria Lubitch <43550154+lubitchv@users.noreply.github.com>
Date: Mon, 3 Jun 2024 14:45:28 -0400
Subject: [PATCH 12/63] Update doc/sphinx-guides/source/developers/windows.rst
Co-authored-by: Philip Durbin
---
doc/sphinx-guides/source/developers/windows.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx-guides/source/developers/windows.rst b/doc/sphinx-guides/source/developers/windows.rst
index 8986cc2e875..f689b172cd6 100755
--- a/doc/sphinx-guides/source/developers/windows.rst
+++ b/doc/sphinx-guides/source/developers/windows.rst
@@ -58,7 +58,7 @@ If you do not have an internet connection try adding it in ``/etc/wsl.conf``
[network]
generateResolvConf = false
-Also in /etc/resolv.conf add
+Also in ``/etc/resolv.conf`` add
.. code-block:: bash
From 74254affb19eba566699675fae4d677ce6417ef2 Mon Sep 17 00:00:00 2001
From: Victoria Lubitch <43550154+lubitchv@users.noreply.github.com>
Date: Mon, 3 Jun 2024 14:45:45 -0400
Subject: [PATCH 13/63] Update doc/sphinx-guides/source/developers/windows.rst
Co-authored-by: Philip Durbin
---
doc/sphinx-guides/source/developers/windows.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx-guides/source/developers/windows.rst b/doc/sphinx-guides/source/developers/windows.rst
index f689b172cd6..ccba42274b8 100755
--- a/doc/sphinx-guides/source/developers/windows.rst
+++ b/doc/sphinx-guides/source/developers/windows.rst
@@ -64,7 +64,7 @@ Also in ``/etc/resolv.conf`` add
nameserver 1.1.1.1
-Now you can install all the tools one usually uses in Linux. For example, it is good idea to run update:
+Now you can install all the tools one usually uses in Linux. For example, it is good idea to run an update:
.. code-block:: bash
From 93c452d6bec71a402e73b4670db68cc0f95918fc Mon Sep 17 00:00:00 2001
From: Victoria Lubitch <43550154+lubitchv@users.noreply.github.com>
Date: Mon, 3 Jun 2024 14:46:18 -0400
Subject: [PATCH 14/63] Update doc/sphinx-guides/source/developers/windows.rst
Co-authored-by: Philip Durbin
---
doc/sphinx-guides/source/developers/windows.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx-guides/source/developers/windows.rst b/doc/sphinx-guides/source/developers/windows.rst
index ccba42274b8..dda34a22719 100755
--- a/doc/sphinx-guides/source/developers/windows.rst
+++ b/doc/sphinx-guides/source/developers/windows.rst
@@ -102,5 +102,5 @@ To use the full strength of Intelij with build, deployment and debugging, one wi
PgAdmin in Windows for Dataverse
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-You can access dataverse database from Windows. Install pgAdmin https://www.pgadmin.org/download/pgadmin-4-windows/ In pgAdmin register server using 127.0.0.1 with port 5432, database dvndb and dvnapp as username with secret password. Now you will be able to access and update dataverse database.
+You can access The Dataverse database from Windows. Install pgAdmin https://www.pgadmin.org/download/pgadmin-4-windows/ In pgAdmin register a server using 127.0.0.1 with port 5432, database dvndb and dvnapp as username with secret password. Now you will be able to access and update Dataverse database.
From fc57ddffd12c75798fd83f2a99da20128da0821b Mon Sep 17 00:00:00 2001
From: Victoria Lubitch <43550154+lubitchv@users.noreply.github.com>
Date: Mon, 3 Jun 2024 14:46:46 -0400
Subject: [PATCH 15/63] Update doc/sphinx-guides/source/developers/windows.rst
Co-authored-by: Philip Durbin
---
doc/sphinx-guides/source/developers/windows.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx-guides/source/developers/windows.rst b/doc/sphinx-guides/source/developers/windows.rst
index dda34a22719..81b518333f9 100755
--- a/doc/sphinx-guides/source/developers/windows.rst
+++ b/doc/sphinx-guides/source/developers/windows.rst
@@ -30,7 +30,7 @@ If you have Docker already installed, you should already have WSL installed, oth
wsl --install
-If you already had WSL installed you can install specific linux distribution:
+If you already had WSL installed you can install a specific Linux distribution:
See the list of possible distributions:
From fc25adf11a78f405045fdf64aee37f044bde4973 Mon Sep 17 00:00:00 2001
From: Victoria Lubitch <43550154+lubitchv@users.noreply.github.com>
Date: Mon, 3 Jun 2024 14:46:57 -0400
Subject: [PATCH 16/63] Update doc/sphinx-guides/source/developers/windows.rst
Co-authored-by: Philip Durbin
---
doc/sphinx-guides/source/developers/windows.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx-guides/source/developers/windows.rst b/doc/sphinx-guides/source/developers/windows.rst
index 81b518333f9..4ff309bbc9f 100755
--- a/doc/sphinx-guides/source/developers/windows.rst
+++ b/doc/sphinx-guides/source/developers/windows.rst
@@ -44,7 +44,7 @@ Choose the distribution you would like. Then run the following command. These in
wsl --install -d
-You will be asked to create a linux user.
+You will be asked to create a Linux user.
After the installation of Linux is complete, check that you have an internet connection:
.. code-block:: bash
From 841ffd06ddc475f5168549171b97c1b1288673cd Mon Sep 17 00:00:00 2001
From: Victoria Lubitch <43550154+lubitchv@users.noreply.github.com>
Date: Mon, 3 Jun 2024 14:47:13 -0400
Subject: [PATCH 17/63] Update doc/sphinx-guides/source/developers/windows.rst
Co-authored-by: Philip Durbin
---
doc/sphinx-guides/source/developers/windows.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx-guides/source/developers/windows.rst b/doc/sphinx-guides/source/developers/windows.rst
index 4ff309bbc9f..fdc6641eab1 100755
--- a/doc/sphinx-guides/source/developers/windows.rst
+++ b/doc/sphinx-guides/source/developers/windows.rst
@@ -94,7 +94,7 @@ It is still though possible to use full strength of IDE, the following instructi
You can open the project through ``\\wsl.localhost`` and navigate to dataverse project.
You can try to build the project in Intelij. You may get a message ``Cannot establish network connection from WSL to Windows host (could be blocked by firewall).`` In that case you can try
to disable WSL Hyperviser from firewall.
-After that you should be able to build the project in Intelij.
+After that you should be able to build the project in Intellij.
It seems that at present it is impossible to deploy the glassfish application in Intelij. You can try to add Glassfish plugin through Settings->Plugins and in Run->Edit Configurations configure Application Server from WSL ``/usr/localhost/payara6`` with URL http://localhost:8080 and Server Domain as domian one, but it may fail since Intelij confuses the Windows and Linux paths.
To use the full strength of Intelij with build, deployment and debugging, one will need to use Intelij ``Remote development``. Close all the projects in InteliJ and go to ``Remote development->WSL`` and press ``New Project``. In WSL instance choose your linux distribution and press ``Next``. In ``Prpject Directory`` navigate to WSL dataverse project.Then press ``Download IDE and Connect``. This will install InteliJ in WSL in ``~/.cache/JetBrains/``. Now in InteliJ you should see your project opened in a new InteliJ window. After adding Glassfish plugin and editing configuration you should be able to build the project and run the project.
From 185c31cac6aee4869772736bda0ea9879be61a42 Mon Sep 17 00:00:00 2001
From: Victoria Lubitch <43550154+lubitchv@users.noreply.github.com>
Date: Mon, 3 Jun 2024 14:47:26 -0400
Subject: [PATCH 18/63] Update doc/sphinx-guides/source/developers/windows.rst
Co-authored-by: Philip Durbin
---
doc/sphinx-guides/source/developers/windows.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx-guides/source/developers/windows.rst b/doc/sphinx-guides/source/developers/windows.rst
index fdc6641eab1..5d74072f264 100755
--- a/doc/sphinx-guides/source/developers/windows.rst
+++ b/doc/sphinx-guides/source/developers/windows.rst
@@ -92,7 +92,7 @@ It is still though possible to use full strength of IDE, the following instructi
- Install Intelij in Windows.
You can open the project through ``\\wsl.localhost`` and navigate to dataverse project.
-You can try to build the project in Intelij. You may get a message ``Cannot establish network connection from WSL to Windows host (could be blocked by firewall).`` In that case you can try
+You can try to build the project in Intellij. You may get a message ``Cannot establish network connection from WSL to Windows host (could be blocked by firewall).`` In that case you can try
to disable WSL Hyperviser from firewall.
After that you should be able to build the project in Intellij.
It seems that at present it is impossible to deploy the glassfish application in Intelij. You can try to add Glassfish plugin through Settings->Plugins and in Run->Edit Configurations configure Application Server from WSL ``/usr/localhost/payara6`` with URL http://localhost:8080 and Server Domain as domian one, but it may fail since Intelij confuses the Windows and Linux paths.
From f9fb940228106221b08f4cf60139cdd829171a6f Mon Sep 17 00:00:00 2001
From: Victoria Lubitch <43550154+lubitchv@users.noreply.github.com>
Date: Mon, 3 Jun 2024 14:48:08 -0400
Subject: [PATCH 19/63] Update doc/sphinx-guides/source/developers/windows.rst
Co-authored-by: Philip Durbin
---
doc/sphinx-guides/source/developers/windows.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx-guides/source/developers/windows.rst b/doc/sphinx-guides/source/developers/windows.rst
index 5d74072f264..e877f4612e1 100755
--- a/doc/sphinx-guides/source/developers/windows.rst
+++ b/doc/sphinx-guides/source/developers/windows.rst
@@ -77,7 +77,7 @@ Install Dataverse
Now you can install Dataverse in WSL following the instructions for :doc:`classic-dev-env`
At the end check that you have ``-Ddataverse.pid.default-provider=fake`` in jvm-options.
-Now you can access dataverse in your windows browser
+Now you can access Dataverse in your Windows browser (Edge, Chrome, etc.):
- http://localhost:8080
- username: dataverseAdmin
From d336f45154425cd0e49526807b3d087e268233d5 Mon Sep 17 00:00:00 2001
From: Victoria Lubitch <43550154+lubitchv@users.noreply.github.com>
Date: Mon, 3 Jun 2024 14:53:15 -0400
Subject: [PATCH 20/63] Update doc/sphinx-guides/source/developers/windows.rst
Co-authored-by: Philip Durbin
---
doc/sphinx-guides/source/developers/windows.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx-guides/source/developers/windows.rst b/doc/sphinx-guides/source/developers/windows.rst
index e877f4612e1..16063272966 100755
--- a/doc/sphinx-guides/source/developers/windows.rst
+++ b/doc/sphinx-guides/source/developers/windows.rst
@@ -85,7 +85,7 @@ Now you can access Dataverse in your Windows browser (Edge, Chrome, etc.):
IDE for Dataverse in Windows
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Files in WSL are accessible from Windows for editing using ``\\wsl.localhost`` or ``\\wsl$`` path. Windows files are accessible in linux in ``/mnt/c/`` directory. Therefore one can use one's favorite editor or IDE to edit dataverse project files. Then one can build using ``mvn`` in WSL and deploy manually in WSL using ``asadmin``.
+Files in WSL are accessible from Windows for editing using ``\\wsl.localhost`` or ``\\wsl$`` path. Windows files are accessible under Linux in the ``/mnt/c/`` directory. Therefore one can use one's favorite editor or IDE to edit Dataverse project files. Then one can build using ``mvn`` in WSL and deploy manually in WSL using ``asadmin``.
It is still though possible to use full strength of IDE, the following instructions are for Intelij users.
From 4e4af12890c00b1b484d1d98d7428c16c32faa1c Mon Sep 17 00:00:00 2001
From: Victoria Lubitch <43550154+lubitchv@users.noreply.github.com>
Date: Mon, 3 Jun 2024 14:53:32 -0400
Subject: [PATCH 21/63] Update doc/sphinx-guides/source/developers/windows.rst
Co-authored-by: Philip Durbin
---
doc/sphinx-guides/source/developers/windows.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx-guides/source/developers/windows.rst b/doc/sphinx-guides/source/developers/windows.rst
index 16063272966..ec92adf7099 100755
--- a/doc/sphinx-guides/source/developers/windows.rst
+++ b/doc/sphinx-guides/source/developers/windows.rst
@@ -87,7 +87,7 @@ IDE for Dataverse in Windows
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Files in WSL are accessible from Windows for editing using ``\\wsl.localhost`` or ``\\wsl$`` path. Windows files are accessible under Linux in the ``/mnt/c/`` directory. Therefore one can use one's favorite editor or IDE to edit Dataverse project files. Then one can build using ``mvn`` in WSL and deploy manually in WSL using ``asadmin``.
-It is still though possible to use full strength of IDE, the following instructions are for Intelij users.
+It is still though possible to use a full-strength IDE. The following instructions are for Intellij users.
- Install Intelij in Windows.
From 6a34b97b7e67e163553f483ab12a55e1379d4b92 Mon Sep 17 00:00:00 2001
From: Victoria Lubitch <43550154+lubitchv@users.noreply.github.com>
Date: Mon, 3 Jun 2024 14:53:48 -0400
Subject: [PATCH 22/63] Update doc/sphinx-guides/source/developers/windows.rst
Co-authored-by: Philip Durbin
---
doc/sphinx-guides/source/developers/windows.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx-guides/source/developers/windows.rst b/doc/sphinx-guides/source/developers/windows.rst
index ec92adf7099..b16e86b5c2d 100755
--- a/doc/sphinx-guides/source/developers/windows.rst
+++ b/doc/sphinx-guides/source/developers/windows.rst
@@ -91,7 +91,7 @@ It is still though possible to use a full-strength IDE. The following instructio
- Install Intelij in Windows.
-You can open the project through ``\\wsl.localhost`` and navigate to dataverse project.
+You can open the project through ``\\wsl.localhost`` and navigate to Dataverse project.
You can try to build the project in Intellij. You may get a message ``Cannot establish network connection from WSL to Windows host (could be blocked by firewall).`` In that case you can try
to disable WSL Hyperviser from firewall.
After that you should be able to build the project in Intellij.
From 3b9e691c476f9cc50ca75065c80f1a08526ff386 Mon Sep 17 00:00:00 2001
From: Victoria Lubitch <43550154+lubitchv@users.noreply.github.com>
Date: Mon, 3 Jun 2024 14:54:05 -0400
Subject: [PATCH 23/63] Update doc/sphinx-guides/source/developers/windows.rst
Co-authored-by: Philip Durbin
---
doc/sphinx-guides/source/developers/windows.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx-guides/source/developers/windows.rst b/doc/sphinx-guides/source/developers/windows.rst
index b16e86b5c2d..09060b801ad 100755
--- a/doc/sphinx-guides/source/developers/windows.rst
+++ b/doc/sphinx-guides/source/developers/windows.rst
@@ -95,7 +95,7 @@ You can open the project through ``\\wsl.localhost`` and navigate to Dataverse p
You can try to build the project in Intellij. You may get a message ``Cannot establish network connection from WSL to Windows host (could be blocked by firewall).`` In that case you can try
to disable WSL Hyperviser from firewall.
After that you should be able to build the project in Intellij.
-It seems that at present it is impossible to deploy the glassfish application in Intelij. You can try to add Glassfish plugin through Settings->Plugins and in Run->Edit Configurations configure Application Server from WSL ``/usr/localhost/payara6`` with URL http://localhost:8080 and Server Domain as domian one, but it may fail since Intelij confuses the Windows and Linux paths.
+It seems that at present it is impossible to deploy the Glassfish application in Intellij. You can try to add Glassfish plugin through Settings->Plugins and in Run->Edit Configurations configure Application Server from WSL ``/usr/localhost/payara6`` with URL http://localhost:8080 and Server Domain as domain1, but it may fail since Intellij confuses the Windows and Linux paths.
To use the full strength of Intelij with build, deployment and debugging, one will need to use Intelij ``Remote development``. Close all the projects in InteliJ and go to ``Remote development->WSL`` and press ``New Project``. In WSL instance choose your linux distribution and press ``Next``. In ``Prpject Directory`` navigate to WSL dataverse project.Then press ``Download IDE and Connect``. This will install InteliJ in WSL in ``~/.cache/JetBrains/``. Now in InteliJ you should see your project opened in a new InteliJ window. After adding Glassfish plugin and editing configuration you should be able to build the project and run the project.
From 2e497a65aa609eff3934a914951b18da217dac9d Mon Sep 17 00:00:00 2001
From: Victoria Lubitch <43550154+lubitchv@users.noreply.github.com>
Date: Mon, 3 Jun 2024 14:54:23 -0400
Subject: [PATCH 24/63] Update doc/sphinx-guides/source/developers/windows.rst
Co-authored-by: Philip Durbin
---
doc/sphinx-guides/source/developers/windows.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/sphinx-guides/source/developers/windows.rst b/doc/sphinx-guides/source/developers/windows.rst
index 09060b801ad..54a30e95aef 100755
--- a/doc/sphinx-guides/source/developers/windows.rst
+++ b/doc/sphinx-guides/source/developers/windows.rst
@@ -97,7 +97,7 @@ to disable WSL Hyperviser from firewall.
After that you should be able to build the project in Intellij.
It seems that at present it is impossible to deploy the Glassfish application in Intellij. You can try to add Glassfish plugin through Settings->Plugins and in Run->Edit Configurations configure Application Server from WSL ``/usr/localhost/payara6`` with URL http://localhost:8080 and Server Domain as domain1, but it may fail since Intellij confuses the Windows and Linux paths.
-To use the full strength of Intelij with build, deployment and debugging, one will need to use Intelij ``Remote development``. Close all the projects in InteliJ and go to ``Remote development->WSL`` and press ``New Project``. In WSL instance choose your linux distribution and press ``Next``. In ``Prpject Directory`` navigate to WSL dataverse project.Then press ``Download IDE and Connect``. This will install InteliJ in WSL in ``~/.cache/JetBrains/``. Now in InteliJ you should see your project opened in a new InteliJ window. After adding Glassfish plugin and editing configuration you should be able to build the project and run the project.
+To use the full strength of Intelij with build, deployment and debugging, one will need to use Intelij ``Remote development``. Close all the projects in Intellij and go to ``Remote development->WSL`` and press ``New Project``. In WSL instance choose your Linux distribution and press ``Next``. In ``Prpject Directory`` navigate to WSL Dataverse project. Then press ``Download IDE and Connect``. This will install Intellij in WSL in ``~/.cache/JetBrains/``. Now in Intellij you should see your project opened in a new Intellij window. After adding Glassfish plugin and editing configuration you should be able to build the project and run the project.
PgAdmin in Windows for Dataverse
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
From 40503758427f6c2bae790f7ead45844af20293e9 Mon Sep 17 00:00:00 2001
From: Steven Winship <39765413+stevenwinship@users.noreply.github.com>
Date: Wed, 5 Jun 2024 13:46:40 -0400
Subject: [PATCH 25/63] adding fix to file name for download guestbook
responses
---
.../edu/harvard/iq/dataverse/GuestbookResponsesPage.java | 5 +++--
.../java/edu/harvard/iq/dataverse/ManageGuestbooksPage.java | 3 ++-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/main/java/edu/harvard/iq/dataverse/GuestbookResponsesPage.java b/src/main/java/edu/harvard/iq/dataverse/GuestbookResponsesPage.java
index c53df93def8..93ba8028fa8 100644
--- a/src/main/java/edu/harvard/iq/dataverse/GuestbookResponsesPage.java
+++ b/src/main/java/edu/harvard/iq/dataverse/GuestbookResponsesPage.java
@@ -101,8 +101,9 @@ public String init() {
private String getFileName(){
// The fix below replaces any spaces in the name of the dataverse with underscores;
// without it, the filename was chopped off (by the browser??), and the user
- // was getting the file name "Foo", instead of "Foo and Bar in Social Sciences.csv". -- L.A.
- return dataverse.getName().replace(' ', '_') + "_" + guestbook.getId() + "_GuestbookReponses.csv";
+ // was getting the file name "Foo", instead of "Foo and Bar in Social Sciences.csv". -- L.A.
+ // Also removing some chars that have been reported to cause issues with certain browsers
+ return dataverse.getName().replace(' ', '_').replaceAll("[\\\\/:*?\"<>|,;]", "") + "_" + guestbook.getId() + "_GuestbookResponses.csv";
}
public void streamResponsesByDataverseAndGuestbook(){
diff --git a/src/main/java/edu/harvard/iq/dataverse/ManageGuestbooksPage.java b/src/main/java/edu/harvard/iq/dataverse/ManageGuestbooksPage.java
index cc89cfd9d56..94c36a40794 100644
--- a/src/main/java/edu/harvard/iq/dataverse/ManageGuestbooksPage.java
+++ b/src/main/java/edu/harvard/iq/dataverse/ManageGuestbooksPage.java
@@ -220,7 +220,8 @@ private String getFileName(){
// The fix below replaces any spaces in the name of the dataverse with underscores;
// without it, the filename was chopped off (by the browser??), and the user
// was getting the file name "Foo", instead of "Foo and Bar in Social Sciences.csv". -- L.A.
- return dataverse.getName().replace(' ', '_') + "_GuestbookReponses.csv";
+ // Also removing some chars that have been reported to cause issues with certain browsers
+ return dataverse.getName().replace(' ', '_').replaceAll("[\\\\/:*?\"<>|,;]", "") + "_GuestbookResponses.csv";
}
public void deleteGuestbook() {
From c129474b2f90bfe1087b9c62660fed02c0577eb3 Mon Sep 17 00:00:00 2001
From: Stephen Kraffmiller
Date: Wed, 5 Jun 2024 14:27:13 -0400
Subject: [PATCH 26/63] #8796 fix display when no custom terms entered
---
.../dataverse/DatasetVersionServiceBean.java | 17 +++++++++++++
.../iq/dataverse/TermsOfUseAndAccess.java | 24 +++++++++++++++++++
.../iq/dataverse/dataset/DatasetUtil.java | 18 ++++++++++++++
.../iq/dataverse/search/IndexServiceBean.java | 12 ++++++++++
src/main/java/propertyFiles/Bundle.properties | 2 ++
src/main/webapp/dataset-license-terms.xhtml | 4 ++--
.../search/IndexServiceBeanTest.java | 1 +
7 files changed, 76 insertions(+), 2 deletions(-)
diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersionServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersionServiceBean.java
index ab23fa779d5..f99b3ee1b53 100644
--- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersionServiceBean.java
+++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersionServiceBean.java
@@ -315,6 +315,23 @@ private void msg(String s){
//logger.fine(s);
}
+ public boolean isVersionDefaultCustomTerms(DatasetVersion datasetVersion) {
+
+ if (datasetVersion.getId() != null) {
+ try {
+ TermsOfUseAndAccess toua = (TermsOfUseAndAccess) em.createNamedQuery("TermsOfUseAndAccess.findByDatasetVersionIdAndDefaultTerms")
+ .setParameter("id", datasetVersion.getId()).setParameter("defaultTerms", TermsOfUseAndAccess.DEFAULT_NOTERMS).getSingleResult();
+ if (toua != null && datasetVersion.getTermsOfUseAndAccess().getLicense() == null) {
+ return true;
+ }
+
+ } catch (NoResultException e) {
+ return false;
+ }
+ }
+ return false;
+ }
+
/**
* Does the version identifier in the URL ask for a "DRAFT"?
*
diff --git a/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccess.java b/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccess.java
index ee865770dbe..9e48c6c0165 100644
--- a/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccess.java
+++ b/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccess.java
@@ -17,6 +17,28 @@
import jakarta.persistence.Transient;
import edu.harvard.iq.dataverse.license.License;
+import jakarta.persistence.NamedQueries;
+import jakarta.persistence.NamedQuery;
+
+@NamedQueries({
+ // TermsOfUseAndAccess.findByDatasetVersionIdAndDefaultTerms
+ // is used to determine if the dataset terms were set by the multi license support update
+ // as part of the 5.10 release.
+
+ @NamedQuery(name = "TermsOfUseAndAccess.findByDatasetVersionIdAndDefaultTerms",
+ query = "SELECT o FROM TermsOfUseAndAccess o, DatasetVersion dv WHERE "
+ + "dv.id =:id "
+ + "AND dv.termsOfUseAndAccess.id = o.id "
+ + "AND o.termsOfUse =:defaultTerms "
+ + "AND o.confidentialityDeclaration IS null "
+ + "AND o.specialPermissions IS null "
+ + "AND o.restrictions IS null "
+ + "AND o.citationRequirements IS null "
+ + "AND o.depositorRequirements IS null "
+ + "AND o.conditions IS null "
+ + "AND o.disclaimer IS null "
+ )
+})
/**
*
@@ -26,6 +48,8 @@
@Entity
@ValidateTermsOfUseAndAccess
public class TermsOfUseAndAccess implements Serializable {
+
+ public static final String DEFAULT_NOTERMS = "This dataset is made available without information on how it can be used. You should communicate with the Contact(s) specified before use.";
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
diff --git a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java
index 98bd26b51d6..060b8694e9c 100644
--- a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java
+++ b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java
@@ -653,6 +653,15 @@ public static License getLicense(DatasetVersion dsv) {
}
public static String getLicenseName(DatasetVersion dsv) {
+
+ DatasetVersionServiceBean datasetVersionService = CDI.current().select(DatasetVersionServiceBean.class).get();
+ /*
+ Special case where there are default custom terms indicating that no actual choice has been made...
+ */
+ if (datasetVersionService.isVersionDefaultCustomTerms(dsv)) {
+ return BundleUtil.getStringFromBundle("license.none.chosen");
+ }
+
License license = DatasetUtil.getLicense(dsv);
return getLocalizedLicenseName(license);
}
@@ -683,7 +692,16 @@ public static String getLicenseIcon(DatasetVersion dsv) {
}
public static String getLicenseDescription(DatasetVersion dsv) {
+
+ DatasetVersionServiceBean datasetVersionService = CDI.current().select(DatasetVersionServiceBean.class).get();
+ /*
+ Special case where there are default custom terms indicating that no actual choice has been made...
+ */
+ if (datasetVersionService.isVersionDefaultCustomTerms(dsv)) {
+ return BundleUtil.getStringFromBundle("license.none.chosen.description");
+ }
License license = DatasetUtil.getLicense(dsv);
+
return license != null ? getLocalizedLicenseDetails(license,"DESCRIPTION") : BundleUtil.getStringFromBundle("license.custom.description");
}
diff --git a/src/main/java/edu/harvard/iq/dataverse/search/IndexServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/search/IndexServiceBean.java
index e61b93a741f..cbe6c532a65 100644
--- a/src/main/java/edu/harvard/iq/dataverse/search/IndexServiceBean.java
+++ b/src/main/java/edu/harvard/iq/dataverse/search/IndexServiceBean.java
@@ -53,7 +53,9 @@
import jakarta.inject.Named;
import jakarta.json.JsonObject;
import jakarta.persistence.EntityManager;
+import jakarta.persistence.NoResultException;
import jakarta.persistence.PersistenceContext;
+import jakarta.persistence.Query;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
@@ -96,6 +98,8 @@ public class IndexServiceBean {
@EJB
DatasetServiceBean datasetService;
@EJB
+ DatasetVersionServiceBean datasetVersionService;
+ @EJB
BuiltinUserServiceBean dataverseUserServiceBean;
@EJB
PermissionServiceBean permissionService;
@@ -468,11 +472,13 @@ public void indexDvObject(DvObject objectIn) throws SolrServerException, IOExce
public void indexDataset(Dataset dataset, boolean doNormalSolrDocCleanUp) throws SolrServerException, IOException {
doIndexDataset(dataset, doNormalSolrDocCleanUp);
+ System.out.print("indexed: " + dataset.getId());
updateLastIndexedTime(dataset.getId());
}
private void doIndexDataset(Dataset dataset, boolean doNormalSolrDocCleanUp) throws SolrServerException, IOException {
logger.fine("indexing dataset " + dataset.getId());
+ System.out.print("indexing dataset " + dataset.getId());
/**
* @todo should we use solrDocIdentifierDataset or
* IndexableObject.IndexableTypes.DATASET.getName() + "_" ?
@@ -1694,6 +1700,12 @@ private List getDataversePathsFromSegments(List dataversePathSeg
private void addLicenseToSolrDoc(SolrInputDocument solrInputDocument, DatasetVersion datasetVersion) {
if (datasetVersion != null && datasetVersion.getTermsOfUseAndAccess() != null) {
+ //test to see if the terms of use are the default set in 5.10 - if so and there's no license then don't add license to solr doc.
+ //fixes 10513
+ if (datasetVersionService.isVersionDefaultCustomTerms(datasetVersion)){
+ return;
+ }
+
String licenseName = "Custom Terms";
if(datasetVersion.getTermsOfUseAndAccess().getLicense() != null) {
licenseName = datasetVersion.getTermsOfUseAndAccess().getLicense().getName();
diff --git a/src/main/java/propertyFiles/Bundle.properties b/src/main/java/propertyFiles/Bundle.properties
index 0441853eee9..c32adb352a8 100644
--- a/src/main/java/propertyFiles/Bundle.properties
+++ b/src/main/java/propertyFiles/Bundle.properties
@@ -1445,6 +1445,8 @@ dataset.exportBtn.itemLabel.json=JSON
dataset.exportBtn.itemLabel.oai_ore=OAI_ORE
dataset.exportBtn.itemLabel.dataciteOpenAIRE=OpenAIRE
dataset.exportBtn.itemLabel.html=DDI HTML Codebook
+license.none.chosen=No license or custom terms chosen
+license.none.chosen.description=No custom terms have been entered for this dataset
license.custom=Custom Dataset Terms
license.custom.description=Custom terms specific to this dataset
metrics.title=Metrics
diff --git a/src/main/webapp/dataset-license-terms.xhtml b/src/main/webapp/dataset-license-terms.xhtml
index c54d94442ea..88bd75947cb 100644
--- a/src/main/webapp/dataset-license-terms.xhtml
+++ b/src/main/webapp/dataset-license-terms.xhtml
@@ -46,8 +46,8 @@
-
-
+
+
diff --git a/src/test/java/edu/harvard/iq/dataverse/search/IndexServiceBeanTest.java b/src/test/java/edu/harvard/iq/dataverse/search/IndexServiceBeanTest.java
index 92b06e5936f..c062f63e264 100644
--- a/src/test/java/edu/harvard/iq/dataverse/search/IndexServiceBeanTest.java
+++ b/src/test/java/edu/harvard/iq/dataverse/search/IndexServiceBeanTest.java
@@ -51,6 +51,7 @@ public void setUp() {
indexService.settingsService = Mockito.mock(SettingsServiceBean.class);
indexService.dataverseService = Mockito.mock(DataverseServiceBean.class);
indexService.datasetFieldService = Mockito.mock(DatasetFieldServiceBean.class);
+ indexService.datasetVersionService = Mockito.mock(DatasetVersionServiceBean.class);
BrandingUtil.injectServices(indexService.dataverseService, indexService.settingsService);
Mockito.when(indexService.dataverseService.findRootDataverse()).thenReturn(dataverse);
From 7cb45960dfcad5b9e6f41c052769a174f2e8704a Mon Sep 17 00:00:00 2001
From: Stephen Kraffmiller
Date: Wed, 5 Jun 2024 15:19:41 -0400
Subject: [PATCH 27/63] #8796 code cleanup
---
.../edu/harvard/iq/dataverse/search/IndexServiceBean.java | 4 ----
1 file changed, 4 deletions(-)
diff --git a/src/main/java/edu/harvard/iq/dataverse/search/IndexServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/search/IndexServiceBean.java
index 02f04d38bd1..129e3f5af16 100644
--- a/src/main/java/edu/harvard/iq/dataverse/search/IndexServiceBean.java
+++ b/src/main/java/edu/harvard/iq/dataverse/search/IndexServiceBean.java
@@ -54,9 +54,7 @@
import jakarta.inject.Named;
import jakarta.json.JsonObject;
import jakarta.persistence.EntityManager;
-import jakarta.persistence.NoResultException;
import jakarta.persistence.PersistenceContext;
-import jakarta.persistence.Query;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
@@ -476,13 +474,11 @@ public void indexDvObject(DvObject objectIn) throws SolrServerException, IOExce
public void indexDataset(Dataset dataset, boolean doNormalSolrDocCleanUp) throws SolrServerException, IOException {
doIndexDataset(dataset, doNormalSolrDocCleanUp);
- System.out.print("indexed: " + dataset.getId());
updateLastIndexedTime(dataset.getId());
}
private void doIndexDataset(Dataset dataset, boolean doNormalSolrDocCleanUp) throws SolrServerException, IOException {
logger.fine("indexing dataset " + dataset.getId());
- System.out.print("indexing dataset " + dataset.getId());
/**
* @todo should we use solrDocIdentifierDataset or
* IndexableObject.IndexableTypes.DATASET.getName() + "_" ?
From 88877a44f5ac0e52168c0b86841fae5bd9d09ca6 Mon Sep 17 00:00:00 2001
From: Steven Winship <39765413+stevenwinship@users.noreply.github.com>
Date: Wed, 5 Jun 2024 16:25:03 -0400
Subject: [PATCH 28/63] move like method to FileUtil static method and added
tests
---
.../harvard/iq/dataverse/GuestbookResponsesPage.java | 3 ++-
.../edu/harvard/iq/dataverse/ManageGuestbooksPage.java | 3 ++-
.../java/edu/harvard/iq/dataverse/util/FileUtil.java | 10 +++++++++-
.../edu/harvard/iq/dataverse/util/FileUtilTest.java | 7 +++++++
4 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/src/main/java/edu/harvard/iq/dataverse/GuestbookResponsesPage.java b/src/main/java/edu/harvard/iq/dataverse/GuestbookResponsesPage.java
index 93ba8028fa8..4276eb02882 100644
--- a/src/main/java/edu/harvard/iq/dataverse/GuestbookResponsesPage.java
+++ b/src/main/java/edu/harvard/iq/dataverse/GuestbookResponsesPage.java
@@ -8,6 +8,7 @@
import edu.harvard.iq.dataverse.engine.command.impl.UpdateDataverseCommand;
import edu.harvard.iq.dataverse.util.BundleUtil;
+import edu.harvard.iq.dataverse.util.FileUtil;
import edu.harvard.iq.dataverse.util.SystemConfig;
import java.util.List;
import java.util.logging.Logger;
@@ -103,7 +104,7 @@ private String getFileName(){
// without it, the filename was chopped off (by the browser??), and the user
// was getting the file name "Foo", instead of "Foo and Bar in Social Sciences.csv". -- L.A.
// Also removing some chars that have been reported to cause issues with certain browsers
- return dataverse.getName().replace(' ', '_').replaceAll("[\\\\/:*?\"<>|,;]", "") + "_" + guestbook.getId() + "_GuestbookResponses.csv";
+ return FileUtil.sanitizeFileName(dataverse.getName() + "_" + guestbook.getId() + "_GuestbookResponses.csv");
}
public void streamResponsesByDataverseAndGuestbook(){
diff --git a/src/main/java/edu/harvard/iq/dataverse/ManageGuestbooksPage.java b/src/main/java/edu/harvard/iq/dataverse/ManageGuestbooksPage.java
index 94c36a40794..d1cc515fd01 100644
--- a/src/main/java/edu/harvard/iq/dataverse/ManageGuestbooksPage.java
+++ b/src/main/java/edu/harvard/iq/dataverse/ManageGuestbooksPage.java
@@ -5,6 +5,7 @@
import edu.harvard.iq.dataverse.engine.command.impl.UpdateDataverseCommand;
import edu.harvard.iq.dataverse.engine.command.impl.UpdateDataverseGuestbookRootCommand;
import edu.harvard.iq.dataverse.util.BundleUtil;
+import edu.harvard.iq.dataverse.util.FileUtil;
import edu.harvard.iq.dataverse.util.JsfHelper;
import static edu.harvard.iq.dataverse.util.JsfHelper.JH;
import java.util.LinkedList;
@@ -221,7 +222,7 @@ private String getFileName(){
// without it, the filename was chopped off (by the browser??), and the user
// was getting the file name "Foo", instead of "Foo and Bar in Social Sciences.csv". -- L.A.
// Also removing some chars that have been reported to cause issues with certain browsers
- return dataverse.getName().replace(' ', '_').replaceAll("[\\\\/:*?\"<>|,;]", "") + "_GuestbookResponses.csv";
+ return FileUtil.sanitizeFileName(dataverse.getName() + "_GuestbookResponses.csv");
}
public void deleteGuestbook() {
diff --git a/src/main/java/edu/harvard/iq/dataverse/util/FileUtil.java b/src/main/java/edu/harvard/iq/dataverse/util/FileUtil.java
index 6c427672e6d..a0c32d5c8ce 100644
--- a/src/main/java/edu/harvard/iq/dataverse/util/FileUtil.java
+++ b/src/main/java/edu/harvard/iq/dataverse/util/FileUtil.java
@@ -1816,5 +1816,13 @@ public static String getStorageDriver(DataFile dataFile) {
String storageIdentifier = dataFile.getStorageIdentifier();
return storageIdentifier.substring(0, storageIdentifier.indexOf(DataAccess.SEPARATOR));
}
-
+
+ /**
+ * Replace spaces with "_" and remove invalid chars
+ * @param fileNameIn - Name before sanitization NOTE: not full path since this method removes '/' and '\'
+ * @return filename without spaces or invalid chars
+ */
+ public static String sanitizeFileName(String fileNameIn) {
+ return fileNameIn == null ? null : fileNameIn.replace(' ', '_').replaceAll("[\\\\/:*?\"<>|,;]", "");
+ }
}
diff --git a/src/test/java/edu/harvard/iq/dataverse/util/FileUtilTest.java b/src/test/java/edu/harvard/iq/dataverse/util/FileUtilTest.java
index ce8698c95eb..46359d7b02c 100644
--- a/src/test/java/edu/harvard/iq/dataverse/util/FileUtilTest.java
+++ b/src/test/java/edu/harvard/iq/dataverse/util/FileUtilTest.java
@@ -434,4 +434,11 @@ public void testDetermineFileTypeROCrate() {
assertEquals("Code", FileUtil.getIndexableFacetFileType(dockerDataFile));
}
+ @Test
+ public void testSanitizeFileName() {
+ assertEquals(null, FileUtil.sanitizeFileName(null));
+ assertEquals("with_space", FileUtil.sanitizeFileName("with space"));
+ assertEquals("withcomma", FileUtil.sanitizeFileName("with,comma"));
+ assertEquals("with.txt", FileUtil.sanitizeFileName("with,\\?:;,.txt"));
+ }
}
From 3d9592cdc20ae20c339fdd59f975cdfcfe09081c Mon Sep 17 00:00:00 2001
From: Stephen Kraffmiller
Date: Wed, 5 Jun 2024 16:44:01 -0400
Subject: [PATCH 29/63] #8796 add release note
---
doc/release-notes/8796-fix-license-display-indexing.md | 1 +
1 file changed, 1 insertion(+)
create mode 100644 doc/release-notes/8796-fix-license-display-indexing.md
diff --git a/doc/release-notes/8796-fix-license-display-indexing.md b/doc/release-notes/8796-fix-license-display-indexing.md
new file mode 100644
index 00000000000..ebded088875
--- /dev/null
+++ b/doc/release-notes/8796-fix-license-display-indexing.md
@@ -0,0 +1 @@
+When datasets have neither a license nor custom terms of use the display will indicate this. Also, these datasets will no longer be indexed as having custom terms.
From 584dad757bbb5b9e438466b50e2b6fefdfac8a2e Mon Sep 17 00:00:00 2001
From: Stephen Kraffmiller
Date: Wed, 5 Jun 2024 16:58:45 -0400
Subject: [PATCH 30/63] #8796 fix popups
---
src/main/webapp/datasetLicenseInfoFragment.xhtml | 2 +-
src/main/webapp/guestbook-terms-popup-fragment.xhtml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/webapp/datasetLicenseInfoFragment.xhtml b/src/main/webapp/datasetLicenseInfoFragment.xhtml
index 257f6b3b12f..a1bd604aa6a 100644
--- a/src/main/webapp/datasetLicenseInfoFragment.xhtml
+++ b/src/main/webapp/datasetLicenseInfoFragment.xhtml
@@ -22,7 +22,7 @@ xmlns:jsf="http://xmlns.jcp.org/jsf">
target="_blank">#{DatasetUtil:getLicenseName(DatasetPage.workingVersion)}
-
diff --git a/src/main/webapp/guestbook-terms-popup-fragment.xhtml b/src/main/webapp/guestbook-terms-popup-fragment.xhtml
index 5948047d845..d53c4bf4709 100644
--- a/src/main/webapp/guestbook-terms-popup-fragment.xhtml
+++ b/src/main/webapp/guestbook-terms-popup-fragment.xhtml
@@ -48,7 +48,7 @@
-
From f7b95656df437ff3086b13a88e5434092f1ee737 Mon Sep 17 00:00:00 2001
From: Thomas van Erven
Date: Thu, 6 Jun 2024 15:59:24 +0200
Subject: [PATCH 31/63] Docs update.
---
doc/sphinx-guides/source/installation/config.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/doc/sphinx-guides/source/installation/config.rst b/doc/sphinx-guides/source/installation/config.rst
index 8fb9460892b..6b2ef571101 100644
--- a/doc/sphinx-guides/source/installation/config.rst
+++ b/doc/sphinx-guides/source/installation/config.rst
@@ -1292,8 +1292,8 @@ Reported Working S3-Compatible Storage
Note that for direct uploads and downloads, Dataverse redirects to the proxy-url but presigns the urls based on the ``dataverse.files..custom-endpoint-url``. Also, note that if you choose to enable ``dataverse.files..download-redirect`` the S3 URLs expire after 60 minutes by default. You can change that minute value to reflect a timeout value that’s more appropriate by using ``dataverse.files..url-expiration-minutes``.
`Surf Object Store v2019-10-30 `_
- Set ``dataverse.files..payload-signing=true`` and ``dataverse.files..chunked-encoding=false`` to use Surf Object
- Store.
+ Set ``dataverse.files..payload-signing=true``, ``dataverse.files..chunked-encoding=false`` and ``dataverse.files..path-style-request=true`` to use Surf Object
+ Store. You will need the Swift client (documented at ) to create the access key and secret key for the S3 interface.
Note that the ``dataverse.files..proxy-url`` setting can be used in installations where the object store is proxied, but it should be considered an advanced option that will require significant expertise to properly configure.
For direct uploads and downloads, Dataverse redirects to the proxy-url but presigns the urls based on the ``dataverse.files..custom-endpoint-url``.
From 7b9319eea4f26ad7d2b6986cfdc1976b7f433e9a Mon Sep 17 00:00:00 2001
From: Steven Winship <39765413+stevenwinship@users.noreply.github.com>
Date: Wed, 12 Jun 2024 11:49:38 -0400
Subject: [PATCH 32/63] ignore shapefiles if they are under a hidden directory
in the zip file
---
.../iq/dataverse/util/ShapefileHandler.java | 42 +++++++++++-------
.../util/shapefile/ShapefileHandlerTest.java | 8 +++-
src/test/resources/hiddenShapefiles.zip | Bin 0 -> 53764 bytes
3 files changed, 33 insertions(+), 17 deletions(-)
create mode 100644 src/test/resources/hiddenShapefiles.zip
diff --git a/src/main/java/edu/harvard/iq/dataverse/util/ShapefileHandler.java b/src/main/java/edu/harvard/iq/dataverse/util/ShapefileHandler.java
index 9786fda4217..0c77e33712b 100644
--- a/src/main/java/edu/harvard/iq/dataverse/util/ShapefileHandler.java
+++ b/src/main/java/edu/harvard/iq/dataverse/util/ShapefileHandler.java
@@ -15,6 +15,7 @@
import java.util.*;
import java.nio.file.Files;
+import java.nio.file.Paths;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -695,33 +696,42 @@ private boolean examineZipfile(FileInputStream zip_file_stream){
this.filesListInDir.clear();
this.filesizeHash.clear();
this.fileGroups.clear();
-
- try{
+
+ try{
ZipInputStream zipStream = new ZipInputStream(zip_file_stream);
ZipEntry entry;
-
+ List hiddenDirectories = new ArrayList<>();
while((entry = zipStream.getNextEntry())!=null){
+ String zentryFileName = entry.getName();
+ boolean isDirectory = entry.isDirectory();
+
+ Boolean skip = isDirectory || this.isFileToSkip(zentryFileName);
+
+ // check if path is hidden
+ if (isDirectory && Files.isHidden(Paths.get(zentryFileName))) {
+ hiddenDirectories.add(zentryFileName);
+ logger.info("Ignoring files under hidden directory: " + zentryFileName);
+ } else {
+ // check if the path was already found to be hidden
+ for (String hidden : hiddenDirectories) {
+ if (zentryFileName.startsWith(hidden)) {
+ skip = true;
+ break;
+ }
+ }
+ }
- String zentryFileName = entry.getName();
- //msg("zip entry: " + entry.getName());
- // Skip files or folders starting with __
- if (this.isFileToSkip(zentryFileName)){
- continue;
- }
-
- if (entry.isDirectory()) {
- //String dirpath = outputFolder + "/" + zentryFileName;
- //createDirectory(dirpath);
- continue;
+ if (skip) {
+ continue;
}
-
+
String unzipFileName = this.getFileBasename(zentryFileName);
if (unzipFileName==null){
logger.warning("Zip Entry Basename is an empty string: " + zentryFileName);
continue;
}
String unzipFolderName = this.getFolderName(zentryFileName);
-
+
String unzipFilePath = unzipFileName;
if (unzipFolderName != null) {
unzipFilePath = unzipFolderName + "/" + unzipFileName;
diff --git a/src/test/java/edu/harvard/iq/dataverse/util/shapefile/ShapefileHandlerTest.java b/src/test/java/edu/harvard/iq/dataverse/util/shapefile/ShapefileHandlerTest.java
index f0e538616b2..3c5b4797b0a 100644
--- a/src/test/java/edu/harvard/iq/dataverse/util/shapefile/ShapefileHandlerTest.java
+++ b/src/test/java/edu/harvard/iq/dataverse/util/shapefile/ShapefileHandlerTest.java
@@ -282,8 +282,14 @@ public void testZippedShapefileWithExtraFiles() throws IOException{
msg("Passed!");
}
-
+ @Test
+ public void testHiddenFiles() {
+ // test with shapefiles in hidden directory
+ ShapefileHandler shp_handler = new ShapefileHandler("src/test/resources/hiddenShapefiles.zip");
+ shp_handler.DEBUG= true;
+ assertFalse(shp_handler.containsShapefile());
+ }
diff --git a/src/test/resources/hiddenShapefiles.zip b/src/test/resources/hiddenShapefiles.zip
new file mode 100644
index 0000000000000000000000000000000000000000..64ed1721eb20f9c5bcaff7e205ec866a967b90d2
GIT binary patch
literal 53764
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 stY98ev}
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 |