Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/release-notes/7956-display original file name
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This release changes the display behavior for tabular files to show the original file name and metadata, and to allow editing of the original file name. The ingested *.tab version is still available from the download menu.

2 changes: 1 addition & 1 deletion src/main/java/edu/harvard/iq/dataverse/DataCitation.java
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public DataCitation(FileMetadata fm, boolean direct) {
getCommonValuesFrom(dsv);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll just put this here at the top...

@qqmyers could you please add a release note snippet?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

// file Title for direct File citation
fileTitle = fm.getLabel();
fileTitle = fm.getLabelForOriginal();
DataFile df = fm.getDataFile();

// File description
Expand Down
15 changes: 12 additions & 3 deletions src/main/java/edu/harvard/iq/dataverse/DataFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,11 @@ public Long getOriginalFileSize() {
return null;
}

public String getFriendlyOriginalFileSize() {
Long size = (getOriginalFileSize()==null) ? filesize : getOriginalFileSize();
return getFriendlySize(size);
}

public String getOriginalFileName() {
if (isTabularData()) {
DataTable dataTable = getDataTable();
Expand All @@ -539,7 +544,7 @@ public String getOriginalFileName() {
}


private String getDerivedOriginalFileName() {
public String getDerivedOriginalFileName() {
FileMetadata fm = getFileMetadata();
String filename = fm.getLabel();
String originalExtension = FileUtil.generateOriginalExtension(getOriginalFileFormat());
Expand Down Expand Up @@ -689,8 +694,12 @@ public void setFilesize(long filesize) {
* @return
*/
public String getFriendlySize() {
if (filesize != null) {
return FileSizeChecker.bytesToHumanReadable(filesize);
return getFriendlySize(filesize);
}

private String getFriendlySize(Long size) {
if (size != null) {
return FileSizeChecker.bytesToHumanReadable(size);
} else {
return BundleUtil.getStringFromBundle("file.sizeNotAvailable");
}
Expand Down
34 changes: 34 additions & 0 deletions src/main/java/edu/harvard/iq/dataverse/FileLabelValidator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package edu.harvard.iq.dataverse;

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FileLabelValidator implements ConstraintValidator<ValidateDataFileLabel, String> {

@Override
public void initialize(ValidateDataFileLabel constraintAnnotation) {

}

@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return isFileLabelValid(value, context);

}

public static boolean isFileLabelValid(String value, ConstraintValidatorContext context) {

if (value == null || value.isEmpty()) {
return true;
}
String validCharacters = "^[^:<>;#/\"\\*\\|\\?\\\\]*$";
Pattern p = Pattern.compile(validCharacters);
Matcher m = p.matcher(value);
return m.matches();

}

}
46 changes: 46 additions & 0 deletions src/main/java/edu/harvard/iq/dataverse/FileMetadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import jakarta.persistence.NamedNativeQuery;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OrderBy;
import jakarta.persistence.PostLoad;
import jakarta.persistence.SqlResultSetMapping;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
Expand Down Expand Up @@ -153,6 +154,18 @@ public class FileMetadata implements Serializable {
@OneToMany (mappedBy="fileMetadata", cascade={ CascadeType.REMOVE, CascadeType.MERGE,CascadeType.PERSIST})
private Collection<VariableMetadata> variableMetadatas;

// A transient field is needed for JSF UI - validation errors on label do not get routed directly to the input for labelNoExtension, causing rollback.
// With a separate transient field kept in sync with label, the validation can be done on the labelNoExtension field, which avoids the issue and allows proper validation.
@Transient
@ValidateDataFileLabel(message = "{filename.illegalCharacters}")
String labelNoExtension;

// Initialize the labelNoExtension from label after loading the entity
@PostLoad
public void postLoad() {
getLabelNoExtension();
}

/**
* Creates a copy of {@code this}, with identical business logic fields, making the bi-drectional connections to the specified version.
*
Expand All @@ -173,13 +186,46 @@ public FileMetadata createCopyInVersion(DatasetVersion dsv) {
}

public String getLabel() {
getLabelNoExtension();
return label;
}

public void setLabel(String label) {
this.label = label;
getLabelNoExtension();
}


public String getLabelNoExtension() {
int last = label.lastIndexOf(".");
labelNoExtension = (last == -1) ? label : label.substring(0, last);
return labelNoExtension;
}

public String getOriginalExtension() {
String origFilename = getLabelForOriginal();
int last = origFilename.lastIndexOf(".");
return (last == -1) ? "" : origFilename.substring(last);
}

public void setLabelNoExtension(String name) {
labelNoExtension = name;
int last = this.label.lastIndexOf(".");
if (last == -1) {
this.label = name;
} else {
this.label = name + this.label.substring(last);
}
}

public String getLabelForOriginal() {
if(dataFile.isTabularData()) {
return dataFile.getDerivedOriginalFileName();
} else {
return label;
}
}

public FileMetadata() {
variableMetadatas = new ArrayList<VariableMetadata>();
varGroups = new ArrayList<VarGroup>();
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/edu/harvard/iq/dataverse/ValidateDataFileLabel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package edu.harvard.iq.dataverse;

import jakarta.validation.Constraint;
import jakarta.validation.Payload;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = {FileLabelValidator.class})
@Documented
public @interface ValidateDataFileLabel {

String message() default "Failed Validation for Validate Data File Label";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

}
7 changes: 4 additions & 3 deletions src/main/webapp/editFilesFragment.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -424,13 +424,14 @@
</div>
</div>
<div class="col-md-10 file-metadata-block">
<label class="control-label" for="datasetForm:filesTable:#{rowNum}:fileName" style="margin-right:1em;margin-bottom:.5em;">
<label class="control-label" jsf:for="fileName" style="margin-right:1em;margin-bottom:.5em;">
#{bundle['file.fileName']}
</label>
<p:inputText id="fileName" value="#{fileMetadata.label}" style="width:60%; margin-bottom:.5em;" disabled="#{fileMetadata.dataFile.filePackage}"/>
<p:inputText id="fileName" value="#{fileMetadata.labelNoExtension}" style="width:60%; margin-bottom:.5em;" disabled="#{fileMetadata.dataFile.filePackage}"/>
<h:outputText value="#{fileMetadata.originalExtension}"/>
<p:message for="datasetForm:filesTable:#{rowNum}:fileName"/>

<label class="control-label" for="datasetForm:filesTable:#{rowNum}:fileDirectoryName" style="margin-right:1em;margin-bottom:.5em;">
<label class="control-label" jsf:for="fileDirectoryName" style="margin-right:1em;margin-bottom:.5em;">
#{bundle['file.metadataTab.fileMetadata.hierarchy.label']}
<span class="glyphicon glyphicon-question-sign tooltip-icon"
data-toggle="tooltip" data-placement="auto right" data-original-title="#{bundle['file.metadataTab.fileMetadata.hierarchy.tip']}"></span>
Expand Down
13 changes: 7 additions & 6 deletions src/main/webapp/file-info-fragment.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,19 @@
<ui:fragment rendered="#{!editDatafilesPage}">
<!-- conditional render in file page links, if file has global id, use that; if not, we use database id -->
<a href="#{widgetWrapper.wrapURL('/file.xhtml?'.concat(fileIdParam).concat(fileIdValue).concat('&amp;version=').concat(fileMetadata.datasetVersion.friendlyVersionNumber))}">
#{fileMetadata.label}
#{fileMetadata.labelForOriginal}
</a>
</ui:fragment>
<ui:fragment rendered="#{editDatafilesPage}">
<span>#{fileMetadata.label}</span>
<span>#{fileMetadata.labelForOriginal}</span>
</ui:fragment>
</div>
<!-- HIERARCHY + TYPE + SIZE + DATE + CHECKSUM -->
<div class="text-muted small">
<!-- id:#{dataFile.id} -->
<!-- id:#{fileMetadata.dataFile.id} -->
<h:outputText id="fileHierarchy" styleClass="show" value="#{fileMetadata.directoryLabel}/" rendered="#{hasDirectoryLabel}"/>
<h:outputText id="fileType" value="#{dataFile.tabularData ? bundle['file.type.tabularData'] : dataFile.friendlyType}"/>
<h:outputText id="fileSize" value=" - #{dataFile.friendlySize}"/>
<h:outputText id="fileType" value="#{dataFile.friendlyType}"/>
<h:outputText id="fileSize" value=" - #{dataFile.friendlyOriginalFileSize}"/>
<div class="dateCreatePublish-block">
<h:outputText id="fileCreatePublishDate" value="#{isReleased ? ((dataFile.embargo!=null) ? bundle['metadatareleased'] : bundle['published']) : bundle['deposited']} #{fileMetadata.getFileDateToDisplay()}" rendered="#{hasFileId}"/>
<h:outputText id="embargoDate" class="embargoright" value="#{isReleased ? ((dataFileServiceBean.isActivelyEmbargoed(fileMetadata)) ? bundle['embargoed.until'] : bundle['embargoed.wasthrough']):bundle['embargoed.willbeuntil']} #{dataFile.embargo.formattedDateAvailable}" rendered="#{hasEmbargo}"/>
Expand All @@ -91,7 +91,7 @@
</h:outputFormat>
</div>
<!-- CHECKSUM -->
<div class="checksum-block" jsf:rendered="#{!dataFile.tabularData and !(empty dataFile.checksumValue)}">
<div class="checksum-block" jsf:rendered="#{!(empty dataFile.checksumValue)}">
<span class="#{!editDatafilesPage ? 'checksum-truncate checksum-tooltip' : ''}" style="margin-right:3px;"
data-toggle="tooltip" data-placement="top" data-html="true"
data-clipboard-action="copy"
Expand All @@ -105,6 +105,7 @@
</div>
<!-- TABULAR VARIABLES, OBSERVATIONS + UNF -->
<div class="unf-block" jsf:rendered="#{isTabularData}">
<h:outputText value="#{bundle['file.type.tabularData']}: "/>
<h:outputText id="fileNumVars" value="#{dataFile.dataTable.varQuantity} #{bundle['file.metaData.dataFile.dataTab.variables']}, "/>
<h:outputText id="fileNumObs" value="#{dataFile.dataTable.caseQuantity} #{bundle['file.metaData.dataFile.dataTab.observations']} "/>
<span jsf:id="fileUNF" class="#{!editDatafilesPage ? 'checksum-truncate checksum-tooltip' : ''}" style="margin-right:3px;"
Expand Down
6 changes: 3 additions & 3 deletions src/main/webapp/file.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
<div class="col-xs-12">
<div class="row">
<div id="file-title-block" class="col-xs-12 margin-bottom-half">
<span class="file-title-label">#{FilePage.fileMetadata.label}</span>
<span class="file-title-label">#{FilePage.fileMetadata.labelForOriginal}</span>

<!-- FILE LEVEL MSGs -->
<div class="bg-info text-info text-center margin-bottom-half" jsf:rendered="#{FilePage.fileMetadata.dataFile.ingestProblem and FilePage.canUpdateDataset()}">
Expand Down Expand Up @@ -590,11 +590,11 @@
<td>#{FilePage.file.retention.reason}
</td>
</tr>
<tr id="fileSizeBlock" jsf:rendered="#{!(empty FilePage.file.friendlySize)}">
<tr id="fileSizeBlock" jsf:rendered="#{!(empty FilePage.file.friendlyOriginalFileSize)}">
<th scope="row">
#{bundle['file.metadataTab.fileMetadata.size.label']}
</th>
<td>#{FilePage.file.friendlySize}</td>
<td>#{FilePage.file.friendlyOriginalFileSize}</td>
</tr>
<tr id="fileTypeBlock" jsf:rendered="#{!(empty FilePage.file.friendlyType)}">
<th scope="row">
Expand Down
Loading