diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetFieldServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/DatasetFieldServiceBean.java index 32ce570ddaa..85639de9a59 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetFieldServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetFieldServiceBean.java @@ -944,7 +944,7 @@ private Predicate buildFieldPresentInDataversePredicate(Dataverse dataverse, boo // Predicate for displayOnCreate in input level Predicate displayOnCreateInputLevelPredicate = criteriaBuilder.and( criteriaBuilder.equal(datasetFieldTypeRoot, datasetFieldTypeInputLevelJoin.get("datasetFieldType")), - criteriaBuilder.isTrue(datasetFieldTypeInputLevelJoin.get("displayOnCreate")) + criteriaBuilder.equal(datasetFieldTypeInputLevelJoin.get("displayOnCreate"), Boolean.TRUE) ); // Create a subquery to check for the absence of a specific DataverseFieldTypeInputLevel. @@ -953,7 +953,8 @@ private Predicate buildFieldPresentInDataversePredicate(Dataverse dataverse, boo subquery.select(criteriaBuilder.literal(1L)) .where( criteriaBuilder.equal(subqueryRoot.get("dataverse"), dataverseRoot), - criteriaBuilder.equal(subqueryRoot.get("datasetFieldType"), datasetFieldTypeRoot) + criteriaBuilder.equal(subqueryRoot.get("datasetFieldType"), datasetFieldTypeRoot), + criteriaBuilder.isNotNull(subqueryRoot.get("displayOnCreate")) ); // Define a predicate to exclude DatasetFieldTypes that have no associated input level (i.e., the subquery does not return a result). diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetFieldType.java b/src/main/java/edu/harvard/iq/dataverse/DatasetFieldType.java index e4ada80b05d..32a23e06761 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetFieldType.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetFieldType.java @@ -273,21 +273,35 @@ public void setValidationFormat(String validationFormat) { * Determines whether this field type is displayed in the form when creating * the Dataset (or only later when editing after the initial creation). */ - @Column(name = "displayoncreate", nullable = true) - private Boolean displayOnCreate; + private boolean displayOnCreate; - public Boolean isDisplayOnCreate() { + public boolean isDisplayOnCreate() { return displayOnCreate; } - public Boolean getDisplayOnCreate() { - return displayOnCreate; + public void setDisplayOnCreate(boolean displayOnCreate) { + this.displayOnCreate = displayOnCreate; } - public void setDisplayOnCreate(Boolean displayOnCreate) { - this.displayOnCreate = displayOnCreate; + /** + * Determines whether this field type is displayed in the form when creating + * the Dataset (or only later when editing after the initial creation). + */ + @Transient + private Boolean localDisplayOnCreate; + + public Boolean getLocalDisplayOnCreate() { + return localDisplayOnCreate; + } + + public void setLocalDisplayOnCreate(Boolean localDisplayOnCreate) { + this.localDisplayOnCreate = localDisplayOnCreate; } + public boolean shouldDisplayOnCreate() { + return (localDisplayOnCreate == null) ? displayOnCreate : localDisplayOnCreate; + } + public boolean isControlledVocabulary() { return allowControlledVocabulary; } diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index 8258fb613d3..af8cdc21968 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -1856,7 +1856,10 @@ private void updateDatasetFieldInputLevels() { if (dsf != null){ // Yes, call "setInclude" dsf.setInclude(oneDSFieldTypeInputLevel.isInclude()); - dsf.getDatasetFieldType().setDisplayOnCreate(oneDSFieldTypeInputLevel.isDisplayOnCreate()); + Boolean displayOnCreate = oneDSFieldTypeInputLevel.getDisplayOnCreate(); + if (displayOnCreate!= null) { + dsf.getDatasetFieldType().setLocalDisplayOnCreate(displayOnCreate); + } // remove from hash mapDatasetFields.remove(oneDSFieldTypeInputLevel.getDatasetFieldType().getId()); } diff --git a/src/main/java/edu/harvard/iq/dataverse/Dataverse.java b/src/main/java/edu/harvard/iq/dataverse/Dataverse.java index d2cb51d0072..8ab6f537aca 100644 --- a/src/main/java/edu/harvard/iq/dataverse/Dataverse.java +++ b/src/main/java/edu/harvard/iq/dataverse/Dataverse.java @@ -438,10 +438,17 @@ public boolean isDatasetFieldTypeInInputLevels(Long datasetFieldTypeId) { .anyMatch(inputLevel -> inputLevel.getDatasetFieldType().getId().equals(datasetFieldTypeId)); } + public DataverseFieldTypeInputLevel getDatasetFieldTypeInInputLevels(Long datasetFieldTypeId) { + return dataverseFieldTypeInputLevels.stream() + .filter(inputLevel -> inputLevel.getDatasetFieldType().getId().equals(datasetFieldTypeId)) + .findFirst() + .orElse(null); + } + public boolean isDatasetFieldTypeDisplayOnCreateAsInputLevel(Long datasetFieldTypeId) { return dataverseFieldTypeInputLevels.stream() .anyMatch(inputLevel -> inputLevel.getDatasetFieldType().getId().equals(datasetFieldTypeId) - && inputLevel.isDisplayOnCreate()); + && Boolean.TRUE.equals(inputLevel.getDisplayOnCreate())); } public Template getDefaultTemplate() { diff --git a/src/main/java/edu/harvard/iq/dataverse/DataverseFieldTypeInputLevel.java b/src/main/java/edu/harvard/iq/dataverse/DataverseFieldTypeInputLevel.java index 27cb1e00cad..973a98d246f 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DataverseFieldTypeInputLevel.java +++ b/src/main/java/edu/harvard/iq/dataverse/DataverseFieldTypeInputLevel.java @@ -6,6 +6,8 @@ package edu.harvard.iq.dataverse; import java.io.Serializable; + +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; @@ -38,8 +40,9 @@ , uniqueConstraints={ @UniqueConstraint(columnNames={"dataverse_id", "datasetfieldtype_id"})} , indexes = {@Index(columnList="dataverse_id") - , @Index(columnList="datasetfieldtype_id") - , @Index(columnList="required")} + , @Index(columnList="datasetfieldtype_id") + , @Index(columnList="required") + , @Index(columnList="displayOnCreate")} ) @Entity public class DataverseFieldTypeInputLevel implements Serializable { @@ -58,11 +61,14 @@ public class DataverseFieldTypeInputLevel implements Serializable { private DatasetFieldType datasetFieldType; private boolean include; private boolean required; - private boolean displayOnCreate; + + + @Column(nullable = true) + private Boolean displayOnCreate; public DataverseFieldTypeInputLevel () {} - public DataverseFieldTypeInputLevel (DatasetFieldType fieldType, Dataverse dataverse, boolean required, boolean include, boolean displayOnCreate) { + public DataverseFieldTypeInputLevel (DatasetFieldType fieldType, Dataverse dataverse, boolean required, boolean include, Boolean displayOnCreate) { this.datasetFieldType = fieldType; this.dataverse = dataverse; this.required = required; @@ -117,11 +123,11 @@ public void setRequired(boolean required) { this.required = required; } - public boolean isDisplayOnCreate() { + public Boolean getDisplayOnCreate() { return displayOnCreate; } - public void setDisplayOnCreate(boolean displayOnCreate) { + public void setDisplayOnCreate(Boolean displayOnCreate) { this.displayOnCreate = displayOnCreate; } diff --git a/src/main/java/edu/harvard/iq/dataverse/DataversePage.java b/src/main/java/edu/harvard/iq/dataverse/DataversePage.java index 1f8c3defa7e..4eb9828253d 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DataversePage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DataversePage.java @@ -1025,12 +1025,11 @@ private void loadInputLevels(DatasetFieldType dsft, Long dataverseIdForInputLeve if (dsfIl != null) { dsft.setRequiredDV(dsfIl.isRequired()); dsft.setInclude(dsfIl.isInclude()); - dsft.setDisplayOnCreate(dsfIl.isDisplayOnCreate()); + dsft.setLocalDisplayOnCreate(dsfIl.getDisplayOnCreate()); } else { // If there is no input level, use the default values dsft.setRequiredDV(dsft.isRequired()); dsft.setInclude(true); - dsft.setDisplayOnCreate(false); } } @@ -1317,7 +1316,7 @@ public void updateDisplayOnCreate(Long mdbId, Long dsftId, boolean currentValue) for (DatasetFieldType dsft : mdb.getDatasetFieldTypes()) { if (dsft.getId().equals(dsftId)) { // Update value in memory - dsft.setDisplayOnCreate(!currentValue); + dsft.setLocalDisplayOnCreate(!currentValue); // Update or create input level DataverseFieldTypeInputLevel existingLevel = dataverseFieldTypeInputLevelService @@ -1348,18 +1347,18 @@ private void saveInputLevels(List listDFTIL, Datas .findByDataverseIdDatasetFieldTypeId(dataverse.getId(), dsft.getId()); if (existingLevel != null) { - existingLevel.setDisplayOnCreate(dsft.isDisplayOnCreate()); + existingLevel.setDisplayOnCreate(dsft.getLocalDisplayOnCreate()); existingLevel.setInclude(dsft.isInclude()); existingLevel.setRequired(dsft.isRequiredDV()); listDFTIL.add(existingLevel); - } else if (dsft.isInclude() || dsft.isDisplayOnCreate() || dsft.isRequiredDV()) { + } else if (dsft.isInclude() || (dsft.getLocalDisplayOnCreate()!=null) || dsft.isRequiredDV()) { // Only create new input level if there is any specific configuration listDFTIL.add(new DataverseFieldTypeInputLevel( dsft, dataverse, dsft.isRequiredDV(), dsft.isInclude(), - dsft.isDisplayOnCreate() + dsft.getLocalDisplayOnCreate() )); } } diff --git a/src/main/java/edu/harvard/iq/dataverse/DataverseServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/DataverseServiceBean.java index c56bd2f2956..f89e707cc03 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DataverseServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/DataverseServiceBean.java @@ -961,13 +961,13 @@ public String getCollectionDatasetSchema(String dataverseAlias, Map childrenRequired = new ArrayList<>(); List childrenAllowed = new ArrayList<>(); if (dsft.isHasChildren()) { @@ -976,10 +976,12 @@ public String getCollectionDatasetSchema(String dataverseAlias, Map datasetFieldTypes) { public boolean isDisplayOnCreate() { for (DatasetFieldType dsfType : datasetFieldTypes) { - Boolean displayOnCreate = dsfType.isDisplayOnCreate(); - if (displayOnCreate != null && displayOnCreate) { + boolean shouldDisplayOnCreate = dsfType.shouldDisplayOnCreate(); + if (shouldDisplayOnCreate) { return true; } } diff --git a/src/main/java/edu/harvard/iq/dataverse/MetadataBlockServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/MetadataBlockServiceBean.java index f5bddf3fc79..9a5a1060c50 100644 --- a/src/main/java/edu/harvard/iq/dataverse/MetadataBlockServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/MetadataBlockServiceBean.java @@ -8,6 +8,7 @@ import jakarta.persistence.TypedQuery; import jakarta.persistence.criteria.*; +import java.util.Comparator; import java.util.List; /** @@ -52,68 +53,62 @@ public MetadataBlock findByName(String name) { public List listMetadataBlocksDisplayedOnCreate(Dataverse ownerDataverse) { CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(MetadataBlock.class); - Root metadataBlockRoot = criteriaQuery.from(MetadataBlock.class); - Join datasetFieldTypeJoin = metadataBlockRoot.join("datasetFieldTypes"); - + Root dataverseRoot = criteriaQuery.from(Dataverse.class); + + // Join metadataBlocks from Dataverse + Join metadataBlockJoin = dataverseRoot.join("metadataBlocks"); + + // Join datasetFieldTypes from MetadataBlock + Join datasetFieldTypeJoin = metadataBlockJoin.join("datasetFieldTypes"); + + Predicate displayOnCreatePredicate = criteriaBuilder.isTrue(datasetFieldTypeJoin.get("displayOnCreate")); + Predicate requiredPredicate = criteriaBuilder.isTrue(datasetFieldTypeJoin.get("required")); + if (ownerDataverse != null) { - Root dataverseRoot = criteriaQuery.from(Dataverse.class); - Join datasetFieldTypeInputLevelJoin = - dataverseRoot.join("dataverseFieldTypeInputLevels", JoinType.LEFT); - - // Subquery to check if the input level exists - Subquery inputLevelSubquery = criteriaQuery.subquery(Long.class); - Root subqueryRoot = inputLevelSubquery.from(DataverseFieldTypeInputLevel.class); - inputLevelSubquery.select(criteriaBuilder.literal(1L)) - .where( - criteriaBuilder.equal(subqueryRoot.get("dataverse"), dataverseRoot), - criteriaBuilder.equal(subqueryRoot.get("datasetFieldType"), datasetFieldTypeJoin) - ); - - // Predicate for displayOnCreate in the input level - Predicate displayOnCreateInputLevelPredicate = criteriaBuilder.and( - datasetFieldTypeInputLevelJoin.get("datasetFieldType").in(metadataBlockRoot.get("datasetFieldTypes")), - criteriaBuilder.isNotNull(datasetFieldTypeInputLevelJoin.get("displayOnCreate")), - criteriaBuilder.isTrue(datasetFieldTypeInputLevelJoin.get("displayOnCreate"))); - - // Predicate for required fields - Predicate requiredPredicate = criteriaBuilder.and( - datasetFieldTypeInputLevelJoin.get("datasetFieldType").in(metadataBlockRoot.get("datasetFieldTypes")), - criteriaBuilder.isTrue(datasetFieldTypeInputLevelJoin.get("required"))); - - // Predicate for default displayOnCreate (when there is no input level) - Predicate defaultDisplayOnCreatePredicate = criteriaBuilder.and( - criteriaBuilder.not(criteriaBuilder.exists(inputLevelSubquery)), - criteriaBuilder.or( - criteriaBuilder.isTrue(datasetFieldTypeJoin.get("displayOnCreate")), - criteriaBuilder.isTrue(datasetFieldTypeJoin.get("required")) - )); - - Predicate unionPredicate = criteriaBuilder.or( - displayOnCreateInputLevelPredicate, - requiredPredicate, - defaultDisplayOnCreatePredicate + // Ensure we filter for the specific Dataverse + Predicate dataversePredicate = criteriaBuilder.equal(dataverseRoot.get("id"), ownerDataverse.getId()); + + // Join DataverseFieldTypeInputLevel (LEFT JOIN) + Join datasetFieldTypeInputLevelJoin = + dataverseRoot.join("dataverseFieldTypeInputLevels", JoinType.LEFT); + + // Check if input level explicitly defines displayOnCreate + Predicate inputLevelDisplayPredicate = criteriaBuilder.and( + criteriaBuilder.equal(datasetFieldTypeInputLevelJoin.get("datasetFieldType"), datasetFieldTypeJoin), + criteriaBuilder.isTrue(datasetFieldTypeInputLevelJoin.get("displayOnCreate")) + ); + + // Check if input level explicitly defines required + Predicate inputLevelRequiredPredicate = criteriaBuilder.and( + criteriaBuilder.equal(datasetFieldTypeInputLevelJoin.get("datasetFieldType"), datasetFieldTypeJoin), + criteriaBuilder.isTrue(datasetFieldTypeInputLevelJoin.get("required")) ); - criteriaQuery.where(criteriaBuilder.and( - criteriaBuilder.equal(dataverseRoot.get("id"), ownerDataverse.getId()), - metadataBlockRoot.in(dataverseRoot.get("metadataBlocks")), - unionPredicate - )); + Predicate finalDisplayPredicate = criteriaBuilder.or(inputLevelDisplayPredicate, displayOnCreatePredicate); + Predicate finalRequiredPredicate = criteriaBuilder.or(inputLevelRequiredPredicate, requiredPredicate); + + criteriaQuery.where( + dataversePredicate, + criteriaBuilder.or(finalDisplayPredicate, finalRequiredPredicate) + ); } else { // When ownerDataverse is null, we need to include fields that are either displayOnCreate=true OR required=true - Predicate displayOnCreatePredicate = criteriaBuilder.isTrue(datasetFieldTypeJoin.get("displayOnCreate")); - Predicate requiredPredicate = criteriaBuilder.isTrue(datasetFieldTypeJoin.get("required")); - // We also need to ensure that fields from linked metadata blocks are included Predicate linkedFieldsPredicate = criteriaBuilder.and( - criteriaBuilder.isNotNull(datasetFieldTypeJoin.get("id")), - criteriaBuilder.or(displayOnCreatePredicate, requiredPredicate) + criteriaBuilder.isNotNull(datasetFieldTypeJoin.get("id")), + criteriaBuilder.or(displayOnCreatePredicate, requiredPredicate) ); - + criteriaQuery.where(linkedFieldsPredicate); } - criteriaQuery.select(metadataBlockRoot).distinct(true); - return em.createQuery(criteriaQuery).getResultList(); + criteriaQuery.select(metadataBlockJoin).distinct(true); + + List result = em.createQuery(criteriaQuery).getResultList(); + + // Order by id + result.sort(Comparator.comparing(MetadataBlock::getId)); + + return result; } } diff --git a/src/main/java/edu/harvard/iq/dataverse/TemplatePage.java b/src/main/java/edu/harvard/iq/dataverse/TemplatePage.java index 94ab9e70330..279944beaa7 100644 --- a/src/main/java/edu/harvard/iq/dataverse/TemplatePage.java +++ b/src/main/java/edu/harvard/iq/dataverse/TemplatePage.java @@ -172,10 +172,9 @@ private void updateDatasetFieldInputLevels(){ ); if (dsfIl != null) { dsf.setInclude(dsfIl.isInclude()); - dsf.getDatasetFieldType().setDisplayOnCreate(dsfIl.isDisplayOnCreate()); + dsf.getDatasetFieldType().setLocalDisplayOnCreate(dsfIl.getDisplayOnCreate()); } else { dsf.setInclude(true); - dsf.getDatasetFieldType().setDisplayOnCreate(false); } } } diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java b/src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java index d677ced2ffe..3564a07d984 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java @@ -803,7 +803,10 @@ private List parseInputLevels(JsonArray inputLevel boolean required = inputLevel.getBoolean("required"); boolean include = inputLevel.getBoolean("include"); - boolean displayOnCreate = inputLevel.getBoolean("displayOnCreate", false); + Boolean displayOnCreate = null; + if(inputLevel.containsKey("displayOnCreate")) { + displayOnCreate = inputLevel.getBoolean("displayOnCreate", false); + } if (required && !include) { String errorMessage = MessageFormat.format(BundleUtil.getStringFromBundle("dataverse.inputlevels.error.cannotberequiredifnotincluded"), datasetFieldTypeName); diff --git a/src/main/java/edu/harvard/iq/dataverse/util/json/BriefJsonPrinter.java b/src/main/java/edu/harvard/iq/dataverse/util/json/BriefJsonPrinter.java index 85bfe49846c..83b9d341d6d 100644 --- a/src/main/java/edu/harvard/iq/dataverse/util/json/BriefJsonPrinter.java +++ b/src/main/java/edu/harvard/iq/dataverse/util/json/BriefJsonPrinter.java @@ -25,10 +25,10 @@ public JsonObjectBuilder json( DatasetVersion dsv ) { public JsonObjectBuilder json( MetadataBlock blk ) { if (blk == null) return null; - Boolean displayOnCreate = blk.isDisplayOnCreate(); + boolean displayOnCreate = blk.isDisplayOnCreate(); return jsonObjectBuilder().add("id", blk.getId()) .add("displayName", blk.getDisplayName()) - .add("displayOnCreate", displayOnCreate == null ? false : displayOnCreate) + .add("displayOnCreate", displayOnCreate) .add("name", blk.getName()) ; } diff --git a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java index 53184caeaf4..c3f4d347646 100644 --- a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java +++ b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java @@ -57,7 +57,6 @@ import jakarta.ejb.Singleton; import jakarta.json.JsonArray; import jakarta.json.JsonObject; -import java.util.function.Predicate; /** * Convert objects to Json. @@ -75,14 +74,9 @@ public class JsonPrinter { @EJB static DatasetFieldServiceBean datasetFieldService; - @EJB - static DataverseFieldTypeInputLevelServiceBean datasetFieldInputLevelService; - public static void injectSettingsService(SettingsServiceBean ssb, DatasetFieldServiceBean dfsb, DataverseFieldTypeInputLevelServiceBean dfils) { settingsService = ssb; datasetFieldService = dfsb; - datasetFieldInputLevelService = dfils; - } public JsonPrinter() { @@ -661,35 +655,29 @@ public static JsonObjectBuilder json(MetadataBlock metadataBlock, boolean printO .add("name", metadataBlock.getName()) .add("displayName", metadataBlock.getDisplayName()); - Boolean displayOnCreate = metadataBlock.isDisplayOnCreate(); - jsonObjectBuilder.add("displayOnCreate", displayOnCreate == null ? false : displayOnCreate); + jsonObjectBuilder.add("displayOnCreate", metadataBlock.isDisplayOnCreate()); List datasetFieldTypesList = metadataBlock.getDatasetFieldTypes(); Set datasetFieldTypes = filterOutDuplicateDatasetFieldTypes(datasetFieldTypesList); JsonObjectBuilder fieldsBuilder = Json.createObjectBuilder(); - - - + for (DatasetFieldType datasetFieldType : datasetFieldTypes) { if (!datasetFieldType.isChild()) { - Boolean fieldDisplayOnCreate = datasetFieldType.isDisplayOnCreate(); - Boolean fieldRequired = datasetFieldType.isRequired(); - Boolean fieldExcludedDisplayOnCreateCollection = false; - Boolean fieldIncludedDisplayOnCreateCollection = false; - Boolean fieldExcludedCollection = false; - - if (ownerDataverse != null){ - DataverseFieldTypeInputLevel custom = datasetFieldInputLevelService.findByDataverseIdDatasetFieldTypeId(ownerDataverse.getId(), datasetFieldType.getId() ); - if(custom != null){ - fieldIncludedDisplayOnCreateCollection = custom.isDisplayOnCreate(); - fieldExcludedDisplayOnCreateCollection = !custom.isDisplayOnCreate(); - fieldExcludedCollection = !custom.isInclude(); + DataverseFieldTypeInputLevel level = null; + datasetFieldType.setInclude(true); + if (ownerDataverse != null) { + level = ownerDataverse.getDatasetFieldTypeInInputLevels(datasetFieldType.getId()); + if (level != null) { + datasetFieldType.setLocalDisplayOnCreate(level.getDisplayOnCreate()); + datasetFieldType.setRequiredDV(level.isRequired()); + datasetFieldType.setInclude(level.isInclude()); } } - - if ((!printOnlyDisplayedOnCreateDatasetFieldTypes && !fieldExcludedCollection) || (fieldDisplayOnCreate != null && fieldDisplayOnCreate && !fieldExcludedDisplayOnCreateCollection) - || fieldRequired || fieldIncludedDisplayOnCreateCollection ) { + boolean fieldDisplayOnCreate = datasetFieldType.shouldDisplayOnCreate(); + if (datasetFieldType.isInclude() && (!printOnlyDisplayedOnCreateDatasetFieldTypes + || fieldDisplayOnCreate || datasetFieldType.isRequired() + || (datasetFieldType.isRequiredDV() && (level != null)))) { fieldsBuilder.add(datasetFieldType.getName(), json(datasetFieldType, ownerDataverse)); } } @@ -726,8 +714,7 @@ public static JsonObjectBuilder json(DatasetFieldType fld, Dataverse ownerDatave JsonObjectBuilder fieldsBld = jsonObjectBuilder(); fieldsBld.add("name", fld.getName()); fieldsBld.add("displayName", fld.getDisplayName()); - Boolean displayOnCreate = fld.isDisplayOnCreate(); - fieldsBld.add("displayOnCreate", displayOnCreate == null ? false : displayOnCreate); + fieldsBld.add("displayOnCreate", fld.shouldDisplayOnCreate()); fieldsBld.add("title", fld.getTitle()); fieldsBld.add("type", fld.getFieldType().toString()); fieldsBld.add("typeClass", typeClassString(fld)); @@ -738,8 +725,8 @@ public static JsonObjectBuilder json(DatasetFieldType fld, Dataverse ownerDatave fieldsBld.add("displayFormat", fld.getDisplayFormat()); fieldsBld.add("displayOrder", fld.getDisplayOrder()); - boolean requiredInOwnerDataverse = ownerDataverse != null && ownerDataverse.isDatasetFieldTypeRequiredAsInputLevel(fld.getId()); - fieldsBld.add("isRequired", requiredInOwnerDataverse || fld.isRequired()); + boolean inLevel= ownerDataverse != null && ownerDataverse.isDatasetFieldTypeInInputLevels(fld.getId()); + fieldsBld.add("isRequired", (fld.isRequiredDV() && inLevel) || fld.isRequired()); if (fld.isControlledVocabulary()) { // If the field has a controlled vocabulary, @@ -754,7 +741,20 @@ public static JsonObjectBuilder json(DatasetFieldType fld, Dataverse ownerDatave if (!fld.getChildDatasetFieldTypes().isEmpty()) { JsonObjectBuilder subFieldsBld = jsonObjectBuilder(); for (DatasetFieldType subFld : fld.getChildDatasetFieldTypes()) { - subFieldsBld.add(subFld.getName(), JsonPrinter.json(subFld, ownerDataverse)); + subFld.setInclude(true); + if (ownerDataverse != null) { + DataverseFieldTypeInputLevel childLevel = ownerDataverse + .getDatasetFieldTypeInInputLevels(subFld.getId()); + if (childLevel != null) { + subFld.setLocalDisplayOnCreate(childLevel.getDisplayOnCreate()); + subFld.setRequiredDV(childLevel.isRequired()); + subFld.setInclude(childLevel.isInclude()); + } + } + //This assumes a child have can't be displayOnCreate=false when the parent has it true (i.e. we're not excluding children based on testing displayOnCreate (or required) here.) + if(subFld.isInclude()) { + subFieldsBld.add(subFld.getName(), JsonPrinter.json(subFld, ownerDataverse)); + } } fieldsBld.add("childFields", subFieldsBld); } @@ -1460,7 +1460,7 @@ public static JsonArrayBuilder jsonDataverseFieldTypeInputLevels(List
+ jsf:rendered="#{((editMode == 'METADATA' or dsf.datasetFieldType.shouldDisplayOnCreate() or !dsf.isEmpty() or dsf.required) and dsf.include) or (!datasetPage and dsf.include)}"> diff --git a/src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java b/src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java index 1da6707ed2c..7fde1992d9f 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java @@ -33,6 +33,8 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.hasItemInArray; +import static org.hamcrest.Matchers.hasKey; + import static org.junit.jupiter.api.Assertions.*; import java.nio.file.Files; @@ -1976,6 +1978,14 @@ public void testUpdateInputLevelDisplayOnCreate() { .statusCode(OK.getStatusCode()) .body("data.inputLevels[0].displayOnCreate", equalTo(true)) .body("data.inputLevels[0].datasetFieldTypeName", equalTo("unitOfAnalysis")); + + // Update an inputlevel w/o displayOnCreate set + Response updateResponse2 = UtilIT.updateDataverseInputLevelDisplayOnCreate( + dataverseAlias, "unitOfAnalysis", null, apiToken); + updateResponse2.then().assertThat() + .statusCode(OK.getStatusCode()) + .body("data.inputLevels[0]", not(hasKey("displayOnCreate"))) + .body("data.inputLevels[0].datasetFieldTypeName", equalTo("unitOfAnalysis")); } @Test diff --git a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java index db8a0255017..5ee78a29582 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java @@ -4609,13 +4609,15 @@ public static Response deleteDatasetFiles(String datasetId, JsonArray fileIds, S .put(path); } - public static Response updateDataverseInputLevelDisplayOnCreate(String dataverseAlias, String fieldTypeName, boolean displayOnCreate, String apiToken) { + public static Response updateDataverseInputLevelDisplayOnCreate(String dataverseAlias, String fieldTypeName, Boolean displayOnCreate, String apiToken) { JsonArrayBuilder inputLevelsArrayBuilder = Json.createArrayBuilder(); JsonObjectBuilder inputLevel = Json.createObjectBuilder() .add("datasetFieldTypeName", fieldTypeName) .add("required", false) - .add("include", true) - .add("displayOnCreate", displayOnCreate); + .add("include", true); + if(displayOnCreate != null) { + inputLevel.add("displayOnCreate", displayOnCreate); + } inputLevelsArrayBuilder.add(inputLevel); diff --git a/src/test/java/edu/harvard/iq/dataverse/engine/command/impl/CreateDataverseCommandTest.java b/src/test/java/edu/harvard/iq/dataverse/engine/command/impl/CreateDataverseCommandTest.java index 24c349d34d1..73880b78e7b 100644 --- a/src/test/java/edu/harvard/iq/dataverse/engine/command/impl/CreateDataverseCommandTest.java +++ b/src/test/java/edu/harvard/iq/dataverse/engine/command/impl/CreateDataverseCommandTest.java @@ -150,11 +150,11 @@ public DataverseFieldTypeInputLevel findByDataverseIdDatasetFieldTypeId(Long dat } - @Override public void deleteDataverseFieldTypeInputLevelFor(Dataverse d) { dftilsDeleted = true; } + }; DataverseFacetServiceBean facets = new DataverseFacetServiceBean() {