diff --git a/conf/solr/4.6.0/schema.xml b/conf/solr/4.6.0/schema.xml index 2577c3b27f4..034e3f23994 100644 --- a/conf/solr/4.6.0/schema.xml +++ b/conf/solr/4.6.0/schema.xml @@ -269,6 +269,10 @@ + + + + @@ -412,7 +416,8 @@ - + + diff --git a/doc/Sphinx/source/User/appendix.rst b/doc/Sphinx/source/User/appendix.rst index 7e62c4745e8..8c16e9bcd2f 100644 --- a/doc/Sphinx/source/User/appendix.rst +++ b/doc/Sphinx/source/User/appendix.rst @@ -16,7 +16,7 @@ currently proposed metadata fields for 4.0 (per metadata block): - `Citation Metadata `__ (compliant with `DDI 2.5 `__ and `DataCite 3.0 `__) - `Social Science & Humanities Metadata (DDI 2.5 compliant) `__ - `Astronomy and Astrophysics Metadata `__ - (based on `Virtual Observatory (VO) Discovery and Provenance Metadata `__) + : These metadata elements can be mapped/exported to the International Virtual Observatory Alliance’s (IVOA) Resource Metadata for the Virtual Observatory (VOResource Schema format) and based on `Virtual Observatory (VO) Discovery and Provenance Metadata `__) - `Biomedical Metadata `__ (based on `ISA-Tab `__ and `Stem Cell Commons `__) diff --git a/scripts/search/data/tabular/50by1000.dta b/scripts/search/data/tabular/50by1000.dta new file mode 100644 index 00000000000..2cbadda3f6d Binary files /dev/null and b/scripts/search/data/tabular/50by1000.dta differ diff --git a/src/main/java/edu/harvard/iq/dataverse/AdvancedSearchPage.java b/src/main/java/edu/harvard/iq/dataverse/AdvancedSearchPage.java index 1c0a8296949..19382e5d246 100644 --- a/src/main/java/edu/harvard/iq/dataverse/AdvancedSearchPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/AdvancedSearchPage.java @@ -35,6 +35,8 @@ public class AdvancedSearchPage { private String fileFieldName; private String fileFieldDescription; private String fileFieldFiletype; + private String fileFieldVariableName; + private String fileFieldVariableLabel; public void init() { /** @@ -115,6 +117,14 @@ private String constructFileQuery() { queryStrings.add(constructQuery(SearchFields.FILE_TYPE_SEARCHABLE, fileFieldFiletype)); } + if (!fileFieldVariableName.isEmpty()) { + queryStrings.add(constructQuery(SearchFields.VARIABLE_NAME, fileFieldVariableName)); + } + + if (!fileFieldVariableLabel.isEmpty()) { + queryStrings.add(constructQuery(SearchFields.VARIABLE_LABEL, fileFieldVariableLabel)); + } + return constructQuery(queryStrings, true); } @@ -256,4 +266,20 @@ public void setFileFieldFiletype(String fileFieldFiletype) { this.fileFieldFiletype = fileFieldFiletype; } + public String getFileFieldVariableName() { + return fileFieldVariableName; + } + + public void setFileFieldVariableName(String fileFieldVariableName) { + this.fileFieldVariableName = fileFieldVariableName; + } + + public String getFileFieldVariableLabel() { + return fileFieldVariableLabel; + } + + public void setFileFieldVariableLabel(String fileFieldVariableLabel) { + this.fileFieldVariableLabel = fileFieldVariableLabel; + } + } diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index 85143efc1de..600013712cc 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -322,7 +322,7 @@ public void refresh(ActionEvent e) { // .getLatestVersion().getFileMetadatas() - because that's how the page is // accessing them. -- L.A.) //for (DataFile dataFile : dataset.getFiles()) { - for (FileMetadata fileMetadata : dataset.getLatestVersion().getFileMetadatas()) { + for (FileMetadata fileMetadata : getDisplayVersion().getFileMetadatas()) { DataFile dataFile = fileMetadata.getDataFile(); // and see if any are marked as "ingest-in-progress": if (dataFile.isIngestInProgress()) { diff --git a/src/main/java/edu/harvard/iq/dataverse/IndexServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/IndexServiceBean.java index 778bae848df..2746892bec5 100644 --- a/src/main/java/edu/harvard/iq/dataverse/IndexServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/IndexServiceBean.java @@ -714,6 +714,7 @@ private String addOrUpdateDataset(IndexableDataset indexableDataset) { datafileSolrInputDocument.addField(SearchFields.FILE_TYPE, FileUtil.getFacetFileType(fileMetadata.getDataFile())); datafileSolrInputDocument.addField(SearchFields.FILE_TYPE_SEARCHABLE, FileUtil.getFacetFileType(fileMetadata.getDataFile())); datafileSolrInputDocument.addField(SearchFields.DESCRIPTION, fileMetadata.getDescription()); + datafileSolrInputDocument.addField(SearchFields.FILE_DESCRIPTION, fileMetadata.getDescription()); datafileSolrInputDocument.addField(SearchFields.SUBTREE, dataversePaths); // datafileSolrInputDocument.addField(SearchFields.HOST_DATAVERSE, dataFile.getOwner().getOwner().getName()); // datafileSolrInputDocument.addField(SearchFields.PARENT_NAME, dataFile.getDataset().getTitle()); @@ -727,11 +728,8 @@ private String addOrUpdateDataset(IndexableDataset indexableDataset) { if (fileMetadata.getDataFile().isTabularData()) { List variables = fileMetadata.getDataFile().getDataTable().getDataVariables(); - String variableNamesToIndex = null; - String variableLabelsToIndex = null; for (DataVariable var : variables) { // Hard-coded search fields, for now: - // TODO: immediately: define these as constants in SearchFields; // TODO: eventually: review, decide how datavariables should // be handled for indexing purposes. (should it be a fixed // setup, defined in the code? should it be flexible? unlikely @@ -741,28 +739,12 @@ private String addOrUpdateDataset(IndexableDataset indexableDataset) { // anyway -- needs to be reviewed. -- L.A. 4.0alpha1 if (var.getName() != null && !var.getName().equals("")) { - if (variableNamesToIndex == null) { - variableNamesToIndex = var.getName(); - } else { - variableNamesToIndex = variableNamesToIndex + " " + var.getName(); - } + datafileSolrInputDocument.addField(SearchFields.VARIABLE_NAME, var.getName()); } if (var.getLabel() != null && !var.getLabel().equals("")) { - if (variableLabelsToIndex == null) { - variableLabelsToIndex = var.getLabel(); - } else { - variableLabelsToIndex = variableLabelsToIndex + " " + var.getLabel(); - } + datafileSolrInputDocument.addField(SearchFields.VARIABLE_LABEL, var.getLabel()); } } - if (variableNamesToIndex != null) { - logger.info("indexing " + variableNamesToIndex.length() + " bytes"); - datafileSolrInputDocument.addField("varname_s", variableNamesToIndex); - } - if (variableLabelsToIndex != null) { - logger.info("indexing " + variableLabelsToIndex.length() + " bytes"); - datafileSolrInputDocument.addField("varlabel_s", variableLabelsToIndex); - } } docs.add(datafileSolrInputDocument); @@ -991,7 +973,8 @@ private List findSolrDocIdsForDraftFilesToDelete(Dataset datasetWithDraf Long datasetId = datasetWithDraftFilesToDelete.getId(); SolrServer solrServer = new HttpSolrServer("http://localhost:8983/solr"); SolrQuery solrQuery = new SolrQuery(); - solrQuery.setQuery("parentid:" + datasetId); + solrQuery.setRows(Integer.MAX_VALUE); + solrQuery.setQuery(SearchFields.PARENT_ID + ":" + datasetId); /** * @todo rather than hard coding "_draft" here, tie to * IndexableDataset(new DatasetVersion()).getDatasetState().getSuffix() @@ -1000,6 +983,8 @@ private List findSolrDocIdsForDraftFilesToDelete(Dataset datasetWithDraf solrQuery.addFilterQuery(SearchFields.ID + ":" + "*_draft"); List solrIdsOfFilesToDelete = new ArrayList<>(); try { + // i.e. rows=2147483647&q=parentid%3A16&fq=id%3A*_draft + logger.info("passing this Solr query to find draft files to delete: " + solrQuery); QueryResponse queryResponse = solrServer.query(solrQuery); SolrDocumentList results = queryResponse.getResults(); for (SolrDocument solrDocument : results) { diff --git a/src/main/java/edu/harvard/iq/dataverse/PermissionServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/PermissionServiceBean.java index fe43848e96e..91cf95b5096 100644 --- a/src/main/java/edu/harvard/iq/dataverse/PermissionServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/PermissionServiceBean.java @@ -17,143 +17,155 @@ import static edu.harvard.iq.dataverse.engine.command.CommandHelper.CH; /** - * Your one-stop-shop for deciding which user can do what action on which objects (TM). - * Note that this bean accesses the permissions/user assignment on a read-only basis. - * Changing the permissions a user has is done via roles and groups, over at {@link DataverseRoleServiceBean}. + * Your one-stop-shop for deciding which user can do what action on which + * objects (TM). Note that this bean accesses the permissions/user assignment on + * a read-only basis. Changing the permissions a user has is done via roles and + * groups, over at {@link DataverseRoleServiceBean}. + * * @author michael */ @Stateless @Named public class PermissionServiceBean { - private static final Logger logger = Logger.getLogger(PermissionServiceBean.class.getName()); - - @EJB - DataverseUserServiceBean userService; - - @EJB - DataverseRoleServiceBean roleService; - - @PersistenceContext - EntityManager em; - - @Inject - DataverseSession session; - - public class PermissionQuery { - final DataverseUser user; - final DvObject subject; - - public PermissionQuery(DataverseUser user, DvObject subject) { - this.user = user; - this.subject = subject; - } - - public PermissionQuery user( DataverseUser anotherUser ) { - return new PermissionQuery(anotherUser, subject); - } - - public boolean canIssue( Class cmd ) { - return isUserAllowedOn(user, cmd, subject); - } - + + private static final Logger logger = Logger.getLogger(PermissionServiceBean.class.getName()); + + @EJB + DataverseUserServiceBean userService; + + @EJB + DataverseRoleServiceBean roleService; + + @PersistenceContext + EntityManager em; + + @Inject + DataverseSession session; + + public class PermissionQuery { + + final DataverseUser user; + final DvObject subject; + + public PermissionQuery(DataverseUser user, DvObject subject) { + this.user = user; + this.subject = subject; + } + + public PermissionQuery user(DataverseUser anotherUser) { + return new PermissionQuery(anotherUser, subject); + } + + public boolean canIssue(Class cmd) { + return isUserAllowedOn(user, cmd, subject); + } + /** - * "Fast and loose" query mechanism, allowing to pass the command class name. - * Command is assumed to live in {@code edu.harvard.iq.dataverse.engine.command.impl.} + * "Fast and loose" query mechanism, allowing to pass the command class + * name. Command is assumed to live in + * {@code edu.harvard.iq.dataverse.engine.command.impl.} + * * @param commandName - * @return {@code true} iff the user has the permissions required by the command on the - * object. - * @throws ClassNotFoundException + * @return {@code true} iff the user has the permissions required by the + * command on the object. + * @throws ClassNotFoundException */ - public boolean canIssueCommand( String commandName ) throws ClassNotFoundException { - return isUserAllowedOn(user, - (Class)Class.forName("edu.harvard.iq.dataverse.engine.command.impl." + commandName), subject); - } - - public Set get() { - return permissionsFor(user, subject); - } - - public boolean has( Permission p ) { - return get().contains(p); - } - public boolean has( String pName ) { - return get().contains( Permission.valueOf(pName) ); - } - - } - - public List assignmentsOn( DvObject d ) { - return em.createNamedQuery("RoleAssignment.listByDefinitionPointId", RoleAssignment.class) - .setParameter("definitionPointId", d.getId()).getResultList(); - } - - public Set permissionsFor( DataverseUser u, DvObject d ) { - Set retVal = EnumSet.noneOf(Permission.class); - for ( RoleAssignment asmnt : roleService.assignmentsFor(u, d) ) { - retVal.addAll( asmnt.getRole().permissions() ); - } - - // special root case - All registered users can add to the root dv - if ( (d.getOwner() == null) && (!u.isGuest()) ) { - // TODO when groups arrive, this has to go. - retVal.add( Permission.UndoableEdit ); - retVal.add( Permission.AddDataset ); - retVal.add( Permission.AddDataverse ); - } - - return retVal; - } - - public Set assignmentsFor( DataverseUser u, DvObject d ) { - Set assignments = new HashSet<>(); - while ( d!=null ) { - assignments.addAll( roleService.directRoleAssignments(u, d) ); - if ( d instanceof Dataverse && ((Dataverse)d).isEffectivlyPermissionRoot() ) { - return assignments; - } else { - d = d.getOwner(); - } - } - - return assignments; - } - - /** - * For commands with no named dataverses, this allows a quick check whether - * a user can issue the command on the dataverse or not. - * @param u - * @param commandClass - * @param dvo - * @return - */ - public boolean isUserAllowedOn( DataverseUser u, Class commandClass, DvObject dvo ) { - Map> required = CH.permissionsRequired(commandClass); - if ( required.isEmpty() || required.get("")==null ) { + public boolean canIssueCommand(String commandName) throws ClassNotFoundException { + return isUserAllowedOn(user, + (Class) Class.forName("edu.harvard.iq.dataverse.engine.command.impl." + commandName), subject); + } + + public Set get() { + return permissionsFor(user, subject); + } + + public boolean has(Permission p) { + return get().contains(p); + } + + public boolean has(String pName) { + return get().contains(Permission.valueOf(pName)); + } + + } + + public List assignmentsOn(DvObject d) { + return em.createNamedQuery("RoleAssignment.listByDefinitionPointId", RoleAssignment.class) + .setParameter("definitionPointId", d.getId()).getResultList(); + } + + public Set permissionsFor(DataverseUser u, DvObject d) { + Set retVal = EnumSet.noneOf(Permission.class); + for (RoleAssignment asmnt : roleService.assignmentsFor(u, d)) { + retVal.addAll(asmnt.getRole().permissions()); + } + + // special case - All registered users can add to the root dv (no owner) + // or if alias ends in "_open" + if (d instanceof Dataverse) { + Dataverse dv = (Dataverse) d; + if ((dv.getOwner() == null || dv.getAlias().endsWith("_open")) && (!u.isGuest())) { + // TODO when groups arrive, this has to go. + retVal.add(Permission.UndoableEdit); + retVal.add(Permission.AddDataset); + retVal.add(Permission.AddDataverse); + } + } + + return retVal; + } + + public Set assignmentsFor(DataverseUser u, DvObject d) { + Set assignments = new HashSet<>(); + while (d != null) { + assignments.addAll(roleService.directRoleAssignments(u, d)); + if (d instanceof Dataverse && ((Dataverse) d).isEffectivlyPermissionRoot()) { + return assignments; + } else { + d = d.getOwner(); + } + } + + return assignments; + } + + /** + * For commands with no named dataverses, this allows a quick check whether + * a user can issue the command on the dataverse or not. + * + * @param u + * @param commandClass + * @param dvo + * @return + */ + public boolean isUserAllowedOn(DataverseUser u, Class commandClass, DvObject dvo) { + Map> required = CH.permissionsRequired(commandClass); + if (required.isEmpty() || required.get("") == null) { logger.info("IsUserAllowedOn: empty-true"); - return true; - } else { - Set grantedUserPermissions = permissionsFor(u, dvo); - Set requiredPermissionSet = required.get(""); - return grantedUserPermissions.containsAll(requiredPermissionSet); - } - } - - public PermissionQuery userOn( DataverseUser u, DvObject d ) { - if ( u==null ) { - // get guest user for dataverse d - u = userService.findByUserName("GabbiGuest"); - } - return new PermissionQuery(u, d); - } - - public PermissionQuery on( DvObject d ) { - if ( d == null ) { - throw new IllegalArgumentException("Cannot query permissions on a null DvObject"); - } - if ( d.getId() == null ) { - throw new IllegalArgumentException("Cannot query permissions on a DvObject with a null id."); - } - return userOn( session.getUser(), d ); - } - + return true; + } else { + Set grantedUserPermissions = permissionsFor(u, dvo); + Set requiredPermissionSet = required.get(""); + return grantedUserPermissions.containsAll(requiredPermissionSet); + } + } + + public PermissionQuery userOn(DataverseUser u, DvObject d) { + if (u == null) { + // get guest user for dataverse d + u = userService.findByUserName("GabbiGuest"); + } + return new PermissionQuery(u, d); + } + + public PermissionQuery on(DvObject d) { + if (d == null) { + throw new IllegalArgumentException("Cannot query permissions on a null DvObject"); + } + if (d.getId() == null) { + throw new IllegalArgumentException("Cannot query permissions on a DvObject with a null id."); + } + return userOn(session.getUser(), d); + } + } diff --git a/src/main/java/edu/harvard/iq/dataverse/SearchServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/SearchServiceBean.java index ee62bfd34f8..22622ffc569 100644 --- a/src/main/java/edu/harvard/iq/dataverse/SearchServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/SearchServiceBean.java @@ -94,6 +94,9 @@ public SolrQueryResponse search(DataverseUser dataverseUser, Dataverse dataverse solrFieldsToHightlightOnMap.put(SearchFields.AFFILIATION, "Affiliation"); solrFieldsToHightlightOnMap.put(SearchFields.FILE_TYPE_MIME, "File Type"); solrFieldsToHightlightOnMap.put(SearchFields.DESCRIPTION, "Description"); + solrFieldsToHightlightOnMap.put(SearchFields.VARIABLE_NAME, "Variable Name"); + solrFieldsToHightlightOnMap.put(SearchFields.VARIABLE_LABEL, "Variable Label"); + solrFieldsToHightlightOnMap.put(SearchFields.FILE_TYPE_SEARCHABLE, "File Type"); /** * @todo: show highlight on file card? * https://redmine.hmdc.harvard.edu/issues/3848 diff --git a/src/main/java/edu/harvard/iq/dataverse/api/SearchFields.java b/src/main/java/edu/harvard/iq/dataverse/api/SearchFields.java index bd92490caa7..7069707b8cf 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/SearchFields.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/SearchFields.java @@ -102,4 +102,7 @@ public class SearchFields { public static final String DATASET_DESCRIPTION = "dsDescription"; public static final String DATASET_VERSION_ID = "dataset_version_id_l"; + public static final String VARIABLE_NAME = "variable_name_en"; + public static final String VARIABLE_LABEL = "variable_label_en"; + } diff --git a/src/main/java/edu/harvard/iq/dataverse/dataaccess/ImageThumbConverter.java b/src/main/java/edu/harvard/iq/dataverse/dataaccess/ImageThumbConverter.java index 1896f82c647..1a3e2cc06d8 100644 --- a/src/main/java/edu/harvard/iq/dataverse/dataaccess/ImageThumbConverter.java +++ b/src/main/java/edu/harvard/iq/dataverse/dataaccess/ImageThumbConverter.java @@ -147,15 +147,34 @@ public static String generateImageThumb(String fileLocation, int size) { return null; } - double scaleFactor = ((double) size) / (double) fullSizeImage.getWidth(null); - int thumbHeight = (int) (fullSizeImage.getHeight(null) * scaleFactor); + int width = fullSizeImage.getWidth(null); + int height = fullSizeImage.getHeight(null); + + logger.info("image dimensions: "+width+"x"+height); + + double scaleFactor = 0.0; + int thumbHeight = size; + int thumbWidth = size; + + if (width > height) { + scaleFactor = ((double) size) / (double) width; + thumbHeight = (int) (height * scaleFactor); + } else { + scaleFactor = ((double) size) / (double) height; + thumbWidth = (int) (width * scaleFactor); + } + + logger.info("scale factor: "+scaleFactor); + logger.info("thumbnail dimensions: "+thumbWidth+"x"+thumbHeight); + + // We are willing to spend a few extra CPU cycles to generate // better-looking thumbnails, hence the SCALE_SMOOTH flag. // SCALE_FAST would trade quality for speed. //logger.info("Start image rescaling ("+size+" pixels), SCALE_FAST used;"); - java.awt.Image thumbImage = fullSizeImage.getScaledInstance(size, thumbHeight, java.awt.Image.SCALE_FAST); + java.awt.Image thumbImage = fullSizeImage.getScaledInstance(thumbWidth, thumbHeight, java.awt.Image.SCALE_FAST); //logger.info("Finished image rescaling."); ImageWriter writer = null; @@ -166,7 +185,7 @@ public static String generateImageThumb(String fileLocation, int size) { return null; } - BufferedImage lowRes = new BufferedImage(size, thumbHeight, BufferedImage.TYPE_INT_RGB); + BufferedImage lowRes = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB); lowRes.getGraphics().drawImage(thumbImage, 0, 0, null); ImageOutputStream ios = ImageIO.createImageOutputStream(new File(thumbFileLocation)); diff --git a/src/main/java/edu/harvard/iq/dataverse/ingest/IngestServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/ingest/IngestServiceBean.java index 8d13541fb8d..7f8d6395be8 100644 --- a/src/main/java/edu/harvard/iq/dataverse/ingest/IngestServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/ingest/IngestServiceBean.java @@ -125,6 +125,7 @@ public class IngestServiceBean { private static final String MIME_TYPE_STATA = "application/x-stata"; private static final String MIME_TYPE_RDATA = "application/x-rlang-transport"; private static final String MIME_TYPE_CSV = "text/csv"; + private static final String MIME_TYPE_CSV_ALT = "text/comma-separated-values"; private static final String MIME_TYPE_XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; private static final String MIME_TYPE_SPSS_SAV = "application/x-spss-sav"; private static final String MIME_TYPE_SPSS_POR = "application/x-spss-por"; @@ -256,7 +257,12 @@ public boolean ingestAsTabular(String tempFileLocation, DataFile dataFile) throw Logger.getLogger(DatasetPage.class.getName()).log(Level.INFO, "Tab-delimited file produced: " + tabFile.getAbsolutePath()); - tabDataIngest.getDataTable().setOriginalFileFormat(dataFile.getContentType()); + if (MIME_TYPE_CSV_ALT.equals(dataFile.getContentType())) { + tabDataIngest.getDataTable().setOriginalFileFormat(MIME_TYPE_CSV); + } else { + tabDataIngest.getDataTable().setOriginalFileFormat(dataFile.getContentType()); + } + // and we want to save the original of the ingested file: try { @@ -319,7 +325,7 @@ public boolean ingestableAsTabular(DataFile dataFile) { return true; } else if (mimeType.equals(MIME_TYPE_RDATA)) { return true; - } else if (mimeType.equals(MIME_TYPE_CSV)) { + } else if (mimeType.equals(MIME_TYPE_CSV) || mimeType.equals(MIME_TYPE_CSV_ALT)) { return true; } else if (mimeType.equals(MIME_TYPE_XLSX)) { return true; @@ -351,7 +357,7 @@ private TabularDataFileReader getTabDataReaderByMimeType(DataFile dataFile) { ingestPlugin = new DTAFileReader(new DTAFileReaderSpi()); } else if (mimeType.equals(MIME_TYPE_RDATA)) { ingestPlugin = new RDATAFileReader(new RDATAFileReaderSpi()); - } else if (mimeType.equals(MIME_TYPE_CSV)) { + } else if (mimeType.equals(MIME_TYPE_CSV) || mimeType.equals(MIME_TYPE_CSV_ALT)) { ingestPlugin = new CSVFileReader(new CSVFileReaderSpi()); } else if (mimeType.equals(MIME_TYPE_XLSX)) { ingestPlugin = new XLSXFileReader(new XLSXFileReaderSpi()); diff --git a/src/main/webapp/dataset.xhtml b/src/main/webapp/dataset.xhtml index 0e6ffa30c4c..0b480d68345 100644 --- a/src/main/webapp/dataset.xhtml +++ b/src/main/webapp/dataset.xhtml @@ -148,7 +148,7 @@ - +
@@ -253,7 +253,7 @@
+ fileUploadListener="#{DatasetPage.handleFileUpload}" process="filesTable" update="filesTable" label="Select Files to Add" oncomplete="javascript:bind_bsui_components();"/>