Skip to content

Commit 1bbf3b9

Browse files
authored
Merge branch 'develop' into 10517-dataset-types
2 parents 42ff504 + 025b55d commit 1bbf3b9

26 files changed

+641
-97
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
New "Unlink Dataset" button has been added to the Dataset Page to allow a user to unlink a dataset from a collection that was previously linked with the "Link Dataset" button. The user must possess the same permissions needed to unlink the Dataset as they would to link the Dataset.
2+
The [existing API](https://guides.dataverse.org/en/6.3/admin/dataverses-datasets.html#unlink-a-dataset) for unlinking datasets has been updated to no longer require superuser access. The "Publish Dataset" permission is now enough.
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## RO-Crate Support (Metadata Export)
2+
3+
Dataverse now supports [RO-Crate](https://www.researchobject.org/ro-crate/) in the sense that dataset metadata can be exported in that format. This functionality is not available out of the box but you can enable one or more RO-Crate exporters from the [list of external exporters](https://preview.guides.gdcc.io/en/develop/installation/advanced.html#inventory-of-external-exporters). See also #10744.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
A significant bug in the superuser-only "Update-Current-Version" publication was found and fixed in this release. If the Update-Current-Version option was used when changes were made to the dataset Terms (rather than to dataset metadata), or if the PID provider service was down/returned an error, the update would fail and render the dataset unusable and require restoration from a backup. The fix in this release allows the update to succeed in both of these cases and redesigns the functionality such that any unknown issues should not make the dataset unusable (i.e. the error would be reported and the dataset would remain in its current state with the last-published version as it was and changes still in the draft version.)
2+
3+
Users of earlier Dataverse releases are encouraged to alert their superusers to this issue. Those who wish to disable this functionality have two options:
4+
* Change the dataset.updateRelease entry in the Bundle.properties file (or local language version) to "Do Not Use" or similar (doesn't disable but alerts superusers to the issue), or
5+
* Edit the dataset.xhtml file to remove the lines
6+
7+
<c:if test="#{dataverseSession.user.isSuperuser()}">
8+
<f:selectItem rendered="#" itemLabel="#{bundle['dataset.updateRelease']}" itemValue="3" />
9+
</c:if>
10+
11+
, delete the contents of the generated and osgi-cache directories in the Dataverse Payara domain, and restart the Payara server.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
### Saved search deletion
2+
3+
Saved searches can now be removed using API `/api/admin/savedsearches/$id`. See PR #10198.
4+
This is reflected in the [Saved Search Native API section](https://dataverse-guide--10198.org.readthedocs.build/en/10198/api/native-api.html#saved-search) of the Guide.

doc/sphinx-guides/source/admin/dataverses-datasets.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ It returns a list in the following format:
147147
Unlink a Dataset
148148
^^^^^^^^^^^^^^^^
149149

150-
Removes a link between a dataset and a Dataverse collection. Only accessible to superusers. ::
150+
Removes a link between a dataset and a Dataverse collection. Accessible to users with Publish Dataset permissions. ::
151151

152152
curl -H "X-Dataverse-key: $API_TOKEN" -X DELETE http://$SERVER/api/datasets/$linked-dataset-id/deleteLink/$linking-dataverse-alias
153153

doc/sphinx-guides/source/api/native-api.rst

+8-1
Original file line numberDiff line numberDiff line change
@@ -6018,7 +6018,8 @@ The ``$identifier`` should start with an ``@`` if it's a user. Groups start with
60186018
Saved Search
60196019
~~~~~~~~~~~~
60206020
6021-
The Saved Search, Linked Dataverses, and Linked Datasets features shipped with Dataverse 4.0, but as a "`superuser-only <https://github.com/IQSS/dataverse/issues/90#issuecomment-86094663>`_" because they are **experimental** (see `#1364 <https://github.com/IQSS/dataverse/issues/1364>`_, `#1813 <https://github.com/IQSS/dataverse/issues/1813>`_, `#1840 <https://github.com/IQSS/dataverse/issues/1840>`_, `#1890 <https://github.com/IQSS/dataverse/issues/1890>`_, `#1939 <https://github.com/IQSS/dataverse/issues/1939>`_, `#2167 <https://github.com/IQSS/dataverse/issues/2167>`_, `#2186 <https://github.com/IQSS/dataverse/issues/2186>`_, `#2053 <https://github.com/IQSS/dataverse/issues/2053>`_, and `#2543 <https://github.com/IQSS/dataverse/issues/2543>`_). The following API endpoints were added to help people with access to the "admin" API make use of these features in their current form. There is a known issue (`#1364 <https://github.com/IQSS/dataverse/issues/1364>`_) that once a link to a Dataverse collection or dataset is created, it cannot be removed (apart from database manipulation and reindexing) which is why a ``DELETE`` endpoint for saved searches is neither documented nor functional. The Linked Dataverse collections feature is `powered by Saved Search <https://github.com/IQSS/dataverse/issues/1852>`_ and therefore requires that the "makelinks" endpoint be executed on a periodic basis as well.
6021+
The Saved Search, Linked Dataverses, and Linked Datasets features are only accessible to superusers except for linking a dataset. The following API endpoints were added to help people with access to the "admin" API make use of these features in their current form. Keep in mind that they are partially experimental.
6022+
The update of all saved search is run by a timer once a week (See :ref:`saved-search-timer`) so if you just created a saved search, you can run manually ``makelinks`` endpoint that will find new dataverses and datasets that match the saved search and then link the search results to the dataverse in which the saved search is defined.
60226023
60236024
List all saved searches. ::
60246025
@@ -6028,6 +6029,12 @@ List a saved search by database id. ::
60286029
60296030
GET http://$SERVER/api/admin/savedsearches/$id
60306031
6032+
Delete a saved search by database id.
6033+
6034+
The ``unlink=true`` query parameter unlinks all links (linked dataset or Dataverse collection) associated with the deleted saved search. Use of this parameter should be well considered as you cannot know if the links were created manually or by the saved search. After deleting a saved search with ``unlink=true``, we recommend running ``/makelinks/all`` just in case there was a dataset that was linked by another saved search. (Saved searches can link the same dataset.) Reindexing might be necessary as well.::
6035+
6036+
DELETE http://$SERVER/api/admin/savedsearches/$id?unlink=true
6037+
60316038
Execute a saved search by database id and make links to Dataverse collections and datasets that are found. The JSON response indicates which Dataverse collections and datasets were newly linked versus already linked. The ``debug=true`` query parameter adds to the JSON response extra information about the saved search being executed (which you could also get by listing the saved search). ::
60326039
60336040
PUT http://$SERVER/api/admin/savedsearches/makelinks/$id?debug=true

doc/sphinx-guides/source/container/running/demo.rst

-2
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,6 @@ Some JVM options can be configured as environment variables. For example, you ca
124124
125125
We are in the process of making more JVM options configurable as environment variables. Look for the term "MicroProfile Config" in under :doc:`/installation/config` in the Installation Guide to know if you can use them this way.
126126

127-
Please note that for a few environment variables (the ones that start with ``%ct`` in :download:`microprofile-config.properties <../../../../../src/main/resources/META-INF/microprofile-config.properties>`), you have to prepend ``_CT_`` to make, for example, ``_CT_DATAVERSE_SITEURL``. We are working on a fix for this in https://github.com/IQSS/dataverse/issues/10285.
128-
129127
There is a final way to configure JVM options that we plan to deprecate once all JVM options have been converted to MicroProfile Config. Look for "magic trick" under "tunables" at :doc:`../app-image` for more information.
130128

131129
Database Settings

doc/sphinx-guides/source/contributor/documentation.md

+13
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ Please observe the following when writing documentation:
131131
- Use American English spelling.
132132
- Use examples when possible.
133133
- Break up longer paragraphs.
134+
- Use Title Case in Headings.
134135
- Use "double quotes" instead of 'single quotes'.
135136
- Favor "and" (data and code) over slashes (data/code).
136137

@@ -150,6 +151,18 @@ If the page is written in Markdown (.md), use this form:
150151
:depth: 3
151152
```
152153

154+
### Links
155+
156+
Getting links right with .rst files can be tricky.
157+
158+
#### Custom Titles
159+
160+
You can use a custom title when linking to a document like this:
161+
162+
:doc:`Custom title </api/intro>`
163+
164+
See also <https://docs.readthedocs.io/en/stable/guides/cross-referencing-with-sphinx.html#the-doc-role>
165+
153166
### Images
154167

155168
A good documentation is just like a website enhanced and upgraded by adding high quality and self-explanatory images. Often images depict a lot of written text in a simple manner. Within our Sphinx docs, you can add them in two ways: a) add a PNG image directly and include or b) use inline description languages like GraphViz (current only option).

doc/sphinx-guides/source/developers/version-control.rst

+17-5
Original file line numberDiff line numberDiff line change
@@ -137,17 +137,29 @@ Make a Pull Request
137137
~~~~~~~~~~~~~~~~~~~
138138

139139
Make a pull request to get approval to merge your changes into the develop branch.
140-
If the pull request notes indicate that release notes are necessary, the workflow can then verify the existence of a corresponding file and respond with a 'thank you!' message. On the other hand, if no release notes are detected, the contributor can be gently reminded of their absence. Please see :doc:`making-releases` for guidance on writing release notes.
141-
Note that once a pull request is created, we'll remove the corresponding issue from our kanban board so that we're only tracking one card.
142140

143-
Feedback on the pull request template we use is welcome! Here's an example of a pull request for issue #3827: https://github.com/IQSS/dataverse/pull/3827
141+
Feedback on the pull request template we use is welcome!
142+
143+
Here's an example of a pull request for issue #9729: https://github.com/IQSS/dataverse/pull/10474
144+
145+
Replace Issue with Pull Request
146+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
147+
148+
If the pull request closes an issue that has been prioritized, someone from the core team will do the following:
149+
150+
- Move the open issue to the "Done" column of the `project board`_. We do this to track only one card, the pull request, on the project board. Merging the pull request will close the issue because we use the "closes #1234" `keyword <https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue>`_ .
151+
- Copy all labels from the issue to the pull request with the exception of the "size" label.
152+
- Add a size label to the pull request that reflects the amount of review and QA time needed.
153+
- Move the pull request to the "Ready for Review" column.
154+
155+
.. _project board: https://github.com/orgs/IQSS/projects/34
144156

145157
Make Sure Your Pull Request Has Been Advanced to Code Review
146158
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
147159

148-
Now that you've made your pull request, your goal is to make sure it appears in the "Code Review" column at https://github.com/orgs/IQSS/projects/34.
160+
Now that you've made your pull request, your goal is to make sure it appears in the "Code Review" column on the `project board`_.
149161

150-
Look at https://github.com/IQSS/dataverse/blob/master/CONTRIBUTING.md for various ways to reach out to developers who have enough access to the GitHub repo to move your issue and pull request to the "Code Review" column.
162+
Look at :ref:`getting-help-developers` for various ways to reach out to developers who have enough access to the GitHub repo to move your issue and pull request to the "Code Review" column.
151163

152164
Summary of Git commands
153165
~~~~~~~~~~~~~~~~~~~~~~~

doc/sphinx-guides/source/installation/advanced.rst

+4-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,10 @@ Use the :ref:`dataverse.spi.exporters.directory` configuration option to specify
136136
Inventory of External Exporters
137137
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
138138

139-
For a list of external exporters, see the README at https://github.com/gdcc/dataverse-exporters
139+
For a list of external exporters, see the README at https://github.com/gdcc/dataverse-exporters. To highlight a few:
140+
141+
- Croissant
142+
- RO-Crate
140143

141144
Developing New Exporters
142145
^^^^^^^^^^^^^^^^^^^^^^^^

doc/sphinx-guides/source/user/dataset-management.rst

+4-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ Once a dataset has been published, its metadata can be exported in a variety of
3636
- OpenAIRE
3737
- Schema.org JSON-LD
3838

39-
Additional formats can be enabled. See :ref:`inventory-of-external-exporters` in the Installation Guide.
39+
Additional formats can be enabled. See :ref:`inventory-of-external-exporters` in the Installation Guide. To highlight a few:
40+
41+
- Croissant
42+
- RO-Crate
4043

4144
Each of these metadata exports contains the metadata of the most recently published version of the dataset.
4245

docker/compose/demo/compose.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ services:
99
restart: on-failure
1010
user: payara
1111
environment:
12-
_CT_DATAVERSE_SITEURL: "https://demo.example.org"
12+
DATAVERSE_SITEURL: "https://demo.example.org"
1313
DATAVERSE_DB_HOST: postgres
1414
DATAVERSE_DB_PASSWORD: secret
1515
DATAVERSE_DB_USER: dataverse

src/main/java/edu/harvard/iq/dataverse/DatasetPage.java

+45
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
import edu.harvard.iq.dataverse.engine.command.exception.IllegalCommandException;
119119
import edu.harvard.iq.dataverse.engine.command.impl.AbstractSubmitToArchiveCommand;
120120
import edu.harvard.iq.dataverse.engine.command.impl.CreateNewDatasetCommand;
121+
import edu.harvard.iq.dataverse.engine.command.impl.DeleteDatasetLinkingDataverseCommand;
121122
import edu.harvard.iq.dataverse.engine.command.impl.GetLatestPublishedDatasetVersionCommand;
122123
import edu.harvard.iq.dataverse.engine.command.impl.RequestRsyncScriptCommand;
123124
import edu.harvard.iq.dataverse.engine.command.impl.PublishDatasetResult;
@@ -3562,6 +3563,16 @@ public void saveLinkingDataverses(ActionEvent evt) {
35623563
}
35633564
alreadyLinkedDataverses = null; //force update to list of linked dataverses
35643565
}
3566+
public void deleteLinkingDataverses(ActionEvent evt) {
3567+
3568+
if (deleteLink(selectedDataverseForLinking)) {
3569+
JsfHelper.addSuccessMessage(BundleUtil.getStringFromBundle("dataset.message.unlinkSuccess", getSuccessMessageArguments()));
3570+
} else {
3571+
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, BundleUtil.getStringFromBundle("dataset.notlinked"), linkingDataverseErrorMessage);
3572+
FacesContext.getCurrentInstance().addMessage(null, message);
3573+
}
3574+
alreadyLinkedDataverses = null; //force update to list of linked dataverses
3575+
}
35653576

35663577
private String linkingDataverseErrorMessage = "";
35673578

@@ -3596,6 +3607,25 @@ private Boolean saveLink(Dataverse dataverse){
35963607
}
35973608
return retVal;
35983609
}
3610+
private Boolean deleteLink(Dataverse dataverse){
3611+
boolean retVal = true;
3612+
linkingDataverse = dataverse;
3613+
try {
3614+
DatasetLinkingDataverse dsld = dsLinkingService.findDatasetLinkingDataverse(dataset.getId(), linkingDataverse.getId());
3615+
DeleteDatasetLinkingDataverseCommand cmd = new DeleteDatasetLinkingDataverseCommand(dvRequestService.getDataverseRequest(), dataset, dsld, true);
3616+
commandEngine.submit(cmd);
3617+
} catch (CommandException ex) {
3618+
String msg = "There was a problem removing the link between this dataset to yours: " + ex;
3619+
logger.severe(msg);
3620+
msg = BundleUtil.getStringFromBundle("dataset.notlinked.msg") + ex;
3621+
/**
3622+
* @todo how do we get this message to show up in the GUI?
3623+
*/
3624+
linkingDataverseErrorMessage = msg;
3625+
retVal = false;
3626+
}
3627+
return retVal;
3628+
}
35993629

36003630
private String alreadyLinkedDataverses = null;
36013631

@@ -3622,6 +3652,14 @@ public List<Dataverse> completeLinkingDataverse(String query) {
36223652
return null;
36233653
}
36243654
}
3655+
public List<Dataverse> completeUnLinkingDataverse(String query) {
3656+
dataset = datasetService.find(dataset.getId());
3657+
if (session.getUser().isAuthenticated()) {
3658+
return dataverseService.filterDataversesForUnLinking(query, dvRequestService.getDataverseRequest(), dataset);
3659+
} else {
3660+
return null;
3661+
}
3662+
}
36253663

36263664
public List<Dataverse> completeHostDataverseMenuList(String query) {
36273665
if (session.getUser().isAuthenticated()) {
@@ -5580,12 +5618,19 @@ public void setPrivateUrlJustCreatedToFalse() {
55805618
public boolean isShowLinkingPopup() {
55815619
return showLinkingPopup;
55825620
}
5621+
public boolean isShowUnLinkingPopup() {
5622+
return showUnLinkingPopup;
5623+
}
55835624

55845625
public void setShowLinkingPopup(boolean showLinkingPopup) {
55855626
this.showLinkingPopup = showLinkingPopup;
55865627
}
5628+
public void setShowUnLinkingPopup(boolean showUnLinkingPopup) {
5629+
this.showUnLinkingPopup = showUnLinkingPopup;
5630+
}
55875631

55885632
private boolean showLinkingPopup = false;
5633+
private boolean showUnLinkingPopup = false;
55895634
private Boolean anonymizedAccess = null;
55905635

55915636
//

src/main/java/edu/harvard/iq/dataverse/DataverseServiceBean.java

+13-1
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,19 @@ public List<Dataverse> filterDataversesForLinking(String query, DataverseRequest
504504

505505
return dataverseList;
506506
}
507-
507+
public List<Dataverse> filterDataversesForUnLinking(String query, DataverseRequest req, Dataset dataset) {
508+
List<Object> alreadyLinkeddv_ids = em.createNativeQuery("SELECT linkingdataverse_id FROM datasetlinkingdataverse WHERE dataset_id = " + dataset.getId()).getResultList();
509+
List<Dataverse> dataverseList = new ArrayList<>();
510+
if (alreadyLinkeddv_ids != null && !alreadyLinkeddv_ids.isEmpty()) {
511+
alreadyLinkeddv_ids.stream().map((testDVId) -> this.find(testDVId)).forEachOrdered((dataverse) -> {
512+
if (this.permissionService.requestOn(req, dataverse).has(Permission.PublishDataset)) {
513+
dataverseList.add(dataverse);
514+
}
515+
});
516+
}
517+
return dataverseList;
518+
}
519+
508520
public List<Dataverse> filterDataversesForHosting(String pattern, DataverseRequest req) {
509521

510522
// Find the dataverses matching the search parameters:

src/main/java/edu/harvard/iq/dataverse/api/SavedSearches.java

+10-9
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public Response list() {
5555
savedSearchesBuilder.add(thisSavedSearch);
5656
}
5757
JsonObjectBuilder response = Json.createObjectBuilder();
58-
response.add("saved searches", savedSearchesBuilder);
58+
response.add("savedSearches", savedSearchesBuilder);
5959
return ok(response);
6060
}
6161

@@ -90,7 +90,6 @@ private JsonObjectBuilder toJson(SavedSearch savedSearch) {
9090

9191
@POST
9292
public Response add(JsonObject body) {
93-
9493
if (body == null) {
9594
return error(BAD_REQUEST, "JSON is expected.");
9695
}
@@ -159,7 +158,7 @@ public Response add(JsonObject body) {
159158

160159
try {
161160
SavedSearch persistedSavedSearch = savedSearchSvc.add(toPersist);
162-
return ok("Added: " + persistedSavedSearch);
161+
return ok("Added: " + persistedSavedSearch, Json.createObjectBuilder().add("id", persistedSavedSearch.getId()));
163162
} catch (EJBException ex) {
164163
StringBuilder errors = new StringBuilder();
165164
Throwable throwable = ex.getCause();
@@ -173,16 +172,18 @@ public Response add(JsonObject body) {
173172

174173
@DELETE
175174
@Path("{id}")
176-
public Response delete(@PathParam("id") long doomedId) {
177-
boolean disabled = true;
178-
if (disabled) {
179-
return error(BAD_REQUEST, "Saved Searches can not safely be deleted because links can not safely be deleted. See https://github.com/IQSS/dataverse/issues/1364 for details.");
180-
}
175+
public Response delete(@PathParam("id") long doomedId, @QueryParam("unlink") boolean unlink) {
181176
SavedSearch doomed = savedSearchSvc.find(doomedId);
182177
if (doomed == null) {
183178
return error(NOT_FOUND, "Could not find saved search id " + doomedId);
184179
}
185-
boolean wasDeleted = savedSearchSvc.delete(doomedId);
180+
boolean wasDeleted;
181+
try {
182+
wasDeleted = savedSearchSvc.delete(doomedId, unlink);
183+
} catch (Exception e) {
184+
return error(INTERNAL_SERVER_ERROR, "Problem while trying to unlink links of saved search id " + doomedId);
185+
}
186+
186187
if (wasDeleted) {
187188
return ok(Json.createObjectBuilder().add("Deleted", doomedId));
188189
} else {

0 commit comments

Comments
 (0)