diff --git a/doc/sphinx-guides/source/user/dataset-management.rst b/doc/sphinx-guides/source/user/dataset-management.rst index 0aa8df4c64e..6e97a031b78 100755 --- a/doc/sphinx-guides/source/user/dataset-management.rst +++ b/doc/sphinx-guides/source/user/dataset-management.rst @@ -137,7 +137,7 @@ We currently only support the following HTML tags for any of our textbox meatdat
, , ,
,
,
, ,
,

-

, , , ,
  • ,
      ,

      ,

      , , , , 
       , , 
        . -Edit Dataset +Edit Files ================== Go to the dataset you would like to edit where you will see the listing of files. Select the files you would like to edit by using either the Select All checkbox or individually selecting files. Next, click on the Edit button above the files and select if you would like to: @@ -150,10 +150,18 @@ Go to the dataset you would like to edit where you will see the listing of files All of these actions, besides editing file metadata, will happen within this page and not bring you to another page. If you restrict files, you will also be asked to fill out the Terms of Access for the files. If Terms of Access already exist, you will be asked to confirm them. +File Tags +-------------------------------------------------------------- + +The File Tags are comprised of custom, category (i.e. Documentation, Data, Code) and tabular data tags (i.e. Event, Genomics, Geospatial, Network, Panel, Survey, Time Series). Use the dropdown select menus as well as the custom file tag input to apply these tags to the selected files. There is also a Delete Tags feature that, if checked, will allow you to delete unused file tags within that dataset. + + + Upload New Files -=================== +--------------------------------------------------------------- + +To upload new files to a dataset, go to the dataset you want to update and click on the Upload Files button in the files tab. From there you will be brought to the Upload Files page for the dataset. Once you have uploaded files, you will be able to edit the file metadata, restrict, add tags, or delete them before saving. -To upload new files to a dataset, go the dataset you want to update and click on the Upload Files Button in the files tab. From there you will be brought to the Upload page for the dataset. Once you have uploaded files, you will be able to edit the file metadata, restrict, add tags, or delete them before saving. .. _license-terms: diff --git a/src/main/java/Bundle.properties b/src/main/java/Bundle.properties index 2767358f9ac..7c778761088 100755 --- a/src/main/java/Bundle.properties +++ b/src/main/java/Bundle.properties @@ -41,6 +41,7 @@ download=Download deaccession=Deaccession linked=Linked harvested=Harvested +apply=Apply add=Add delete=Delete yes=Yes @@ -896,10 +897,17 @@ file.metaData.viewOnWorldMap=Explore on WorldMap file.addDescription=Add file description... file.tags=Tags file.editTags=Edit Tags -file.editTagsDialog.tip=Select existing file tags or create new tags to describe your files. Creating a new tag will add it as a tag option for all files in this dataset. Each file can have more than one tag. +file.editTagsDialog.tip=Select existing file tags or create new tags to describe your files. Each file can have more than one tag. file.editTagsDialog.select=File Tags +file.editTagsDialog.selectedTags=Selected Tags +file.editTagsDialog.selectedTags.none=No tags selected file.editTagsDialog.add=Custom File Tag +file.editTagsDialog.add.tip=Creating a new tag will add it as a tag option for all files in this dataset. file.editTagsDialog.newName=Add new file tag... +dataset.removeUnusedFileTags.label=Delete Tags +dataset.removeUnusedFileTags.tip=Select to delete Custom File Tags not used by the files in the dataset. +dataset.removeUnusedFileTags.check=Delete tags not being used + file.setThumbnail=Set Thumbnail file.setThumbnail.header=Set Dataset Thumbnail file.datasetThumbnail=Dataset Thumbnail @@ -910,8 +918,7 @@ file.advancedIngestOptions=Advanced Ingest Options file.assignedDataverseImage.success={0} has been saved as the thumbnail for this dataset. file.assignedTabFileTags.success=The tag(s) were successfully added for {0}. file.tabularDataTags=Tabular Data Tags -file.tabularDataTags.title=Select a tag to describe the type(s) of data this is (survey, time series, geospatial, etc). This tag is for excel, SPSS, Stata, or R Data files only. -file.tabularDataTags.tip=Data file specific tags for identifying what type(s) of data a file is. +file.tabularDataTags.tip=Select a tag to describe the type(s) of data this is (survey, time series, geospatial, etc). file.spss-savEncoding=Language Encoding file.spss-savEncoding.title=Select the language used for encoding this SPSS (sav) Data file. file.spss-savEncoding.current=Current Selection: diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index 26fc4080119..d785c82213a 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -21,10 +21,7 @@ import edu.harvard.iq.dataverse.ingest.IngestRequest; import edu.harvard.iq.dataverse.ingest.IngestServiceBean; import edu.harvard.iq.dataverse.metadataimport.ForeignMetadataImportServiceBean; -import edu.harvard.iq.dataverse.search.FacetCategory; -import edu.harvard.iq.dataverse.search.FileView; import edu.harvard.iq.dataverse.search.SearchFilesServiceBean; -import edu.harvard.iq.dataverse.search.SolrSearchResult; import edu.harvard.iq.dataverse.search.SortBy; import edu.harvard.iq.dataverse.settings.SettingsServiceBean; import edu.harvard.iq.dataverse.util.BundleUtil; @@ -37,9 +34,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.StringReader; import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.Paths; import java.sql.Timestamp; import java.text.SimpleDateFormat; @@ -62,28 +57,25 @@ import javax.inject.Named; import org.primefaces.event.FileUploadEvent; import org.primefaces.model.UploadedFile; -import javax.json.Json; -import javax.json.JsonObject; -import javax.json.JsonArray; -import javax.json.JsonReader; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import javax.validation.ConstraintViolation; import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.methods.GetMethod; import org.primefaces.context.RequestContext; import java.text.DateFormat; +import java.util.Arrays; import java.util.HashSet; -import java.util.LinkedHashMap; import javax.faces.model.SelectItem; import java.util.logging.Level; import javax.faces.component.UIComponent; import javax.faces.component.UIInput; + +import javax.faces.event.AjaxBehaviorEvent; + import javax.faces.context.ExternalContext; + import org.primefaces.component.tabview.TabView; import org.primefaces.event.TabChangeEvent; -import org.primefaces.model.LazyDataModel; -import org.primefaces.model.SortOrder; /** * @@ -215,6 +207,15 @@ public enum DisplayMode { private String dataverseSiteUrl = ""; + private boolean removeUnusedTags; + + public boolean isRemoveUnusedTags() { + return removeUnusedTags; + } + + public void setRemoveUnusedTags(boolean removeUnusedTags) { + this.removeUnusedTags = removeUnusedTags; + } private List fileMetadatas; private String fileSortField; @@ -3562,16 +3563,9 @@ public void setTabFileTagsByName(List tabFileTagsByName) { } private void refreshCategoriesByName(){ - categoriesByName= new ArrayList<>(); - for (FileMetadata fm : selectedFiles) { - if (fm.getCategories() != null) { - for (int i = 0; i < fm.getCategories().size(); i++) { - if (!categoriesByName.contains(fm.getCategories().get(i).getName())) { - categoriesByName.add(fm.getCategories().get(i).getName()); - } - } - } + for (String category: dataset.getCategoriesByName() ){ + categoriesByName.add(category); } refreshSelectedTags(); } @@ -3612,16 +3606,13 @@ public void setSelectedTabFileTags(String[] selectedTabFileTags) { private String[] selectedTags = {}; - private void refreshSelectedTags() { - selectedTags = null; - selectedTags = new String[0]; - if (categoriesByName.size() > 0) { - selectedTags = new String[categoriesByName.size()]; - for (int i = 0; i < categoriesByName.size(); i++) { - selectedTags[i] = categoriesByName.get(i); - } + public void handleSelection(final AjaxBehaviorEvent event) { + if (selectedTags != null) { + selectedTags = selectedTags.clone(); } } + + private void refreshTabFileTagsByName(){ @@ -3647,6 +3638,7 @@ private void refreshSelectedTabFileTags() { selectedTabFileTags[i] = tabFileTagsByName.get(i); } } + Arrays.sort(selectedTabFileTags); } private boolean tabularDataSelected = false; @@ -3659,7 +3651,8 @@ public void setTabularDataSelected(boolean tabularDataSelected) { this.tabularDataSelected = tabularDataSelected; } - public String[] getSelectedTags() { + public String[] getSelectedTags() { + return selectedTags; } @@ -3681,6 +3674,46 @@ public void setNewCategoryName(String newCategoryName) { this.newCategoryName = newCategoryName; } + public String saveNewCategory() { + if (newCategoryName != null && !newCategoryName.isEmpty()) { + categoriesByName.add(newCategoryName); + } + //Now increase size of selectedTags and add new category + String[] temp = new String[selectedTags.length + 1]; + System.arraycopy(selectedTags, 0, temp, 0, selectedTags.length); + selectedTags = temp; + selectedTags[selectedTags.length - 1] = newCategoryName; + //Blank out added category + newCategoryName = ""; + return ""; + } + + private void refreshSelectedTags() { + selectedTags = null; + selectedTags = new String[0]; + + List selectedCategoriesByName= new ArrayList<>(); + for (FileMetadata fm : selectedFiles) { + if (fm.getCategories() != null) { + for (int i = 0; i < fm.getCategories().size(); i++) { + if (!selectedCategoriesByName.contains(fm.getCategories().get(i).getName())) { + selectedCategoriesByName.add(fm.getCategories().get(i).getName()); + } + + } + + } + } + + if (selectedCategoriesByName.size() > 0) { + selectedTags = new String[selectedCategoriesByName.size()]; + for (int i = 0; i < selectedCategoriesByName.size(); i++) { + selectedTags[i] = (String) selectedCategoriesByName.get(i); + } + } + Arrays.sort(selectedTags); + } + /* This method handles saving both "tabular file tags" and * "file categories" (which are also considered "tags" in 4.0) */ @@ -3738,9 +3771,52 @@ public String saveFileTagsAndCategories() { newCategoryName = null; - + if (removeUnusedTags){ + removeUnusedFileTagsFromDataset(); + } save(); - return returnToDraftVersion(); + return returnToDraftVersion(); + } + + /* + Remove unused file tags + When updating datafile tags see if any custom tags are not in use. + Remove them + + */ + private void removeUnusedFileTagsFromDataset() { + categoriesByName = new ArrayList<>(); + for (FileMetadata fm : workingVersion.getFileMetadatas()) { + if (fm.getCategories() != null) { + for (int i = 0; i < fm.getCategories().size(); i++) { + if (!categoriesByName.contains(fm.getCategories().get(i).getName())) { + categoriesByName.add(fm.getCategories().get(i).getName()); + } + } + } + } + List datasetFileCategoriesToRemove = new ArrayList(); + + for (DataFileCategory test : dataset.getCategories()) { + boolean remove = true; + for (String catByName : categoriesByName) { + if (catByName.equals(test.getName())) { + remove = false; + break; + } + } + if (remove) { + datasetFileCategoriesToRemove.add(test); + } + } + + if (!datasetFileCategoriesToRemove.isEmpty()) { + for (DataFileCategory remove : datasetFileCategoriesToRemove) { + dataset.getCategories().remove(remove); + } + + } + } diff --git a/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java b/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java index 50f13919a1f..b60bcecef19 100644 --- a/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java @@ -78,9 +78,11 @@ import org.apache.commons.httpclient.methods.GetMethod; import org.primefaces.context.RequestContext; import java.text.DateFormat; +import java.util.Arrays; import java.util.HashSet; import javax.faces.model.SelectItem; import java.util.logging.Level; +import javax.faces.event.AjaxBehaviorEvent; /** * @@ -142,6 +144,7 @@ public enum FileEditMode { private String dropBoxSelection = ""; private String displayCitation; private boolean datasetUpdateRequired = false; + private boolean tabularDataTagsUpdated = false; private String persistentId; @@ -815,6 +818,8 @@ public String save() { if (workingVersion.getId() == null || datasetUpdateRequired) { logger.info("issuing the dataset update command"); // We are creating a new draft version; + // (OR, a full update of the dataset has been explicitly requested, + // because of the nature of the updates the user has made). // We'll use an Update command for this: //newDraftVersion = true; @@ -829,6 +834,27 @@ public String save() { } } } + + // Tabular data tags are assigned to datafiles, not to + // version-specfic filemetadatas! + // So if tabular tags have been modified, we also need to + // refresh the list of datafiles, as found in dataset.getFiles(), + // similarly to what we've just done, above, for the filemetadatas. + // Otherwise, when we call UpdateDatasetCommand, it's not going + // to update the tags in the database (issue #2798). + + if (tabularDataTagsUpdated) { + for (int i = 0; i < dataset.getFiles().size(); i++) { + for (FileMetadata fileMetadata : fileMetadatas) { + if (fileMetadata.getDataFile().getStorageIdentifier() != null) { + if (fileMetadata.getDataFile().getStorageIdentifier().equals(dataset.getFiles().get(i).getStorageIdentifier())) { + dataset.getFiles().set(i, fileMetadata.getDataFile()); + } + } + } + } + tabularDataTagsUpdated = false; + } } @@ -860,7 +886,8 @@ public String save() { datasetUpdateRequired = false; saveEnabled = false; } else { - // This is an existing Draft version. We'll try to update + // This is an existing Draft version (and nobody has explicitly + // requested that the entire dataset is updated). So we'll try to update // only the filemetadatas and/or files affected, and not the // entire version. // TODO: in 4.3, create SaveDataFileCommand! @@ -1443,6 +1470,7 @@ public void saveAsDesignatedThumbnail() { // And reset the selected fileMetadata: fileMetadataSelectedForThumbnailPopup = null; } + /* * Items for the "Tags (Categories)" popup. @@ -1478,32 +1506,107 @@ public List getTabFileTags() { public void setTabFileTags(List tabFileTags) { this.tabFileTags = tabFileTags; } + + private String[] selectedTabFileTags = {}; + + public String[] getSelectedTabFileTags() { + return selectedTabFileTags; + } + + public void setSelectedTabFileTags(String[] selectedTabFileTags) { + this.selectedTabFileTags = selectedTabFileTags; + } private String[] selectedTags = {}; + + public void refreshTagsPopUp(FileMetadata fm){ + setFileMetadataSelectedForTagsPopup(fm); + refreshCategoriesByName(); + refreshTabFileTagsByName(); + } + + private List tabFileTagsByName; - public String[] getSelectedTags() { + public List getTabFileTagsByName() { + return tabFileTagsByName; + } - selectedTags = null; - selectedTags = new String[0]; + public void setTabFileTagsByName(List tabFileTagsByName) { + this.tabFileTagsByName = tabFileTagsByName; + } + + private void refreshTabFileTagsByName() { + tabFileTagsByName = new ArrayList<>(); + if (fileMetadataSelectedForTagsPopup.getDataFile().getTags() != null) { + for (int i = 0; i < fileMetadataSelectedForTagsPopup.getDataFile().getTags().size(); i++) { + tabFileTagsByName.add(fileMetadataSelectedForTagsPopup.getDataFile().getTags().get(i).getTypeLabel()); + } + } + refreshSelectedTabFileTags(); + } - if (fileMetadataSelectedForTagsPopup != null) { - if (fileMetadataSelectedForTagsPopup.getDataFile() != null - && fileMetadataSelectedForTagsPopup.getDataFile().getTags() != null - && fileMetadataSelectedForTagsPopup.getDataFile().getTags().size() > 0) { + private void refreshSelectedTabFileTags() { + selectedTabFileTags = null; + selectedTabFileTags = new String[0]; + if (tabFileTagsByName.size() > 0) { + selectedTabFileTags = new String[tabFileTagsByName.size()]; + for (int i = 0; i < tabFileTagsByName.size(); i++) { + selectedTabFileTags[i] = tabFileTagsByName.get(i); + } + } + Arrays.sort(selectedTabFileTags); + } + + private void refreshCategoriesByName(){ + categoriesByName= new ArrayList<>(); + for (String category: dataset.getCategoriesByName() ){ + categoriesByName.add(category); + } + refreshSelectedTags(); + } + + + private List categoriesByName; + + public List getCategoriesByName() { + return categoriesByName; + } - selectedTags = new String[fileMetadataSelectedForTagsPopup.getDataFile().getTags().size()]; + public void setCategoriesByName(List categoriesByName) { + this.categoriesByName = categoriesByName; + } + + private void refreshSelectedTags() { + selectedTags = null; + selectedTags = new String[0]; + List selectedCategoriesByName = new ArrayList<>(); - for (int i = 0; i < fileMetadataSelectedForTagsPopup.getDataFile().getTags().size(); i++) { - selectedTags[i] = fileMetadataSelectedForTagsPopup.getDataFile().getTags().get(i).getTypeLabel(); + if (fileMetadataSelectedForTagsPopup.getCategories() != null) { + for (int i = 0; i < fileMetadataSelectedForTagsPopup.getCategories().size(); i++) { + if (!selectedCategoriesByName.contains(fileMetadataSelectedForTagsPopup.getCategories().get(i).getName())) { + selectedCategoriesByName.add(fileMetadataSelectedForTagsPopup.getCategories().get(i).getName()); } } } + + if (selectedCategoriesByName.size() > 0) { + selectedTags = new String[selectedCategoriesByName.size()]; + for (int i = 0; i < selectedCategoriesByName.size(); i++) { + selectedTags[i] = (String) selectedCategoriesByName.get(i); + } + } + Arrays.sort(selectedTags); + } + + public String[] getSelectedTags() { return selectedTags; } public void setSelectedTags(String[] selectedTags) { this.selectedTags = selectedTags; } + + /* * "File Tags" (aka "File Categories"): @@ -1518,18 +1621,45 @@ public String getNewCategoryName() { public void setNewCategoryName(String newCategoryName) { this.newCategoryName = newCategoryName; } + + public String saveNewCategory() { + + if (newCategoryName != null && !newCategoryName.isEmpty()) { + categoriesByName.add(newCategoryName); + } + //Now increase size of selectedTags and add new category + String[] temp = new String[selectedTags.length + 1]; + System.arraycopy(selectedTags, 0, temp, 0, selectedTags.length); + selectedTags = temp; + selectedTags[selectedTags.length - 1] = newCategoryName; + //Blank out added category + newCategoryName = ""; + return ""; + } /* This method handles saving both "tabular file tags" and * "file categories" (which are also considered "tags" in 4.0) */ public void saveFileTagsAndCategories() { // 1. File categories: - // we don't need to do anything for the file categories that the user - // selected from the pull down list; that was done directly from the - // page with the FileMetadata.setCategoriesByName() method. - // So here we only need to take care of the new, custom category - // name, if entered: + /* + In order to get the cancel button to work we had to separate the selected tags + from the file metadata and re-add them on save + + */ + fileMetadataSelectedForTagsPopup.setCategories(new ArrayList()); + if (newCategoryName != null) { + fileMetadataSelectedForTagsPopup.addCategoryByName(newCategoryName); + } + // 2. Tabular DataFile Tags: + if (selectedTags != null) { + for (int i = 0; i < selectedTags.length; i++) { + fileMetadataSelectedForTagsPopup.addCategoryByName(selectedTags[i]); + } + } + + logger.fine("New category name: " + newCategoryName); if (fileMetadataSelectedForTagsPopup != null && newCategoryName != null) { @@ -1542,15 +1672,14 @@ public void saveFileTagsAndCategories() { // 2. Tabular DataFile Tags: - if (selectedTags != null) { - + if (tabularDataTagsUpdated && selectedTabFileTags != null) { if (fileMetadataSelectedForTagsPopup != null && fileMetadataSelectedForTagsPopup.getDataFile() != null) { fileMetadataSelectedForTagsPopup.getDataFile().setTags(null); - for (int i = 0; i < selectedTags.length; i++) { + for (int i = 0; i < selectedTabFileTags.length; i++) { DataFileTag tag = new DataFileTag(); try { - tag.setTypeByLabel(selectedTags[i]); + tag.setTypeByLabel(selectedTabFileTags[i]); tag.setDataFile(fileMetadataSelectedForTagsPopup.getDataFile()); fileMetadataSelectedForTagsPopup.getDataFile().addTag(tag); @@ -1575,6 +1704,13 @@ public void saveFileTagsAndCategories() { } + public void handleSelection(final AjaxBehaviorEvent event) { + tabularDataTagsUpdated = true; + if (selectedTags != null) { + selectedTags = selectedTags.clone(); + } + } + /* * Items for the "Advanced (Ingest) Options" popup. diff --git a/src/main/webapp/dataset.xhtml b/src/main/webapp/dataset.xhtml index 3a2c478eb47..72fda13a700 100755 --- a/src/main/webapp/dataset.xhtml +++ b/src/main/webapp/dataset.xhtml @@ -915,52 +915,90 @@

        #{bundle['file.editTagsDialog.tip']}

        -
        -