-
Notifications
You must be signed in to change notification settings - Fork 4
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
Download the search result as a file in a selected format #2581
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -110,6 +110,8 @@ public class DatasetFieldType implements Serializable, Comparable<DatasetFieldTy | |
private int displayOrder; | ||
|
||
private String displayFormat; | ||
|
||
private boolean exportToFile = false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Redundant assignment as false is be default. |
||
|
||
/** Determines whether an instance of this field type may have multiple values. */ | ||
private boolean allowMultiples; | ||
|
@@ -184,6 +186,12 @@ public boolean isRequiredInDataverse() { | |
public String getDisplayFormat() { | ||
return displayFormat; | ||
} | ||
|
||
|
||
public boolean isExportToFile() { | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Empty line do not fit overall code style. Please remove it. |
||
return this.exportToFile; | ||
} | ||
|
||
public int getDisplayOrder() { | ||
return this.displayOrder; | ||
|
@@ -506,6 +514,11 @@ public void setRequiredInDataverse(boolean requiredInDataverse) { | |
public void setDisplayFormat(String displayFormat) { | ||
this.displayFormat = displayFormat; | ||
} | ||
|
||
public void setExportToFile(final boolean exportToFile) { | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Empty line, as above's. Please remove it. |
||
this.exportToFile = exportToFile; | ||
} | ||
|
||
public void setDisplayOrder(int displayOrder) { | ||
this.displayOrder = displayOrder; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -205,6 +205,18 @@ public List<DatasetField> getDatasetFields() { | |
public List<DatasetField> getDatasetFieldsOptional() { | ||
return datasetFieldsOptional; | ||
} | ||
|
||
public List<DatasetField> getDatasetFieldsAll() { | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Empty line. Please remove it. |
||
if (getDatasetFieldsOptional().isEmpty()) { | ||
return getDatasetFields(); | ||
} else { | ||
final List<DatasetField> result = new ArrayList<DatasetField>( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the point of that final declaration? Seems redundant. |
||
getDatasetFields()); | ||
result.addAll(getDatasetFieldsOptional()); | ||
return result; | ||
} | ||
} | ||
|
||
public Date getArchiveTime() { | ||
return archiveTime; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -573,6 +573,13 @@ dashboard.card.maximumembargo.save.success=Maximum embargo length settings have | |
dashboard.card.maximumembargo.save.failure=Maximum embargo length settings have not been saved. | ||
dashboard.card.maximumembargo.notSet.header=Not Set | ||
dashboard.card.maximumembargo.notSet.text=No Maximum | ||
dashboard.card.exportsearchresults.header=Export search results | ||
dashboard.card.exportsearchresults.button=Manage | ||
dashboard.card.exportsearchresults.manage=Manage exported metadata | ||
dashboard.card.exportsearchresults.name=Name | ||
dashboard.card.exportsearchresults.desc=Description | ||
dashboard.card.exportsearchresults.exported=Exported to file | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please remove empty line. |
||
|
||
#dasboard-licenses.xhtml | ||
dashboard.license.header=Licenses | ||
|
@@ -1052,6 +1059,7 @@ dataverse.results.header=Search results | |
dataverse.results.btn.addData=Add Data | ||
dataverse.results.btn.addData.newDataverse=New Dataverse | ||
dataverse.results.btn.addData.newDataset=New Dataset | ||
dataverse.results.btn.saveToFile=Safe to file | ||
dataverse.results.dialog.addDataGuest.header=Add Data | ||
dataverse.results.dialog.addDataGuest.msg=You need to <a href="/loginpage.xhtml{0}" title="Log into your Dataverse Account">Log In</a> to create a dataverse or add a dataset. | ||
dataverse.results.dialog.addDataGuest.msg.signup=You need to <a href="/loginpage.xhtml{0}" title="Log into or sign up for your Dataverse Account">Log In/Sign Up</a> to create a dataverse or add a dataset. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
alter table datasetfieldtype add column exportToFile boolean not null default false; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
package edu.harvard.iq.dataverse.dashboard; | ||
|
||
import static java.lang.Boolean.FALSE; | ||
import static java.util.Comparator.comparing; | ||
import static java.util.stream.Collectors.toList; | ||
import static org.apache.commons.lang.StringUtils.EMPTY; | ||
|
||
import java.io.Serializable; | ||
import java.util.List; | ||
|
||
import javax.inject.Inject; | ||
import javax.inject.Named; | ||
|
||
import org.omnifaces.cdi.ViewScoped; | ||
|
||
import edu.harvard.iq.dataverse.DataverseDao; | ||
import edu.harvard.iq.dataverse.DataverseSession; | ||
import edu.harvard.iq.dataverse.PermissionsWrapper; | ||
import edu.harvard.iq.dataverse.persistence.dataset.DatasetFieldType; | ||
import edu.harvard.iq.dataverse.persistence.dataset.DatasetFieldTypeRepository; | ||
import edu.harvard.iq.dataverse.util.SystemConfig; | ||
|
||
@ViewScoped | ||
@Named("ExportSearchResultsPage") | ||
public class DashboardExportSearchResultsPage implements Serializable { | ||
|
||
// ------------------------------------------------------------------------- | ||
public static class Metadata { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Private? End on the bottom of class? |
||
|
||
private final Long id; | ||
private final String title; | ||
private final String description; | ||
private boolean exportable; | ||
|
||
// --------------------------------------------------------------------- | ||
private Metadata(final DatasetFieldType fieldType) { | ||
|
||
this.id = fieldType.getId(); | ||
this.title = fieldType.getTitle(); | ||
this.description = fieldType.getDescription(); | ||
this.exportable = fieldType.isExportToFile(); | ||
} | ||
|
||
// --------------------------------------------------------------------- | ||
public boolean isExportable() { | ||
|
||
return this.exportable; | ||
} | ||
|
||
// --------------------------------------------------------------------- | ||
public void setExportable(final boolean exportable) { | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please remove empty lines in each case here. |
||
this.exportable = exportable; | ||
} | ||
|
||
// --------------------------------------------------------------------- | ||
public Long getId() { | ||
|
||
return this.id; | ||
} | ||
|
||
// --------------------------------------------------------------------- | ||
public String getTitle() { | ||
|
||
return this.title; | ||
} | ||
|
||
// --------------------------------------------------------------------- | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Whats is the purpose of comments like: |
||
public String getDescription() { | ||
|
||
return this.description; | ||
} | ||
} | ||
|
||
// ------------------------------------------------------------------------- | ||
private final DataverseSession session; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Those fields belongs main class, should be at the top? |
||
private final PermissionsWrapper permissionsWrapper; | ||
private final DataverseDao dataverseDao; | ||
private final SystemConfig systemConfig; | ||
private final DatasetFieldTypeRepository datasetFiledTypeRepo; | ||
|
||
private List<Metadata> metadataTypes; | ||
|
||
// ------------------------------------------------------------------------- | ||
@Inject | ||
public DashboardExportSearchResultsPage(final DataverseSession session, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same for constructor should be at the top of class after fields right? |
||
final PermissionsWrapper permissionsWrapper, | ||
final DataverseDao dataverseDao, final SystemConfig systemConfig, | ||
final DatasetFieldTypeRepository datasetFiledTypeRepo) { | ||
|
||
this.session = session; | ||
this.permissionsWrapper = permissionsWrapper; | ||
this.dataverseDao = dataverseDao; | ||
this.systemConfig = systemConfig; | ||
this.datasetFiledTypeRepo = datasetFiledTypeRepo; | ||
} | ||
|
||
// ------------------------------------------------------------------------- | ||
public List<Metadata> getMetadataTypes() { | ||
|
||
return this.metadataTypes; | ||
} | ||
|
||
// ------------------------------------------------------------------------- | ||
public String init() { | ||
|
||
if (canEdit()) { | ||
initMetadataTypes(); | ||
return EMPTY; | ||
} else { | ||
return this.permissionsWrapper.notAuthorized(); | ||
} | ||
} | ||
|
||
// ------------------------------------------------------------------------- | ||
private void initMetadataTypes() { | ||
|
||
this.metadataTypes = this.datasetFiledTypeRepo.findAll().stream() | ||
.map(Metadata::new).sorted(comparing(Metadata::getTitle)) | ||
.collect(toList()); | ||
} | ||
|
||
// ------------------------------------------------------------------------- | ||
private boolean canEdit() { | ||
|
||
return !this.systemConfig.isReadonlyMode() | ||
&& this.session.getUser().isSuperuser(); | ||
} | ||
|
||
// ------------------------------------------------------------------------- | ||
public String save() { | ||
|
||
for (final DatasetFieldType fieldType : this.datasetFiledTypeRepo.findAll()) { | ||
fieldType.setExportToFile(isExportedToFile(fieldType.getId())); | ||
this.datasetFiledTypeRepo.save(fieldType); | ||
} | ||
|
||
return EMPTY; | ||
} | ||
|
||
// ------------------------------------------------------------------------- | ||
private boolean isExportedToFile(final Long id) { | ||
|
||
return this.metadataTypes.stream().filter(mt -> mt.getId().equals(id)) | ||
.findFirst().map(Metadata::isExportable).orElse(FALSE); | ||
} | ||
|
||
// ------------------------------------------------------------------------- | ||
public String cancel() { | ||
|
||
return "/dashboard.xhtml?faces-redirect=true&dataverseId=" | ||
+ this.dataverseDao.findRootDataverse().getId(); | ||
} | ||
// ------------------------------------------------------------------------- | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package edu.harvard.iq.dataverse.search; | ||
|
||
import static java.util.Comparator.comparing; | ||
import static java.util.stream.Collectors.toList; | ||
|
||
import java.io.ByteArrayInputStream; | ||
import java.io.ByteArrayOutputStream; | ||
import java.io.IOException; | ||
import java.io.OutputStream; | ||
import java.io.OutputStreamWriter; | ||
import java.util.List; | ||
|
||
import org.apache.commons.csv.CSVFormat; | ||
import org.apache.commons.csv.CSVPrinter; | ||
import org.primefaces.model.DefaultStreamedContent; | ||
import org.primefaces.model.StreamedContent; | ||
|
||
import edu.harvard.iq.dataverse.persistence.dataset.DatasetField; | ||
import edu.harvard.iq.dataverse.persistence.dataset.DatasetFieldType; | ||
import edu.harvard.iq.dataverse.persistence.dataset.DatasetFieldTypeRepository; | ||
import edu.harvard.iq.dataverse.persistence.dataset.DatasetRepository; | ||
import edu.harvard.iq.dataverse.search.response.SolrSearchResult; | ||
|
||
public final class CSVResultPrinter { | ||
|
||
private final DatasetRepository datasetRepo; | ||
private final List<DatasetFieldType> exportedFields; | ||
|
||
private final static CSVFormat format = CSVFormat.DEFAULT.builder().build(); | ||
|
||
// ------------------------------------------------------------------------- | ||
public CSVResultPrinter(final DatasetRepository datasetRepo, | ||
final DatasetFieldTypeRepository datasetFieldTypeRepo) { | ||
|
||
this.datasetRepo = datasetRepo; | ||
this.exportedFields = datasetFieldTypeRepo.findAll().stream() | ||
.filter(DatasetFieldType::isExportToFile) | ||
.sorted(comparing(DatasetFieldType::getTitle)).collect(toList()); | ||
} | ||
|
||
// ------------------------------------------------------------------------- | ||
public StreamedContent print(final List<SolrSearchResult> results) { | ||
|
||
try { | ||
final ByteArrayOutputStream content = new ByteArrayOutputStream(4000); | ||
|
||
try (final CSVPrinter printer = newPrinter(content)) { | ||
printHeaders(printer); | ||
printer.println(); | ||
|
||
for (final SolrSearchResult result : results) { | ||
printer.print(result.getId()); | ||
printer.print(result.getName()); | ||
printer.print(result.getTitle()); | ||
if (result.isDataset()) { | ||
printMetadata(printer, result); | ||
} | ||
printer.println(); | ||
} | ||
} | ||
|
||
return DefaultStreamedContent.builder().name("searchResults.csv") | ||
.contentLength(content.size()).contentEncoding("utf-8") | ||
.contentType("text/csv") | ||
.stream(() -> new ByteArrayInputStream(content.toByteArray())) | ||
.build(); | ||
} catch (final IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
// ------------------------------------------------------------------------- | ||
private void printHeaders(final CSVPrinter printer) throws IOException { | ||
|
||
printer.print("Id"); | ||
printer.print("Name"); | ||
printer.print("Title"); | ||
for (final DatasetFieldType type : this.exportedFields) { | ||
printer.print(type.getTitle()); | ||
} | ||
} | ||
|
||
// ------------------------------------------------------------------------- | ||
private void printMetadata(final CSVPrinter printer, final SolrSearchResult result) | ||
throws IOException { | ||
|
||
final List<DatasetField> fields = getAllFieldsOfLatestVersionOf( | ||
result.getEntityId()); | ||
|
||
for (final DatasetFieldType type : this.exportedFields) { | ||
printer.print(get(fields, type)); | ||
} | ||
} | ||
|
||
// ------------------------------------------------------------------------- | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ? |
||
private List<DatasetField> getAllFieldsOfLatestVersionOf(final Long datasetId) { | ||
|
||
return this.datasetRepo.getById(datasetId).getLatestVersion() | ||
.getDatasetFieldsAll(); | ||
} | ||
|
||
// ------------------------------------------------------------------------- | ||
private static String get(final List<DatasetField> fields, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Get of what? Better name please. |
||
final DatasetFieldType type) { | ||
|
||
return fields.stream().filter(f -> f.isOfType(type)).findAny() | ||
.map(DatasetField::getDisplayValue).orElse(null); | ||
} | ||
|
||
// ------------------------------------------------------------------------- | ||
private CSVPrinter newPrinter(final OutputStream output) throws IOException { | ||
|
||
return new CSVPrinter(new OutputStreamWriter(output, "utf-8"), format); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This empty line do not fit Dataverse coding style. Should be removed.