Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IQSS/9387 - Support protected system metadata #9388

Merged
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
7f2c191
initial setting
qqmyers Jan 9, 2023
935f50c
UI cache for system md block setting
qqmyers Jan 9, 2023
549d813
Don't show system md blocks in edit.
qqmyers Jan 9, 2023
a4f1f1a
Merge remote-tracking branch 'IQSS/develop' into DANS/system_metadata
qqmyers Jan 17, 2023
bd49930
Bug fix in semantic api add method
qqmyers Jan 18, 2023
4cccef3
more bugs re: semantic methods
qqmyers Jan 18, 2023
0b3770e
Revert "more bugs re: semantic methods"
qqmyers Jan 18, 2023
ef13bcd
Revert "Bug fix in semantic api add method"
qqmyers Jan 18, 2023
ef233e2
@Inject works, @EJB doesn't
qqmyers Jan 19, 2023
bb7cf31
Adding comment
qqmyers Jan 19, 2023
a8981f3
add commented-out entry to microprofile properties
qqmyers Jan 19, 2023
3f795af
methods to identify changed md blocks
qqmyers Jan 19, 2023
4422940
implementation of system md block checks in Update/Create dsv commands
qqmyers Jan 19, 2023
3e36562
correcting/simplifying sem api methods
qqmyers Jan 19, 2023
0a89bbd
Merge remote-tracking branch 'IQSS/develop' into DANS/system_metadata
qqmyers Jan 19, 2023
156e070
Merge remote-tracking branch 'IQSS/develop' into DANS/system_metadata
qqmyers Jan 30, 2023
eafaa77
remove always false flag, add harvested flag
qqmyers Jan 30, 2023
e368c8a
Check for system md in create, except for harvested
qqmyers Jan 30, 2023
11cea54
add MetadataBlock to test DatasetFieldType
qqmyers Jan 30, 2023
c8680ab
Merge remote-tracking branch 'IQSS/develop' into DANS/system_metadata
qqmyers Feb 14, 2023
a36ab78
Fix checkstyle issue
qqmyers Feb 14, 2023
101580f
respond to review comments
qqmyers Feb 23, 2023
1f54785
allow headers or q params for system mdb keys
qqmyers Feb 23, 2023
dbc81fc
docs and release notes
qqmyers Feb 23, 2023
7dea429
fix docs
qqmyers Feb 23, 2023
33c4102
fix microprofile key parameterization
qqmyers Feb 23, 2023
3e03643
Merge remote-tracking branch 'IQSS/develop' into DANS/system_metadata
qqmyers Feb 23, 2023
f21cefb
Merge remote-tracking branch 'IQSS/develop' into DANS/system_metadata
qqmyers Mar 14, 2023
efeb049
Change to fine logging
qqmyers Mar 14, 2023
9b3d9a1
Merge remote-tracking branch 'IQSS/develop' into DANS/system_metadata
qqmyers Mar 22, 2023
a03263d
Merge remote-tracking branch 'IQSS/develop' into DANS/system_metadata
qqmyers Mar 28, 2023
2221d33
Merge remote-tracking branch 'IQSS/develop' into
qqmyers Apr 24, 2023
1c4228a
Merge remote-tracking branch 'IQSS/develop' into DANS/system_metadata
qqmyers Jul 5, 2023
e400f97
merge issue
qqmyers Jul 5, 2023
791b5cb
Merge remote-tracking branch 'IQSS/develop' into DANS/system_metadata
qqmyers Jul 10, 2023
5e1693d
don't show system blocks for edit in templates
qqmyers Jul 10, 2023
67d0618
fix create dataset constructor re: harvested/validation
qqmyers Jul 10, 2023
07fca52
Clarify case sensitive name, update example to use codeMeta20 name
qqmyers Jul 10, 2023
a3fe128
Merge remote-tracking branch 'IQSS/develop' into DANS/system_metadata
qqmyers Jul 10, 2023
cbfe78c
fix template create hiding of system blocks
qqmyers Jul 11, 2023
9ec4300
change examples to use codeVersion
qqmyers Jul 11, 2023
54f9f3f
typo - header had = not :
qqmyers Jul 11, 2023
c960a36
also mention template issue
qqmyers Jul 11, 2023
4130dfd
fix example (use specific schema.org mapping for this term)
qqmyers Jul 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/java/edu/harvard/iq/dataverse/DatasetPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -3595,7 +3595,7 @@ public String save() {
//ToDo - could drop use of selectedTemplate and just use the persistent dataset.getTemplate()
if ( selectedTemplate != null ) {
if ( isSessionUserAuthenticated() ) {
cmd = new CreateNewDatasetCommand(dataset, dvRequestService.getDataverseRequest(), false, selectedTemplate);
cmd = new CreateNewDatasetCommand(dataset, dvRequestService.getDataverseRequest(), selectedTemplate);
} else {
JH.addMessage(FacesMessage.SEVERITY_FATAL, BundleUtil.getStringFromBundle("dataset.create.authenticatedUsersOnly"));
return null;
Expand Down
114 changes: 110 additions & 4 deletions src/main/java/edu/harvard/iq/dataverse/DatasetVersionDifference.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,29 @@

import edu.harvard.iq.dataverse.datavariable.DataVariable;
import edu.harvard.iq.dataverse.datavariable.VarGroup;
import edu.harvard.iq.dataverse.datavariable.VariableMetadata;
import edu.harvard.iq.dataverse.datavariable.VariableMetadataUtil;
import edu.harvard.iq.dataverse.util.StringUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

import org.apache.commons.lang3.StringUtils;
import edu.harvard.iq.dataverse.util.BundleUtil;
import edu.harvard.iq.dataverse.util.FileUtil;

import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;

/**
*
* @author skraffmiller
*/
public final class DatasetVersionDifference {
private static final Logger logger = Logger.getLogger(DatasetVersionDifference.class.getCanonicalName());

private DatasetVersion newVersion;
private DatasetVersion originalVersion;
Expand Down Expand Up @@ -1713,4 +1714,109 @@ public void setDatasetFilesDiffList(List<datasetFileDifferenceItem> datasetFiles
this.datasetFilesDiffList = datasetFilesDiffList;
}

/*
* Static methods to compute which blocks have changes between the two
* DatasetVersions. Currently used to assess whether 'system metadatablocks'
* (protected by a separate key) have changed. (Simplified from the methods
* above that track all the individual changes)
*
*/
public static Set<MetadataBlock> getBlocksWithChanges(DatasetVersion newVersion, DatasetVersion originalVersion) {
Set<MetadataBlock> changedBlockSet = new HashSet<MetadataBlock>();

// Compare Data
List<DatasetField> newDatasetFields = new LinkedList<DatasetField>(newVersion.getDatasetFields());
if (originalVersion == null) {
// Every field is new, just list blocks used
Iterator<DatasetField> dsfnIter = newDatasetFields.listIterator();
while (dsfnIter.hasNext()) {
DatasetField dsfn = dsfnIter.next();
if (!changedBlockSet.contains(dsfn.getDatasetFieldType().getMetadataBlock())) {
changedBlockSet.add(dsfn.getDatasetFieldType().getMetadataBlock());
}
}

} else {
List<DatasetField> originalDatasetFields = new LinkedList<DatasetField>(originalVersion.getDatasetFields());
Iterator<DatasetField> dsfoIter = originalDatasetFields.listIterator();
while (dsfoIter.hasNext()) {
DatasetField dsfo = dsfoIter.next();
boolean deleted = true;
Iterator<DatasetField> dsfnIter = newDatasetFields.listIterator();

while (dsfnIter.hasNext()) {
DatasetField dsfn = dsfnIter.next();
if (dsfo.getDatasetFieldType().equals(dsfn.getDatasetFieldType())) {
deleted = false;
if (!changedBlockSet.contains(dsfo.getDatasetFieldType().getMetadataBlock())) {
logger.fine("Checking " + dsfo.getDatasetFieldType().getName());
if (dsfo.getDatasetFieldType().isPrimitive()) {
if (fieldsAreDifferent(dsfo, dsfn, false)) {
logger.fine("Adding block for " + dsfo.getDatasetFieldType().getName());
changedBlockSet.add(dsfo.getDatasetFieldType().getMetadataBlock());
}
} else {
if (fieldsAreDifferent(dsfo, dsfn, true)) {
logger.fine("Adding block for " + dsfo.getDatasetFieldType().getName());
changedBlockSet.add(dsfo.getDatasetFieldType().getMetadataBlock());
}
}
}
dsfnIter.remove();
break; // if found go to next dataset field
}
}

if (deleted) {
logger.fine("Adding block for deleted " + dsfo.getDatasetFieldType().getName());
changedBlockSet.add(dsfo.getDatasetFieldType().getMetadataBlock());
}
dsfoIter.remove();
}
// Only fields left are non-matching ones but they may be empty
for (DatasetField dsfn : newDatasetFields) {
if (!dsfn.isEmpty()) {
logger.fine("Adding block for added " + dsfn.getDatasetFieldType().getName());
changedBlockSet.add(dsfn.getDatasetFieldType().getMetadataBlock());
}
}
}
return changedBlockSet;
}

private static boolean fieldsAreDifferent(DatasetField originalField, DatasetField newField, boolean compound) {
String originalValue = "";
String newValue = "";

if (compound) {
for (DatasetFieldCompoundValue datasetFieldCompoundValueOriginal : originalField
.getDatasetFieldCompoundValues()) {
int loopIndex = 0;
if (newField.getDatasetFieldCompoundValues().size() >= loopIndex + 1) {
for (DatasetField dsfo : datasetFieldCompoundValueOriginal.getChildDatasetFields()) {
if (!dsfo.getDisplayValue().isEmpty()) {
originalValue += dsfo.getDisplayValue() + ", ";
}
}
for (DatasetField dsfn : newField.getDatasetFieldCompoundValues().get(loopIndex)
.getChildDatasetFields()) {
if (!dsfn.getDisplayValue().isEmpty()) {
newValue += dsfn.getDisplayValue() + ", ";
}
}
if (!originalValue.trim().equals(newValue.trim())) {
return true;
}
}
loopIndex++;
}
} else {
originalValue = originalField.getDisplayValue();
newValue = newField.getDisplayValue();
if (!originalValue.equalsIgnoreCase(newValue)) {
return true;
}
}
return false;
}
}
17 changes: 9 additions & 8 deletions src/main/java/edu/harvard/iq/dataverse/DatasetVersionUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,18 @@
package edu.harvard.iq.dataverse;

import edu.harvard.iq.dataverse.util.MarkupChecker;
import edu.harvard.iq.dataverse.util.StringUtil;
import java.io.Serializable;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import static java.util.stream.Collectors.toList;
import javax.ejb.EJB;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import javax.inject.Inject;
import javax.json.JsonObject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

Expand All @@ -35,6 +30,9 @@ public class DatasetVersionUI implements Serializable {

@EJB
DataverseServiceBean dataverseService;
@Inject
SettingsWrapper settingsWrapper;

@PersistenceContext(unitName = "VDCNet-ejbPU")
private EntityManager em;

Expand Down Expand Up @@ -400,6 +398,9 @@ public void setMetadataValueBlocks(DatasetVersion datasetVersion) {
//TODO: A lot of clean up on the logic of this method
metadataBlocksForView.clear();
metadataBlocksForEdit.clear();

JsonObject systemMDBlocks = settingsWrapper.getSystemMetadataBlocks();

Long dvIdForInputLevel = datasetVersion.getDataset().getOwner().getId();

if (!dataverseService.find(dvIdForInputLevel).isMetadataBlockRoot()){
Expand Down Expand Up @@ -442,7 +443,7 @@ public void setMetadataValueBlocks(DatasetVersion datasetVersion) {
if (!datasetFieldsForView.isEmpty()) {
metadataBlocksForView.put(mdb, datasetFieldsForView);
}
if (!datasetFieldsForEdit.isEmpty()) {
if (!datasetFieldsForEdit.isEmpty() && !systemMDBlocks.containsKey(mdb.getName())) {
metadataBlocksForEdit.put(mdb, datasetFieldsForEdit);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class MetadataBlockServiceBean {
@PersistenceContext(unitName = "VDCNet-ejbPU")
private EntityManager em;


public static final String SYSTEM_MD_KEY="mdkey";

public MetadataBlock save(MetadataBlock mdb) {
return em.merge(mdb);
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/edu/harvard/iq/dataverse/SettingsWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package edu.harvard.iq.dataverse;

import edu.harvard.iq.dataverse.branding.BrandingUtil;
import edu.harvard.iq.dataverse.settings.JvmSettings;
import edu.harvard.iq.dataverse.settings.Setting;
import edu.harvard.iq.dataverse.settings.SettingsServiceBean;
import edu.harvard.iq.dataverse.settings.SettingsServiceBean.Key;
Expand Down Expand Up @@ -35,6 +36,7 @@
import javax.faces.validator.ValidatorException;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import javax.json.Json;
import javax.json.JsonObject;
import javax.mail.internet.InternetAddress;

Expand Down Expand Up @@ -115,6 +117,8 @@ public class SettingsWrapper implements java.io.Serializable {

private Boolean customLicenseAllowed = null;

private JsonObject systemMetadataBlocks;

private Set<Type> alwaysMuted = null;

private Set<Type> neverMuted = null;
Expand Down Expand Up @@ -700,4 +704,17 @@ public boolean isCustomLicenseAllowed() {
}
return customLicenseAllowed;
}

public JsonObject getSystemMetadataBlocks() {
if (systemMetadataBlocks == null) {
String smdbString = JvmSettings.METADATA_BLOCK_SYSTEM_METADATA_KEYS.lookupOptional().orElse(null);
if (smdbString != null) {
systemMetadataBlocks = JsonUtil.getJsonObject(smdbString);
}
if (systemMetadataBlocks == null) {
systemMetadataBlocks = Json.createObjectBuilder().build();
}
}
return systemMetadataBlocks;
}
}
43 changes: 14 additions & 29 deletions src/main/java/edu/harvard/iq/dataverse/api/Datasets.java
Original file line number Diff line number Diff line change
Expand Up @@ -651,9 +651,6 @@ public Response updateDraftVersion( String jsonBody, @PathParam("id") String id,
}
managedVersion = execCommand(new CreateDatasetVersionCommand(req, ds, incomingVersion));
}
// DatasetVersion managedVersion = execCommand( updateDraft
// ? new UpdateDatasetVersionCommand(req, incomingVersion)
// : new CreateDatasetVersionCommand(req, ds, incomingVersion));
return ok( json(managedVersion) );

} catch (JsonParseException ex) {
Expand Down Expand Up @@ -702,21 +699,19 @@ public Response updateVersionMetadata(String jsonLDBody, @PathParam("id") String
try {
Dataset ds = findDatasetOrDie(id);
DataverseRequest req = createDataverseRequest(findUserOrDie());
DatasetVersion dsv = ds.getOrCreateEditVersion();
//Get draft state as of now
boolean updateDraft = ds.getLatestVersion().isDraft();
//Get the current draft or create a new version to update
DatasetVersion dsv = ds.getOrCreateEditVersion();
dsv = JSONLDUtil.updateDatasetVersionMDFromJsonLD(dsv, jsonLDBody, metadataBlockService, datasetFieldSvc, !replaceTerms, false, licenseSvc);
dsv.getTermsOfUseAndAccess().setDatasetVersion(dsv);
boolean hasValidTerms = TermsOfUseAndAccessValidator.isTOUAValid(dsv.getTermsOfUseAndAccess(), null);
if (!hasValidTerms) {
return error(Status.CONFLICT, BundleUtil.getStringFromBundle("dataset.message.toua.invalid"));
}
DatasetVersion managedVersion;
if (updateDraft) {
Dataset managedDataset = execCommand(new UpdateDatasetVersionCommand(ds, req));
managedVersion = managedDataset.getOrCreateEditVersion();
} else {
managedVersion = execCommand(new CreateDatasetVersionCommand(req, ds, dsv));
}
Dataset managedDataset = execCommand(new UpdateDatasetVersionCommand(ds, req));
managedVersion = managedDataset.getLatestVersion();
String info = updateDraft ? "Version Updated" : "Version Created";
return ok(Json.createObjectBuilder().add(info, managedVersion.getVersionDate()));

Expand All @@ -735,17 +730,15 @@ public Response deleteMetadata(String jsonLDBody, @PathParam("id") String id) {
try {
Dataset ds = findDatasetOrDie(id);
DataverseRequest req = createDataverseRequest(findUserOrDie());
DatasetVersion dsv = ds.getOrCreateEditVersion();
//Get draft state as of now
boolean updateDraft = ds.getLatestVersion().isDraft();
//Get the current draft or create a new version to update
DatasetVersion dsv = ds.getOrCreateEditVersion();
dsv = JSONLDUtil.deleteDatasetVersionMDFromJsonLD(dsv, jsonLDBody, metadataBlockService, licenseSvc);
dsv.getTermsOfUseAndAccess().setDatasetVersion(dsv);
DatasetVersion managedVersion;
if (updateDraft) {
Dataset managedDataset = execCommand(new UpdateDatasetVersionCommand(ds, req));
managedVersion = managedDataset.getOrCreateEditVersion();
} else {
managedVersion = execCommand(new CreateDatasetVersionCommand(req, ds, dsv));
}
Dataset managedDataset = execCommand(new UpdateDatasetVersionCommand(ds, req));
managedVersion = managedDataset.getLatestVersion();
String info = updateDraft ? "Version Updated" : "Version Created";
return ok(Json.createObjectBuilder().add(info, managedVersion.getVersionDate()));

Expand Down Expand Up @@ -773,6 +766,7 @@ private Response processDatasetFieldDataDelete(String jsonBody, String id, Datav

Dataset ds = findDatasetOrDie(id);
JsonObject json = Json.createReader(rdr).readObject();
//Get the current draft or create a new version to update
DatasetVersion dsv = ds.getOrCreateEditVersion();
dsv.getTermsOfUseAndAccess().setDatasetVersion(dsv);
List<DatasetField> fields = new LinkedList<>();
Expand Down Expand Up @@ -884,10 +878,7 @@ private Response processDatasetFieldDataDelete(String jsonBody, String id, Datav
}


boolean updateDraft = ds.getLatestVersion().isDraft();
DatasetVersion managedVersion = updateDraft
? execCommand(new UpdateDatasetVersionCommand(ds, req)).getOrCreateEditVersion()
: execCommand(new CreateDatasetVersionCommand(req, ds, dsv));
DatasetVersion managedVersion = execCommand(new UpdateDatasetVersionCommand(ds, req)).getLatestVersion();
return ok(json(managedVersion));

} catch (JsonParseException ex) {
Expand Down Expand Up @@ -936,6 +927,7 @@ private Response processDatasetUpdate(String jsonBody, String id, DataverseReque

Dataset ds = findDatasetOrDie(id);
JsonObject json = Json.createReader(rdr).readObject();
//Get the current draft or create a new version to update
DatasetVersion dsv = ds.getOrCreateEditVersion();
dsv.getTermsOfUseAndAccess().setDatasetVersion(dsv);
List<DatasetField> fields = new LinkedList<>();
Expand Down Expand Up @@ -1038,14 +1030,7 @@ private Response processDatasetUpdate(String jsonBody, String id, DataverseReque
dsv.getDatasetFields().add(updateField);
}
}
boolean updateDraft = ds.getLatestVersion().isDraft();
DatasetVersion managedVersion;

if (updateDraft) {
managedVersion = execCommand(new UpdateDatasetVersionCommand(ds, req)).getOrCreateEditVersion();
} else {
managedVersion = execCommand(new CreateDatasetVersionCommand(req, ds, dsv));
}
DatasetVersion managedVersion = execCommand(new UpdateDatasetVersionCommand(ds, req)).getLatestVersion();

return ok(json(managedVersion));

Expand Down