From 316ce03d024913fc50bf18ff31ae8b012c2f7cd1 Mon Sep 17 00:00:00 2001 From: Raman Prasad Date: Wed, 21 Sep 2016 12:55:39 -0400 Subject: [PATCH 01/86] Moved isDuplicate method to datasetutility package. No changes to actual method. Added direct method for checking a single file--that's for #2290 --- .../edu/harvard/iq/dataverse/DatasetPage.java | 32 +--- .../dataverse/DatasetVersionServiceBean.java | 50 ++++++ .../iq/dataverse/EditDatafilesPage.java | 36 +--- .../datasetutility/DuplicateFileChecker.java | 165 ++++++++++++++++++ 4 files changed, 222 insertions(+), 61 deletions(-) create mode 100644 src/main/java/edu/harvard/iq/dataverse/datasetutility/DuplicateFileChecker.java diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index 882608dff45..ae06bd4cd29 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -8,6 +8,7 @@ import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser; import edu.harvard.iq.dataverse.authorization.users.PrivateUrlUser; import edu.harvard.iq.dataverse.authorization.users.GuestUser; +import edu.harvard.iq.dataverse.datasetutility.DuplicateFileChecker; import edu.harvard.iq.dataverse.datavariable.VariableServiceBean; import edu.harvard.iq.dataverse.engine.command.Command; import edu.harvard.iq.dataverse.engine.command.exception.CommandException; @@ -2836,37 +2837,12 @@ public String cancel() { return returnToLatestVersion(); } + public boolean isDuplicate(FileMetadata fileMetadata) { - String thisMd5 = fileMetadata.getDataFile().getmd5(); - if (thisMd5 == null) { - return false; - } - - Map MD5Map = new HashMap(); - - // TODO: - // think of a way to do this that doesn't involve populating this - // map for every file on the page? - // man not be that much of a problem, if we paginate and never display - // more than a certain number of files... Still, needs to be revisited - // before the final 4.0. - // -- L.A. 4.0 - Iterator fmIt = workingVersion.getFileMetadatas().iterator(); - while (fmIt.hasNext()) { - FileMetadata fm = fmIt.next(); - String md5 = fm.getDataFile().getmd5(); - if (md5 != null) { - if (MD5Map.get(md5) != null) { - MD5Map.put(md5, MD5Map.get(md5).intValue() + 1); - } else { - MD5Map.put(md5, 1); - } - } - } - return MD5Map.get(thisMd5) != null && MD5Map.get(thisMd5).intValue() > 1; + return DuplicateFileChecker.IsDuplicateOriginalWay(workingVersion, fileMetadata); } - + private HttpClient getClient() { // TODO: // cache the http client? -- L.A. 4.0 alpha diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersionServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersionServiceBean.java index d054b52ad81..c947000ece1 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersionServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersionServiceBean.java @@ -819,4 +819,54 @@ public void populateDatasetSearchCard(SolrSearchResult solrSearchResult) { } } + /** + * Return a list of the checksum Strings for files in the specified DatasetVersion + * + * This is used to help check for duplicate files within a DatasetVersion + * + * @param datasetVersion + * @return a list of checksum Strings for files in the specified DatasetVersion + */ + public List getChecksumListForDatasetVersion(DatasetVersion datasetVersion) { + + if (datasetVersion == null){ + throw new NullPointerException("datasetVersion cannot be null"); + } + + String query = "SELECT df.md5 FROM datafile df, filemetadata fm WHERE fm.datasetversion_id = " + datasetVersion.getId() + " AND fm.datafile_id = df.id;"; + + logger.log(Level.FINE, "query: {0}", query); + Query nativeQuery = em.createNativeQuery(query); + List checksumList = nativeQuery.getResultList(); + + return checksumList; + } + + + /** + * Check for the existence of a single checksum value within a DatasetVersion's files + * + * @param datasetVersion + * @param selectedChecksum + * @return + */ + public boolean doesChecksumExistInDatasetVersion(DatasetVersion datasetVersion, String selectedChecksum) { + if (datasetVersion == null){ + throw new NullPointerException("datasetVersion cannot be null"); + } + + String query = "SELECT df.md5 FROM datafile df, filemetadata fm" + + " WHERE fm.datasetversion_id = " + datasetVersion.getId() + + " AND fm.datafile_id = df.id" + + " AND df.md5 = '" + selectedChecksum + "';"; + + Query nativeQuery = em.createNativeQuery(query); + List checksumList = nativeQuery.getResultList(); + + if (checksumList.size() > 0){ + return true; + } + return false; + } + } // end class diff --git a/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java b/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java index a86374185e8..5d4a65a4c8a 100644 --- a/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java @@ -10,6 +10,7 @@ import edu.harvard.iq.dataverse.authorization.users.ApiToken; import edu.harvard.iq.dataverse.authorization.users.User; import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser; +import edu.harvard.iq.dataverse.datasetutility.DuplicateFileChecker; import edu.harvard.iq.dataverse.datavariable.VariableServiceBean; import edu.harvard.iq.dataverse.engine.command.Command; import edu.harvard.iq.dataverse.engine.command.exception.CommandException; @@ -1030,41 +1031,10 @@ public String cancel() { } public boolean isDuplicate(FileMetadata fileMetadata) { - String thisMd5 = fileMetadata.getDataFile().getmd5(); - if (thisMd5 == null) { - return false; - } - - Map MD5Map = new HashMap(); - // TODO: - // think of a way to do this that doesn't involve populating this - // map for every file on the page? - // man not be that much of a problem, if we paginate and never display - // more than a certain number of files... Still, needs to be revisited - // before the final 4.0. - // -- L.A. 4.0 - - // make a "defensive copy" to avoid java.util.ConcurrentModificationException from being thrown - // when uploading 100+ files - List wvCopy = new ArrayList<>(workingVersion.getFileMetadatas()); - Iterator fmIt = wvCopy.iterator(); - - while (fmIt.hasNext()) { - FileMetadata fm = fmIt.next(); - String md5 = fm.getDataFile().getmd5(); - if (md5 != null) { - if (MD5Map.get(md5) != null) { - MD5Map.put(md5, MD5Map.get(md5).intValue() + 1); - } else { - MD5Map.put(md5, 1); - } - } - } - - return MD5Map.get(thisMd5) != null && MD5Map.get(thisMd5).intValue() > 1; + return DuplicateFileChecker.IsDuplicateOriginalWay(workingVersion, fileMetadata); } - + private HttpClient getClient() { // TODO: // cache the http client? -- L.A. 4.0 alpha diff --git a/src/main/java/edu/harvard/iq/dataverse/datasetutility/DuplicateFileChecker.java b/src/main/java/edu/harvard/iq/dataverse/datasetutility/DuplicateFileChecker.java new file mode 100644 index 00000000000..7be3ae428fc --- /dev/null +++ b/src/main/java/edu/harvard/iq/dataverse/datasetutility/DuplicateFileChecker.java @@ -0,0 +1,165 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package edu.harvard.iq.dataverse.datasetutility; + +import edu.harvard.iq.dataverse.DatasetVersion; +import edu.harvard.iq.dataverse.DatasetVersionServiceBean; +import edu.harvard.iq.dataverse.FileMetadata; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +/** + * Used for adding/replacing single files. + * + * Methods check if the files already exist in the *saved* DatasetVersion + * + * @author rmp553 + */ +public class DuplicateFileChecker { + + private static final Logger logger = Logger.getLogger(DuplicateFileChecker.class.getCanonicalName()); + private DatasetVersionServiceBean datasetVersionService; + + /** + * Constructor + * + * @param datasetVersionService + */ + public DuplicateFileChecker(DatasetVersionServiceBean datasetVersionService){ + + if (datasetVersionService == null){ + throw new NullPointerException("datasetVersionService cannot be null"); + } + + this.datasetVersionService = datasetVersionService; + } // end: constructor + + + /** + * Check the database to see if this file is already in the DatasetVersion + * + * Note: This checks a SINGLE file against the database only. + * + * @param checksum + * @return + */ + public boolean isFileInSavedDatasetVersion(DatasetVersion datasetVersion, FileMetadata fileMetadata){ + + if (datasetVersion == null){ + throw new NullPointerException("datasetVersion cannot be null"); + } + + if (fileMetadata == null){ + throw new NullPointerException("fileMetadata cannot be null"); + } + return this.isFileInSavedDatasetVersion(datasetVersion, fileMetadata.getDataFile().getmd5()); + } + + /** + * See if this checksum already exists by a new query + * + * @param checksum + * @return + */ + public boolean isFileInSavedDatasetVersion(DatasetVersion datasetVersion, String checkSum){ + + if (datasetVersion == null){ + throw new NullPointerException("datasetVersion cannot be null"); + } + + if (checkSum == null){ + throw new NullPointerException("checkSum cannot be null"); + } + + return datasetVersionService.doesChecksumExistInDatasetVersion(datasetVersion, checkSum); + + } + + /** + * From dataset version: + * - Get the md5s of all the files + * - Load them into a hash + * + * Loads checksums from unsaved datasetversion--checks more + * + */ + public Map getDatasetHashesFromDatabase(DatasetVersion datasetVersion){ + + if (datasetVersion == null){ + throw new NullPointerException("datasetVersion cannot be null"); + } + + Map checksumHashCounts = new HashMap<>(); + + List fileMetadatas = new ArrayList<>(datasetVersion.getFileMetadatas()); + + for (FileMetadata fm : fileMetadatas){ + String checkSum = fm.getDataFile().getmd5(); + if (checksumHashCounts.get(checkSum) != null){ + checksumHashCounts.put(checkSum, checksumHashCounts.get(checkSum).intValue() + 1); + }else{ + checksumHashCounts.put(checkSum, 1); + } + } + return checksumHashCounts; + } + + + + /** + * Original isDuplicate method from the DatasetPage and EditDatafilesPage + * + * Note: this has efficiency issues in that the hash is re-created for every fileMetadata checked + * + * @param workingVersion + * @param fileMetadata + * @return + */ + public static boolean IsDuplicateOriginalWay(DatasetVersion workingVersion, FileMetadata fileMetadata) { + if (workingVersion == null){ + throw new NullPointerException("datasetVersion cannot be null"); + } + + String thisMd5 = fileMetadata.getDataFile().getmd5(); + if (thisMd5 == null) { + return false; + } + + Map MD5Map = new HashMap(); + + // TODO: + // think of a way to do this that doesn't involve populating this + // map for every file on the page? + // man not be that much of a problem, if we paginate and never display + // more than a certain number of files... Still, needs to be revisited + // before the final 4.0. + // -- L.A. 4.0 + + // make a "defensive copy" to avoid java.util.ConcurrentModificationException from being thrown + // when uploading 100+ files + List wvCopy = new ArrayList<>(workingVersion.getFileMetadatas()); + Iterator fmIt = wvCopy.iterator(); + + while (fmIt.hasNext()) { + FileMetadata fm = fmIt.next(); + String md5 = fm.getDataFile().getmd5(); + if (md5 != null) { + if (MD5Map.get(md5) != null) { + MD5Map.put(md5, MD5Map.get(md5).intValue() + 1); + } else { + MD5Map.put(md5, 1); + } + } + } + return MD5Map.get(thisMd5) != null && MD5Map.get(thisMd5).intValue() > 1; + + } + +} From 22239b569ceaf5f809a379b5a6aa85c6704abfdf Mon Sep 17 00:00:00 2001 From: Raman Prasad Date: Wed, 21 Sep 2016 13:56:50 -0400 Subject: [PATCH 02/86] created WorldMapPermissionHelper.java to move checks out of the DatasetPage. #2290 --- .../edu/harvard/iq/dataverse/DatasetPage.java | 359 +++++------------- .../iq/dataverse/EditDatafilesPage.java | 13 +- .../WorldMapPermissionHelper.java | 320 ++++++++++++++++ 3 files changed, 427 insertions(+), 265 deletions(-) create mode 100644 src/main/java/edu/harvard/iq/dataverse/datasetutility/WorldMapPermissionHelper.java diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index ae06bd4cd29..fbe7628c406 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -9,6 +9,7 @@ import edu.harvard.iq.dataverse.authorization.users.PrivateUrlUser; import edu.harvard.iq.dataverse.authorization.users.GuestUser; import edu.harvard.iq.dataverse.datasetutility.DuplicateFileChecker; +import edu.harvard.iq.dataverse.datasetutility.WorldMapPermissionHelper; import edu.harvard.iq.dataverse.datavariable.VariableServiceBean; import edu.harvard.iq.dataverse.engine.command.Command; import edu.harvard.iq.dataverse.engine.command.exception.CommandException; @@ -210,13 +211,14 @@ public enum DisplayMode { private List versionTabList = new ArrayList(); private List versionTabListForPostLoad = new ArrayList(); + // Used to help with displaying buttons related to the WorldMap + private WorldMapPermissionHelper worldMapPermissionHelper; // Used to store results of permissions checks private final Map datasetPermissionMap = new HashMap<>(); // { Permission human_name : Boolean } private final Map fileDownloadPermissionMap = new HashMap<>(); // { FileMetadata.id : Boolean } private final Map fileMetadataTwoRavensExploreMap = new HashMap<>(); // { FileMetadata.id : Boolean } - private final Map fileMetadataWorldMapExplore = new HashMap<>(); // { FileMetadata.id : Boolean } private DataFile selectedDownloadFile; @@ -676,9 +678,7 @@ public boolean doesSessionUserHaveDataSetPermission(Permission permissionToCheck public void setNoDVsRemaining(boolean noDVsRemaining) { this.noDVsRemaining = noDVsRemaining; } - - private final Map mapLayerMetadataLookup = new HashMap<>(); - + private GuestbookResponse guestbookResponse; private Guestbook selectedGuestbook; @@ -1013,181 +1013,12 @@ public void handleChange() { public void handleChangeButton() { - } - - public boolean isShapefileType(FileMetadata fm) { - if (fm == null) { - return false; - } - if (fm.getDataFile() == null) { - return false; - } - - return fm.getDataFile().isShapefileType(); - } - - /* - Check if the FileMetadata.dataFile has an associated MapLayerMetadata object - - The MapLayerMetadata objects have been fetched at page inception by "loadMapLayerMetadataLookup()" - */ - public boolean hasMapLayerMetadata(FileMetadata fm) { - if (fm == null) { - return false; - } - if (fm.getDataFile() == null) { - return false; - } - return doesDataFileHaveMapLayerMetadata(fm.getDataFile()); - } - - /** - * Check if a DataFile has an associated MapLayerMetadata object - * - * The MapLayerMetadata objects have been fetched at page inception by - * "loadMapLayerMetadataLookup()" - */ - private boolean doesDataFileHaveMapLayerMetadata(DataFile df) { - if (df == null) { - return false; - } - if (df.getId() == null) { - return false; - } - return this.mapLayerMetadataLookup.containsKey(df.getId()); - } - - /** - * Using a DataFile id, retrieve an associated MapLayerMetadata object - * - * The MapLayerMetadata objects have been fetched at page inception by - * "loadMapLayerMetadataLookup()" - */ - public MapLayerMetadata getMapLayerMetadata(DataFile df) { - if (df == null) { - return null; - } - return this.mapLayerMetadataLookup.get(df.getId()); - } + } private void msg(String s){ // System.out.println(s); } - /** - * See table in: https://github.com/IQSS/dataverse/issues/1618 - * - * Can the user see a reminder to publish button? - * (0) The application has to be set to Create Edit Maps - true - * (1) Logged in user - * (2) Is geospatial file? - * (3) File has NOT been released - * (4) No existing Map - * (5) Can Edit Dataset - * - * @param FileMetadata fm - * @return boolean - */ - public boolean canSeeMapButtonReminderToPublish(FileMetadata fm){ - if (fm==null){ - - return false; - } - - // (0) Is the view GeoconnectViewMaps - if (!settingsService.isTrueForKey(SettingsServiceBean.Key.GeoconnectCreateEditMaps, false)){ - return false; - } - - - // (1) Is there an authenticated user? - // - if (!(isSessionUserAuthenticated())){ - return false; - } - - - // Is this file a Shapefile or a Tabular file tagged as Geospatial? - // - if (!(this.isPotentiallyMappableFileType(fm))){ - return false; - } - - // (3) Is this DataFile released? Yes, don't need reminder - // - if (fm.getDataFile().isReleased()){ - return false; - } - - // (4) Does a map already exist? Yes, don't need reminder - // - if (this.hasMapLayerMetadata(fm)){ - return false; - } - - // (5) If so, can the logged in user edit the Dataset to which this FileMetadata belongs? - if (!this.doesSessionUserHaveDataSetPermission(Permission.EditDataset)){ - return false; - } - - // Looks good - // - return true; - } - - /** - * Should there be a Map Data Button for this file? - * see table in: https://github.com/IQSS/dataverse/issues/1618 - * (1) Is the user logged in? - * (2) Is this file a Shapefile or a Tabular file tagged as Geospatial? - * (3) Does the logged in user have permission to edit the Dataset to which this FileMetadata belongs? - * (4) Is the create Edit Maps flag set to true? - * (5) Any of these conditions: - * 9a) File Published - * (b) Draft: File Previously published - * @param fm FileMetadata - * @return boolean - */ - public boolean canUserSeeMapDataButton(FileMetadata fm){ - - if (fm==null){ - return false; - } - - - // (1) Is there an authenticated user? - if (!(isSessionUserAuthenticated())){ - return false; - } - - // (2) Is this file a Shapefile or a Tabular file tagged as Geospatial? - // TO DO: EXPAND FOR TABULAR FILES TAGGED AS GEOSPATIAL! - // - if (!(this.isPotentiallyMappableFileType(fm))){ - return false; - } - - // (3) Does the user have Edit Dataset permissions? - // - if (!this.doesSessionUserHaveDataSetPermission(Permission.EditDataset)){ - return false; - } - - // (4) Is the view GeoconnectViewMaps - if (!settingsService.isTrueForKey(SettingsServiceBean.Key.GeoconnectCreateEditMaps, false)){ - return false; - } - - // (5) Is File released? - // - if (fm.getDataFile().isReleased()){ - return true; - } - - // Nope - return false; - } - /** * Used in the .xhtml file to check whether a tabular file @@ -1249,37 +1080,6 @@ public boolean canSeeTwoRavensExploreButton(FileMetadata fm){ // and DatasetPage.canDownloadFile(fileMetadata) } - /** - * Check if this is a mappable file type. - * - * Currently (2/2016) - * - Shapefile (zipped shapefile) - * - Tabular file with Geospatial Data tag - * - * @param fm - * @return - */ - private boolean isPotentiallyMappableFileType(FileMetadata fm){ - if (fm==null){ - return false; - } - - // Yes, it's a shapefile - // - if (this.isShapefileType(fm)){ - return true; - } - - // Yes, it's tabular with a geospatial tag - // - if (fm.getDataFile().isTabularData()){ - if (fm.getDataFile().hasGeospatialTag()){ - return true; - } - } - return false; - } - /** * For development @@ -1305,83 +1105,114 @@ public boolean isGeoconnectDebugAvailable(){ /** - * Should there be a Explore WorldMap Button for this file? - * See table in: https://github.com/IQSS/dataverse/issues/1618 + * This object wraps methods used for hiding/displaying WorldMap related messages + * + */ + private void loadWorldMapPermissionHelper() { + + worldMapPermissionHelper = new WorldMapPermissionHelper(settingsService, mapLayerMetadataService, dataset); + + } + + /** * - * (1) Does the file have MapLayerMetadata? - * (2) Is there DownloadFile permission for this file? + * WARNING: Check if the user has file download permission + * - This check is assumed when calling to the worldMapPermissionHelper * - * @param fm FileMetadata - * @return boolean + * Should the user be able to see the WorldMap Explore button? + * + * @param fm + * @return */ public boolean canUserSeeExploreWorldMapButton(FileMetadata fm){ - if (fm==null){ + if ((worldMapPermissionHelper == null)||(fm == null)){ return false; } - if (this.fileMetadataWorldMapExplore.containsKey(fm.getId())){ - // Yes, return previous answer - //logger.info("using cached result for candownloadfile on filemetadata "+fid); - return this.fileMetadataWorldMapExplore.get(fm.getId()); - } - - /* ----------------------------------------------------- - Does a Map Exist? - ----------------------------------------------------- */ - if (!(this.hasMapLayerMetadata(fm))){ - // Nope: no button - this.fileMetadataWorldMapExplore.put(fm.getId(), false); - return false; - } - - /* - Is setting for GeoconnectViewMaps true? - Nope? no button - */ - if (!settingsService.isTrueForKey(SettingsServiceBean.Key.GeoconnectViewMaps, false)){ - this.fileMetadataWorldMapExplore.put(fm.getId(), false); + // You need to have download file permissions as a prereq! + // + if (!this.canDownloadFile(fm)){ return false; } - /* ----------------------------------------------------- - Does user have DownloadFile permission for this file? - Yes: User can view button! - ----------------------------------------------------- */ - if (this.canDownloadFile(fm)){ - this.fileMetadataWorldMapExplore.put(fm.getId(), true); - return true; + return worldMapPermissionHelper.canUserSeeExploreWorldMapButton(fm); + + } // end: canUserSeeExploreWorldMapButton + + + /** + * WARNING: Check if the user isAuthenicated AND has Permission.EditDataset + * - These checks are assumed when calling to the worldMapPermissionHelper + * + * If this is an unpublished Dataset with a mappable file, + * should the user see the "Reminder to Publish" button + * + * @param fm + * @return + */ + public boolean canSeeMapButtonReminderToPublish(FileMetadata fm){ + + if ((worldMapPermissionHelper == null)||(fm == null)){ + return false; } - - // Nope: Can't see button + + // Is this user authenticated with EditDataset permission? // - this.fileMetadataWorldMapExplore.put(fm.getId(), false); - return false; - } + if (!(isUserAuthenticatedWithEditDatasetPermission())){ + return false; + } + + return worldMapPermissionHelper.canSeeMapButtonReminderToPublish(fm); + + } // end: canSeeMapButtonReminderToPublish + /** - * Create a hashmap consisting of { DataFile.id : MapLayerMetadata object} - * - * Very few DataFiles will have associated MapLayerMetadata objects so only - * use 1 query to get them + * WARNING: Check if the user isAuthenicated AND has Permission.EditDataset + * - These checks are assumed when calling to the worldMapPermissionHelper + * + * Should the user be able to map this file? + * + * @param fm + * @return */ - private void loadMapLayerMetadataLookup() { - if (this.dataset == null) { - return; + public boolean canUserSeeMapDataButton(FileMetadata fm){ + + if ((worldMapPermissionHelper == null)||(fm == null)){ + return false; } - if (this.dataset.getId() == null) { - return; + + // Is this user authenticated with EditDataset permission? + // + if (!(isUserAuthenticatedWithEditDatasetPermission())){ + return false; } - List mapLayerMetadataList = mapLayerMetadataService.getMapLayerMetadataForDataset(this.dataset); - if (mapLayerMetadataList == null) { - return; + + return worldMapPermissionHelper.canUserSeeMapDataButton(fm); + + } + + /** + * Is this user authenticated with EditDataset permission + * + * @return + */ + private boolean isUserAuthenticatedWithEditDatasetPermission(){ + + // Is the user authenticated? + // + if (!(isSessionUserAuthenticated())){ + return false; } - for (MapLayerMetadata layer_metadata : mapLayerMetadataList) { - mapLayerMetadataLookup.put(layer_metadata.getDataFile().getId(), layer_metadata); + + // If so, can the logged in user edit the Dataset to which this FileMetadata belongs? + // + if (!this.doesSessionUserHaveDataSetPermission(Permission.EditDataset)){ + return false; } - - }// A DataFile may have a related MapLayerMetadata object - - + + return true; + } private List displayFileMetadata; @@ -1549,7 +1380,7 @@ private String init(boolean initFull) { //SEK - lazymodel may be needed for datascroller in future release // lazyModel = new LazyFileMetadataDataModel(workingVersion.getId(), datafileService ); // populate MapLayerMetadata - this.loadMapLayerMetadataLookup(); // A DataFile may have a related MapLayerMetadata object + this.loadWorldMapPermissionHelper(); // A DataFile may have a related MapLayerMetadata object } } else if (ownerId != null) { // create mode for a new child dataset diff --git a/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java b/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java index 5d4a65a4c8a..97fb4f20bb8 100644 --- a/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java @@ -1030,6 +1030,12 @@ public String cancel() { return returnToDatasetOnly(); } + /** + * Just moved to another class for now + * + * @param fileMetadata + * @return + */ public boolean isDuplicate(FileMetadata fileMetadata) { return DuplicateFileChecker.IsDuplicateOriginalWay(workingVersion, fileMetadata); @@ -1229,6 +1235,9 @@ private String processUploadedFileList(List dFileList){ boolean multipleDupes = false; String warningMessage = null; + // NOTE: for native file uploads, the dFileList will only + // contain 1 file--method is called for every file even if the UI shows "simultaneous uploads" + // ----------------------------------------------------------- // Iterate through list of DataFile objects // ----------------------------------------------------------- @@ -1255,9 +1264,11 @@ private String processUploadedFileList(List dFileList){ // ----------------------------------------------------------- // Check for duplicates -- e.g. file is already in the dataset // ----------------------------------------------------------- + if (!isDuplicate(dataFile.getFileMetadata())) { newFiles.add(dataFile); // looks good fileMetadatas.add(dataFile.getFileMetadata()); + } else { if (duplicateFileNames == null) { duplicateFileNames = dataFile.getFileMetadata().getLabel(); @@ -1289,7 +1300,7 @@ private String processUploadedFileList(List dFileList){ } } } - + // ----------------------------------------------------------- // Formate error message for duplicate files // ----------------------------------------------------------- diff --git a/src/main/java/edu/harvard/iq/dataverse/datasetutility/WorldMapPermissionHelper.java b/src/main/java/edu/harvard/iq/dataverse/datasetutility/WorldMapPermissionHelper.java new file mode 100644 index 00000000000..0877cff4f2e --- /dev/null +++ b/src/main/java/edu/harvard/iq/dataverse/datasetutility/WorldMapPermissionHelper.java @@ -0,0 +1,320 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package edu.harvard.iq.dataverse.datasetutility; + +import edu.harvard.iq.dataverse.DataFile; +import edu.harvard.iq.dataverse.Dataset; +import edu.harvard.iq.dataverse.FileMetadata; +import edu.harvard.iq.dataverse.MapLayerMetadata; +import edu.harvard.iq.dataverse.MapLayerMetadataServiceBean; +import edu.harvard.iq.dataverse.authorization.Permission; +import edu.harvard.iq.dataverse.settings.SettingsServiceBean; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * + * @author rmp553 + */ +public class WorldMapPermissionHelper { + + private SettingsServiceBean settingsService; + private MapLayerMetadataServiceBean mapLayerMetadataService; + + private Dataset dataset; + + private final Map fileMetadataWorldMapExplore = new HashMap<>(); // { FileMetadata.id : Boolean } + private final Map mapLayerMetadataLookup = new HashMap<>(); + + + public WorldMapPermissionHelper(SettingsServiceBean settingsService, MapLayerMetadataServiceBean mapLayerMetadataService, + Dataset dataset){ + + if (dataset == null){ + throw new NullPointerException("dataset cannot be null"); + } + if (dataset.getId() == null){ + throw new NullPointerException("dataset must be saved! (have an id)"); + } + + if (settingsService == null){ + throw new NullPointerException("settingsService cannot be null"); + } + if (mapLayerMetadataService == null){ + throw new NullPointerException("mapLayerMetadataService cannot be null"); + } + this.dataset = dataset; + + this.settingsService = settingsService; + this.mapLayerMetadataService = mapLayerMetadataService; + + loadMapLayerMetadataLookup(); + } + + + + /** + * Create a hashmap consisting of { DataFile.id : MapLayerMetadata object} + * + * Very few DataFiles will have associated MapLayerMetadata objects so only + * use 1 query to get them + */ + private void loadMapLayerMetadataLookup() { + + + List mapLayerMetadataList = mapLayerMetadataService.getMapLayerMetadataForDataset(this.dataset); + if (mapLayerMetadataList == null) { + return; + } + for (MapLayerMetadata layer_metadata : mapLayerMetadataList) { + mapLayerMetadataLookup.put(layer_metadata.getDataFile().getId(), layer_metadata); + } + + }// A DataFile may have a related MapLayerMetadata object + + + /** + * Using a DataFile id, retrieve an associated MapLayerMetadata object + * + * The MapLayerMetadata objects have been fetched at page inception by + * "loadMapLayerMetadataLookup()" + */ + public MapLayerMetadata getMapLayerMetadata(DataFile df) { + if (df == null) { + return null; + } + return this.mapLayerMetadataLookup.get(df.getId()); + } + + /** + * WARNING: Before calling this, make sure the user has download + * permission for the file!! (See DatasetPage.canDownloadFile()) + * + * Should there be a Explore WorldMap Button for this file? + * See table in: https://github.com/IQSS/dataverse/issues/1618 + * + * (1) Does the file have MapLayerMetadata? + * (2) Are the proper settings in place + * + * @param fm FileMetadata + * @return boolean + */ + public boolean canUserSeeExploreWorldMapButton(FileMetadata fm){ + if (fm==null){ + return false; + } + + if (this.fileMetadataWorldMapExplore.containsKey(fm.getId())){ + // Yes, return previous answer + //logger.info("using cached result for candownloadfile on filemetadata "+fid); + return this.fileMetadataWorldMapExplore.get(fm.getId()); + } + + /* ----------------------------------------------------- + Does a Map Exist? + ----------------------------------------------------- */ + if (!(this.hasMapLayerMetadata(fm))){ + // Nope: no button + this.fileMetadataWorldMapExplore.put(fm.getId(), false); + return false; + } + + /* + Is setting for GeoconnectViewMaps true? + Nope? no button + */ + if (!settingsService.isTrueForKey(SettingsServiceBean.Key.GeoconnectViewMaps, false)){ + this.fileMetadataWorldMapExplore.put(fm.getId(), false); + return false; + } + + /* ----------------------------------------------------- + Yes: User can view button! + ----------------------------------------------------- */ + this.fileMetadataWorldMapExplore.put(fm.getId(), true); + return true; + } + + + /* + Check if the FileMetadata.dataFile has an associated MapLayerMetadata object + + The MapLayerMetadata objects have been fetched at page inception by "loadMapLayerMetadataLookup()" + */ + public boolean hasMapLayerMetadata(FileMetadata fm) { + if (fm == null) { + return false; + } + if (fm.getDataFile() == null) { + return false; + } + return doesDataFileHaveMapLayerMetadata(fm.getDataFile()); + } + + /** + * Check if a DataFile has an associated MapLayerMetadata object + * + * The MapLayerMetadata objects have been fetched at page inception by + * "loadMapLayerMetadataLookup()" + */ + private boolean doesDataFileHaveMapLayerMetadata(DataFile df) { + if (df == null) { + return false; + } + if (df.getId() == null) { + return false; + } + return this.mapLayerMetadataLookup.containsKey(df.getId()); + } + + + + /** + * Check if this is a mappable file type. + * + * Currently (2/2016) + * - Shapefile (zipped shapefile) + * - Tabular file with Geospatial Data tag + * + * @param fm + * @return + */ + private boolean isPotentiallyMappableFileType(FileMetadata fm){ + if (fm==null){ + return false; + } + + // Yes, it's a shapefile + // + if (this.isShapefileType(fm)){ + return true; + } + + // Yes, it's tabular with a geospatial tag + // + if (fm.getDataFile().isTabularData()){ + if (fm.getDataFile().hasGeospatialTag()){ + return true; + } + } + return false; + } + + + + public boolean isShapefileType(FileMetadata fm) { + if (fm == null) { + return false; + } + if (fm.getDataFile() == null) { + return false; + } + + return fm.getDataFile().isShapefileType(); + } + + + /** + * WARNING: Assumes user isAuthenicated AND has Permission.EditDataset + * - These checks are made on the DatasetPage which calls this method + * + * See table in: https://github.com/IQSS/dataverse/issues/1618 + * + * Can the user see a reminder to publish button? + * (0) The application has to be set to Create Edit Maps - true + * (1) Logged in user + * (2) Is geospatial file? + * (3) File has NOT been released + * (4) No existing Map + * (5) Can Edit Dataset + * + * @param FileMetadata fm + * @return boolean + */ + public boolean canSeeMapButtonReminderToPublish(FileMetadata fm){ + if (fm==null){ + + return false; + } + + // (1) Is the view GeoconnectViewMaps + if (!settingsService.isTrueForKey(SettingsServiceBean.Key.GeoconnectCreateEditMaps, false)){ + return false; + } + + + // (2) Is this file a Shapefile or a Tabular file tagged as Geospatial? + // + if (!(this.isPotentiallyMappableFileType(fm))){ + return false; + } + + // (3) Is this DataFile released? Yes, don't need reminder + // + if (fm.getDataFile().isReleased()){ + return false; + } + + // (4) Does a map already exist? Yes, don't need reminder + // + if (this.hasMapLayerMetadata(fm)){ + return false; + } + + // Looks good + // + return true; + } + + /** + * + * WARNING: Assumes user isAuthenicated AND has Permission.EditDataset + * - These checks are made on the DatasetPage which calls this method + * + * Should there be a Map Data Button for this file? + * see table in: https://github.com/IQSS/dataverse/issues/1618 + * (1) Is the user logged in? + * (2) Is this file a Shapefile or a Tabular file tagged as Geospatial? + * (3) Does the logged in user have permission to edit the Dataset to which this FileMetadata belongs? + * (4) Is the create Edit Maps flag set to true? + * (5) Any of these conditions: + * 9a) File Published + * (b) Draft: File Previously published + * @param fm FileMetadata + * @return boolean + */ + public boolean canUserSeeMapDataButton(FileMetadata fm){ + + if (fm==null){ + return false; + } + + // (1) Is this file a Shapefile or a Tabular file tagged as Geospatial? + // TO DO: EXPAND FOR TABULAR FILES TAGGED AS GEOSPATIAL! + // + if (!(this.isPotentiallyMappableFileType(fm))){ + return false; + } + + + // (2) Is the view GeoconnectViewMaps + if (!settingsService.isTrueForKey(SettingsServiceBean.Key.GeoconnectCreateEditMaps, false)){ + return false; + } + + // (3) Is File released? + // + if (fm.getDataFile().isReleased()){ + return true; + } + + // Nope + return false; + } + + +} From b77ab3725a29516467c5e8277b0bd0a3bef4b570 Mon Sep 17 00:00:00 2001 From: Raman Prasad Date: Wed, 21 Sep 2016 15:34:19 -0400 Subject: [PATCH 03/86] further updates, methods for api calls and file page --- .../edu/harvard/iq/dataverse/DatasetPage.java | 9 +- .../WorldMapPermissionHelper.java | 226 ++++++++++++++++-- 2 files changed, 214 insertions(+), 21 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index fbe7628c406..fc1503b0e53 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -85,7 +85,6 @@ import javax.faces.event.AjaxBehaviorEvent; -import javax.faces.context.ExternalContext; import org.apache.commons.lang.StringEscapeUtils; import org.primefaces.component.tabview.TabView; @@ -1110,7 +1109,7 @@ public boolean isGeoconnectDebugAvailable(){ */ private void loadWorldMapPermissionHelper() { - worldMapPermissionHelper = new WorldMapPermissionHelper(settingsService, mapLayerMetadataService, dataset); + worldMapPermissionHelper = WorldMapPermissionHelper.getPermissionHelperForDatasetPage(settingsService, mapLayerMetadataService, dataset); } @@ -1135,7 +1134,7 @@ public boolean canUserSeeExploreWorldMapButton(FileMetadata fm){ return false; } - return worldMapPermissionHelper.canUserSeeExploreWorldMapButton(fm); + return worldMapPermissionHelper.canUserSeeExploreWorldMapButtonFromPage(fm); } // end: canUserSeeExploreWorldMapButton @@ -1162,7 +1161,7 @@ public boolean canSeeMapButtonReminderToPublish(FileMetadata fm){ return false; } - return worldMapPermissionHelper.canSeeMapButtonReminderToPublish(fm); + return worldMapPermissionHelper.canSeeMapButtonReminderToPublishFromPage(fm); } // end: canSeeMapButtonReminderToPublish @@ -1188,7 +1187,7 @@ public boolean canUserSeeMapDataButton(FileMetadata fm){ return false; } - return worldMapPermissionHelper.canUserSeeMapDataButton(fm); + return worldMapPermissionHelper.canUserSeeMapDataButtonFromPage(fm); } diff --git a/src/main/java/edu/harvard/iq/dataverse/datasetutility/WorldMapPermissionHelper.java b/src/main/java/edu/harvard/iq/dataverse/datasetutility/WorldMapPermissionHelper.java index 0877cff4f2e..eece1bb48fe 100644 --- a/src/main/java/edu/harvard/iq/dataverse/datasetutility/WorldMapPermissionHelper.java +++ b/src/main/java/edu/harvard/iq/dataverse/datasetutility/WorldMapPermissionHelper.java @@ -10,20 +10,39 @@ import edu.harvard.iq.dataverse.FileMetadata; import edu.harvard.iq.dataverse.MapLayerMetadata; import edu.harvard.iq.dataverse.MapLayerMetadataServiceBean; +import edu.harvard.iq.dataverse.PermissionServiceBean; import edu.harvard.iq.dataverse.authorization.Permission; +import edu.harvard.iq.dataverse.authorization.users.User; import edu.harvard.iq.dataverse.settings.SettingsServiceBean; import java.util.HashMap; import java.util.List; import java.util.Map; /** - * + * This class originally encapsulated display logic for the DatasetPage + * + * It allows the following checks without redundantly querying the db to + * check permissions or if MapLayerMetadata exists + * + * - canUserSeeMapDataButton (private) + * - canUserSeeMapDataButtonFromPage (public) + * - canUserSeeMapDataButtonFromAPI (public) + * + * - canSeeMapButtonReminderToPublish (private) + * - canSeeMapButtonReminderToPublishFromPage (public) + * - canSeeMapButtonReminderToPublishFromAPI (public) + * + * - canUserSeeExploreWorldMapButton (private) + * - canUserSeeExploreWorldMapButtonFromPage (public) + * - canUserSeeExploreWorldMapButtonFromAPI (public) + * * @author rmp553 */ public class WorldMapPermissionHelper { private SettingsServiceBean settingsService; private MapLayerMetadataServiceBean mapLayerMetadataService; + private PermissionServiceBean permissionService; private Dataset dataset; @@ -32,7 +51,7 @@ public class WorldMapPermissionHelper { public WorldMapPermissionHelper(SettingsServiceBean settingsService, MapLayerMetadataServiceBean mapLayerMetadataService, - Dataset dataset){ + Dataset dataset, PermissionServiceBean permissionService){ if (dataset == null){ throw new NullPointerException("dataset cannot be null"); @@ -47,15 +66,58 @@ public WorldMapPermissionHelper(SettingsServiceBean settingsService, MapLayerMet if (mapLayerMetadataService == null){ throw new NullPointerException("mapLayerMetadataService cannot be null"); } + this.dataset = dataset; this.settingsService = settingsService; this.mapLayerMetadataService = mapLayerMetadataService; + this.permissionService = permissionService; loadMapLayerMetadataLookup(); } + /** + * Convenience method for instantiating from dataset page or File page + * + * Does NOT use PermissionServiceBean + * + * @param settingsService + * @param mapLayerMetadataService + * @param dataset + * @return + */ + public static WorldMapPermissionHelper getPermissionHelperForDatasetPage( + SettingsServiceBean settingsService, MapLayerMetadataServiceBean mapLayerMetadataService, + Dataset dataset){ + + return new WorldMapPermissionHelper(settingsService, mapLayerMetadataService, dataset, null); + } + + /** + * Convenience method for instantiating from the API + * + * REQUIRES PermissionServiceBean + * + * @param settingsService + * @param mapLayerMetadataService + * @param dataset + * @param permissionService + * @return + */ + public static WorldMapPermissionHelper getPermissionHelperForAPI( + SettingsServiceBean settingsService, + MapLayerMetadataServiceBean mapLayerMetadataService, + Dataset dataset, + PermissionServiceBean permissionService){ + + if (permissionService == null){ + throw new NullPointerException("permissionService is required for API checks"); + } + + return new WorldMapPermissionHelper(settingsService, mapLayerMetadataService, dataset, permissionService); + } + /** * Create a hashmap consisting of { DataFile.id : MapLayerMetadata object} @@ -90,6 +152,45 @@ public MapLayerMetadata getMapLayerMetadata(DataFile df) { return this.mapLayerMetadataLookup.get(df.getId()); } + + /* + * Call this when using the API + * - calls private method canUserSeeExploreWorldMapButton + */ + public boolean canUserSeeExploreWorldMapButtonFromAPI(FileMetadata fm, User user){ + + if (fm == null){ + return false; + } + if (user==null){ + return false; + } + if (!this.permissionService.userOn(user, fm.getDataFile()).has(Permission.DownloadFile)){ + return false; + } + + return this.canUserSeeExploreWorldMapButton(fm, true); + } + + /** + * Call this for a Dataset or File page + * - calls private method canUserSeeExploreWorldMapButton + * + * WARNING: Before calling this, make sure the user has download + * permission for the file!! (See DatasetPage.canDownloadFile()) + * + * @param FileMetadata fm + * @return boolean + */ + public boolean canUserSeeExploreWorldMapButtonFromPage(FileMetadata fm){ + + if (fm==null){ + return false; + } + + return this.canUserSeeExploreWorldMapButton(fm, true); + } + /** * WARNING: Before calling this, make sure the user has download * permission for the file!! (See DatasetPage.canDownloadFile()) @@ -103,11 +204,16 @@ public MapLayerMetadata getMapLayerMetadata(DataFile df) { * @param fm FileMetadata * @return boolean */ - public boolean canUserSeeExploreWorldMapButton(FileMetadata fm){ + public boolean canUserSeeExploreWorldMapButton(FileMetadata fm, boolean permissionsChecked){ + if (fm==null){ return false; } + if (!permissionsChecked){ + return false; + } + if (this.fileMetadataWorldMapExplore.containsKey(fm.getId())){ // Yes, return previous answer //logger.info("using cached result for candownloadfile on filemetadata "+fid); @@ -219,28 +325,72 @@ public boolean isShapefileType(FileMetadata fm) { /** - * WARNING: Assumes user isAuthenicated AND has Permission.EditDataset - * - These checks are made on the DatasetPage which calls this method + * Call this for a Dataset or File page + * - calls private method canSeeMapButtonReminderToPublish * - * See table in: https://github.com/IQSS/dataverse/issues/1618 + * WARNING: Assumes user isAuthenicated AND has Permission.EditDataset + * - These checks should be made on the DatasetPage or FilePage which calls this method * - * Can the user see a reminder to publish button? - * (0) The application has to be set to Create Edit Maps - true - * (1) Logged in user - * (2) Is geospatial file? - * (3) File has NOT been released - * (4) No existing Map - * (5) Can Edit Dataset * * @param FileMetadata fm * @return boolean */ - public boolean canSeeMapButtonReminderToPublish(FileMetadata fm){ - if (fm==null){ + public boolean canSeeMapButtonReminderToPublishFromPage(FileMetadata fm){ + if (fm == null){ + return false; + } + + return this.canSeeMapButtonReminderToPublish(fm, true); + + } + + /** + * Call this when using the API + * - calls private method canSeeMapButtonReminderToPublish + * + * @param fm + * @param user + * @return + */ + public boolean canSeeMapButtonReminderToPublishFromAPI(FileMetadata fm, User user){ + if (fm == null){ + return false; + } + if (user==null){ + return false; + } + + if (!this.permissionService.userOn(user, this.dataset).has(Permission.EditDataset)){ + return false; + } + + return this.canSeeMapButtonReminderToPublish(fm, true); + + } + + + + /** + * Assumes permissions have been checked!! + * + * See table in: https://github.com/IQSS/dataverse/issues/1618 + * + * Can the user see a reminder to publish button? + * (1) Is the view GeoconnectViewMaps + * (2) Is this file a Shapefile or a Tabular file tagged as Geospatial? + * (3) Is this DataFile released? Yes, don't need reminder + * (4) Does a map already exist? Yes, don't need reminder + */ + private boolean canSeeMapButtonReminderToPublish(FileMetadata fm, boolean permissionsChecked){ + if (fm==null){ return false; } + if (!permissionsChecked){ + return false; + } + // (1) Is the view GeoconnectViewMaps if (!settingsService.isTrueForKey(SettingsServiceBean.Key.GeoconnectCreateEditMaps, false)){ return false; @@ -268,6 +418,46 @@ public boolean canSeeMapButtonReminderToPublish(FileMetadata fm){ // Looks good // return true; + } + + /** + * + * WARNING: Assumes user isAuthenicated AND has Permission.EditDataset + * - These checks are made on the DatasetPage which calls this method + * + */ + public boolean canUserSeeMapDataButtonFromPage(FileMetadata fm){ + + if (fm==null){ + return false; + } + return this.canUserSeeMapDataButton(fm, true); + } + + + + /** + * Call this when using the API + * - calls private method canUserSeeMapDataButton + * + * @param fm + * @param user + * @return + */ + public boolean canUserSeeMapDataButtonFromAPI(FileMetadata fm, User user){ + if (fm == null){ + return false; + } + if (user==null){ + return false; + } + + if (!this.permissionService.userOn(user, this.dataset).has(Permission.EditDataset)){ + return false; + } + + return this.canUserSeeMapDataButton(fm, true); + } /** @@ -287,11 +477,15 @@ public boolean canSeeMapButtonReminderToPublish(FileMetadata fm){ * @param fm FileMetadata * @return boolean */ - public boolean canUserSeeMapDataButton(FileMetadata fm){ + private boolean canUserSeeMapDataButton(FileMetadata fm, boolean permissionsChecked){ if (fm==null){ return false; } + + if (!permissionsChecked){ + return false; + } // (1) Is this file a Shapefile or a Tabular file tagged as Geospatial? // TO DO: EXPAND FOR TABULAR FILES TAGGED AS GEOSPATIAL! From 0badbf8aab908b167b661456d6b67dc6c67f1f74 Mon Sep 17 00:00:00 2001 From: Raman Prasad Date: Wed, 21 Sep 2016 16:02:29 -0400 Subject: [PATCH 04/86] For #2290 and #2465. Move twoRavens code from dataset page to separate class --- .../edu/harvard/iq/dataverse/DatasetPage.java | 143 ++++-------- .../datasetutility/TwoRavensHelper.java | 203 ++++++++++++++++++ .../WorldMapPermissionHelper.java | 9 +- 3 files changed, 256 insertions(+), 99 deletions(-) create mode 100644 src/main/java/edu/harvard/iq/dataverse/datasetutility/TwoRavensHelper.java diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index fc1503b0e53..26370afcb30 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -9,6 +9,7 @@ import edu.harvard.iq.dataverse.authorization.users.PrivateUrlUser; import edu.harvard.iq.dataverse.authorization.users.GuestUser; import edu.harvard.iq.dataverse.datasetutility.DuplicateFileChecker; +import edu.harvard.iq.dataverse.datasetutility.TwoRavensHelper; import edu.harvard.iq.dataverse.datasetutility.WorldMapPermissionHelper; import edu.harvard.iq.dataverse.datavariable.VariableServiceBean; import edu.harvard.iq.dataverse.engine.command.Command; @@ -213,11 +214,12 @@ public enum DisplayMode { // Used to help with displaying buttons related to the WorldMap private WorldMapPermissionHelper worldMapPermissionHelper; + // Used to help with displaying buttons related to TwoRavens + private TwoRavensHelper twoRavensHelper; + // Used to store results of permissions checks private final Map datasetPermissionMap = new HashMap<>(); // { Permission human_name : Boolean } private final Map fileDownloadPermissionMap = new HashMap<>(); // { FileMetadata.id : Boolean } - - private final Map fileMetadataTwoRavensExploreMap = new HashMap<>(); // { FileMetadata.id : Boolean } private DataFile selectedDownloadFile; @@ -1019,67 +1021,7 @@ private void msg(String s){ } - /** - * Used in the .xhtml file to check whether a tabular file - * may be viewed via TwoRavens - * - * @param fm - * @return - */ - public boolean canSeeTwoRavensExploreButton(FileMetadata fm){ - - if (fm == null){ - return false; - } - - // Has this already been checked? - if (this.fileMetadataTwoRavensExploreMap.containsKey(fm.getId())){ - // Yes, return previous answer - //logger.info("using cached result for candownloadfile on filemetadata "+fid); - return this.fileMetadataTwoRavensExploreMap.get(fm.getId()); - } - - - // (1) Is TwoRavens active via the "setting" table? - // Nope: get out - // - if (!settingsService.isTrueForKey(SettingsServiceBean.Key.TwoRavensTabularView, false)){ - this.fileMetadataTwoRavensExploreMap.put(fm.getId(), false); - return false; - } - - // (2) Does the user have download permission? - // Nope: get out - // - if (!(this.canDownloadFile(fm))){ - this.fileMetadataTwoRavensExploreMap.put(fm.getId(), false); - return false; - } - // (3) Is the DataFile object there and persisted? - // Nope: scat - // - if ((fm.getDataFile() == null)||(fm.getDataFile().getId()==null)){ - this.fileMetadataTwoRavensExploreMap.put(fm.getId(), false); - return false; - } - - // (4) Is there tabular data or is the ingest in progress? - // Yes: great - // - if ((fm.getDataFile().isTabularData())||(fm.getDataFile().isIngestInProgress())){ - this.fileMetadataTwoRavensExploreMap.put(fm.getId(), true); - return true; - } - - // Nope - this.fileMetadataTwoRavensExploreMap.put(fm.getId(), false); - return false; - - // (empty fileMetadata.dataFile.id) and (fileMetadata.dataFile.tabularData or fileMetadata.dataFile.ingestInProgress) - // and DatasetPage.canDownloadFile(fileMetadata) - } - - + /** * For development * @@ -1103,6 +1045,47 @@ public boolean isGeoconnectDebugAvailable(){ } + /** + * This object wraps methods used for hiding/displaying WorldMap related messages + * + */ + private void loadTwoRavensHelper() { + + twoRavensHelper = new TwoRavensHelper(settingsService, permissionService); + + } + + public boolean canSeeTwoRavensExploreButton(FileMetadata fm){ + if (fm == null){ + return false; + } + if (twoRavensHelper == null){ + return false; + } + + return twoRavensHelper.canSeeTwoRavensExploreButtonFromPage(fm); + } + + + public String getDataExploreURL() { + if (twoRavensHelper == null){ + return ""; + } + return twoRavensHelper.getDataExploreURL(); + } + + + public String getDataExploreURLComplete(Long fileid) { + if (twoRavensHelper == null){ + return ""; + } + return twoRavensHelper.getDataExploreURLComplete(fileid, getApiTokenKey()); + + + // return TwoRavensDefaultLocal + fileid + "&" + getApiTokenKey(); + } + + /** * This object wraps methods used for hiding/displaying WorldMap related messages * @@ -1380,6 +1363,7 @@ private String init(boolean initFull) { // lazyModel = new LazyFileMetadataDataModel(workingVersion.getId(), datafileService ); // populate MapLayerMetadata this.loadWorldMapPermissionHelper(); // A DataFile may have a related MapLayerMetadata object + this.loadTwoRavensHelper(); } } else if (ownerId != null) { // create mode for a new child dataset @@ -3220,40 +3204,7 @@ public Boolean isDatasetPublishPopupCustomTextOnAllVersions(){ return settingsService.isTrueForKey(SettingsServiceBean.Key.DatasetPublishPopupCustomTextOnAllVersions, false); } - public String getDataExploreURL() { - String TwoRavensUrl = settingsService.getValueForKey(SettingsServiceBean.Key.TwoRavensUrl); - if (TwoRavensUrl != null && !TwoRavensUrl.equals("")) { - return TwoRavensUrl; - } - - return ""; - } - - public String getDataExploreURLComplete(Long fileid) { - String TwoRavensUrl = settingsService.getValueForKey(SettingsServiceBean.Key.TwoRavensUrl); - String TwoRavensDefaultLocal = "/dataexplore/gui.html?dfId="; - - if (TwoRavensUrl != null && !TwoRavensUrl.equals("")) { - // If we have TwoRavensUrl set up as, as an optional - // configuration service, it must mean that TwoRavens is sitting - // on some remote server. And that in turn means that we must use - // full URLs to pass data and metadata to it. - // update: actually, no we don't want to use this "dataurl" notation. - // switching back to the dfId=: - // -- L.A. 4.1 - /* - String tabularDataURL = getTabularDataFileURL(fileid); - String tabularMetaURL = getVariableMetadataURL(fileid); - return TwoRavensUrl + "?ddiurl=" + tabularMetaURL + "&dataurl=" + tabularDataURL + "&" + getApiTokenKey(); - */ - return TwoRavensUrl + "?dfId=" + fileid + "&" + getApiTokenKey(); - } - - // For a local TwoRavens setup it's enough to call it with just - // the file id: - return TwoRavensDefaultLocal + fileid + "&" + getApiTokenKey(); - } public String getVariableMetadataURL(Long fileid) { String myHostURL = getDataverseSiteUrl(); diff --git a/src/main/java/edu/harvard/iq/dataverse/datasetutility/TwoRavensHelper.java b/src/main/java/edu/harvard/iq/dataverse/datasetutility/TwoRavensHelper.java new file mode 100644 index 00000000000..fa16e83be12 --- /dev/null +++ b/src/main/java/edu/harvard/iq/dataverse/datasetutility/TwoRavensHelper.java @@ -0,0 +1,203 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package edu.harvard.iq.dataverse.datasetutility; + +import edu.harvard.iq.dataverse.FileMetadata; +import edu.harvard.iq.dataverse.PermissionServiceBean; +import edu.harvard.iq.dataverse.authorization.Permission; +import edu.harvard.iq.dataverse.authorization.users.User; +import edu.harvard.iq.dataverse.settings.SettingsServiceBean; +import java.util.HashMap; +import java.util.Map; + +/** + * + * @author rmp553 + */ +public class TwoRavensHelper { + + private final SettingsServiceBean settingsService; + private PermissionServiceBean permissionService; + + private final Map fileMetadataTwoRavensExploreMap = new HashMap<>(); // { FileMetadata.id : Boolean } + + public TwoRavensHelper(SettingsServiceBean settingsService, PermissionServiceBean permissionService){ + if (settingsService == null){ + throw new NullPointerException("settingsService cannot be null"); + } + if (permissionService == null){ + throw new NullPointerException("permissionService cannot be null"); + } + this.permissionService = permissionService; + this.settingsService = settingsService; + + + } + + + /** + * Call this from a Dataset or File page + * - calls private method canSeeTwoRavensExploreButton + * + * WARNING: Before calling this, make sure the user has download + * permission for the file!! (See DatasetPage.canDownloadFile()) + * + * @param fm + * @return + */ + public boolean canSeeTwoRavensExploreButtonFromAPI(FileMetadata fm, User user){ + + if (fm == null){ + return false; + } + + if (user == null){ + return false; + } + + if (!this.permissionService.userOn(user, fm.getDataFile()).has(Permission.DownloadFile)){ + return false; + } + + return this.canSeeTwoRavensExploreButton(fm, true); + } + + /** + * Call this from a Dataset or File page + * - calls private method canSeeTwoRavensExploreButton + * + * WARNING: Before calling this, make sure the user has download + * permission for the file!! (See DatasetPage.canDownloadFile()) + * + * @param fm + * @return + */ + public boolean canSeeTwoRavensExploreButtonFromPage(FileMetadata fm){ + + if (fm == null){ + return false; + } + + return this.canSeeTwoRavensExploreButton(fm, true); + } + + /** + * Used to check whether a tabular file + * may be viewed via TwoRavens + * + * @param fm + * @return + */ + public boolean canSeeTwoRavensExploreButton(FileMetadata fm, boolean permissionsChecked){ + + if (fm == null){ + return false; + } + + // This is only here as a reminder to the public method users + if (!permissionsChecked){ + return false; + } + + // Has this already been checked? + if (this.fileMetadataTwoRavensExploreMap.containsKey(fm.getId())){ + // Yes, return previous answer + //logger.info("using cached result for candownloadfile on filemetadata "+fid); + return this.fileMetadataTwoRavensExploreMap.get(fm.getId()); + } + + + // (1) Is TwoRavens active via the "setting" table? + // Nope: get out + // + if (!settingsService.isTrueForKey(SettingsServiceBean.Key.TwoRavensTabularView, false)){ + this.fileMetadataTwoRavensExploreMap.put(fm.getId(), false); + return false; + } + + + // (2) Is the DataFile object there and persisted? + // Nope: scat + // + if ((fm.getDataFile() == null)||(fm.getDataFile().getId()==null)){ + this.fileMetadataTwoRavensExploreMap.put(fm.getId(), false); + return false; + } + + // (3) Is there tabular data or is the ingest in progress? + // Yes: great + // + if ((fm.getDataFile().isTabularData())||(fm.getDataFile().isIngestInProgress())){ + this.fileMetadataTwoRavensExploreMap.put(fm.getId(), true); + return true; + } + + // Nope + this.fileMetadataTwoRavensExploreMap.put(fm.getId(), false); + return false; + + // (empty fileMetadata.dataFile.id) and (fileMetadata.dataFile.tabularData or fileMetadata.dataFile.ingestInProgress) + // and DatasetPage.canDownloadFile(fileMetadata) + } + + + /** + * Copied over from the dataset page - 9/21/2016 + * + * @return + */ + public String getDataExploreURL() { + String TwoRavensUrl = settingsService.getValueForKey(SettingsServiceBean.Key.TwoRavensUrl); + + if (TwoRavensUrl != null && !TwoRavensUrl.equals("")) { + return TwoRavensUrl; + } + + return ""; + } + + + /** + * Copied over from the dataset page - 9/21/2016 + * + * @param fileid + * @param apiTokenKey + * @return + */ + public String getDataExploreURLComplete(Long fileid, String apiTokenKey) { + + if (fileid == null){ + throw new NullPointerException("fileid cannot be null"); + } + if (apiTokenKey == null){ + throw new NullPointerException("apiTokenKey cannot be null (at least adding this check)"); + } + + + String TwoRavensUrl = settingsService.getValueForKey(SettingsServiceBean.Key.TwoRavensUrl); + String TwoRavensDefaultLocal = "/dataexplore/gui.html?dfId="; + + if (TwoRavensUrl != null && !TwoRavensUrl.equals("")) { + // If we have TwoRavensUrl set up as, as an optional + // configuration service, it must mean that TwoRavens is sitting + // on some remote server. And that in turn means that we must use + // full URLs to pass data and metadata to it. + // update: actually, no we don't want to use this "dataurl" notation. + // switching back to the dfId=: + // -- L.A. 4.1 + /* + String tabularDataURL = getTabularDataFileURL(fileid); + String tabularMetaURL = getVariableMetadataURL(fileid); + return TwoRavensUrl + "?ddiurl=" + tabularMetaURL + "&dataurl=" + tabularDataURL + "&" + getApiTokenKey(); + */ + return TwoRavensUrl + "?dfId=" + fileid + "&" + apiTokenKey; + } + + // For a local TwoRavens setup it's enough to call it with just + // the file id: + return TwoRavensDefaultLocal + fileid + "&" + apiTokenKey; + } +} diff --git a/src/main/java/edu/harvard/iq/dataverse/datasetutility/WorldMapPermissionHelper.java b/src/main/java/edu/harvard/iq/dataverse/datasetutility/WorldMapPermissionHelper.java index eece1bb48fe..69205f29452 100644 --- a/src/main/java/edu/harvard/iq/dataverse/datasetutility/WorldMapPermissionHelper.java +++ b/src/main/java/edu/harvard/iq/dataverse/datasetutility/WorldMapPermissionHelper.java @@ -173,7 +173,7 @@ public boolean canUserSeeExploreWorldMapButtonFromAPI(FileMetadata fm, User user } /** - * Call this for a Dataset or File page + * Call this from a Dataset or File page * - calls private method canUserSeeExploreWorldMapButton * * WARNING: Before calling this, make sure the user has download @@ -204,12 +204,13 @@ public boolean canUserSeeExploreWorldMapButtonFromPage(FileMetadata fm){ * @param fm FileMetadata * @return boolean */ - public boolean canUserSeeExploreWorldMapButton(FileMetadata fm, boolean permissionsChecked){ + private boolean canUserSeeExploreWorldMapButton(FileMetadata fm, boolean permissionsChecked){ if (fm==null){ return false; } + // This is only here to make the public method users think... if (!permissionsChecked){ return false; } @@ -325,7 +326,7 @@ public boolean isShapefileType(FileMetadata fm) { /** - * Call this for a Dataset or File page + * Call this from a Dataset or File page * - calls private method canSeeMapButtonReminderToPublish * * WARNING: Assumes user isAuthenicated AND has Permission.EditDataset @@ -387,6 +388,7 @@ private boolean canSeeMapButtonReminderToPublish(FileMetadata fm, boolean permis return false; } + // This is only here as a reminder to the public method users if (!permissionsChecked){ return false; } @@ -483,6 +485,7 @@ private boolean canUserSeeMapDataButton(FileMetadata fm, boolean permissionsChec return false; } + // This is only here as a reminder to the public method users if (!permissionsChecked){ return false; } From 7810af4f3817b8cf48bb58b0f5007c04d94e11d0 Mon Sep 17 00:00:00 2001 From: Raman Prasad Date: Thu, 22 Sep 2016 14:06:10 -0400 Subject: [PATCH 05/86] adding typo change before mucking up repo too much... --- .../java/edu/harvard/iq/dataverse/DatasetPage.java | 2 +- .../edu/harvard/iq/dataverse/EditDatafilesPage.java | 2 +- .../java/edu/harvard/iq/dataverse/api/Admin.java | 13 +++++++++++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index 26370afcb30..83303f3255f 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -2654,7 +2654,7 @@ public String cancel() { public boolean isDuplicate(FileMetadata fileMetadata) { - return DuplicateFileChecker.IsDuplicateOriginalWay(workingVersion, fileMetadata); + return DuplicateFileChecker.isDuplicateOriginalWay(workingVersion, fileMetadata); } private HttpClient getClient() { diff --git a/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java b/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java index 97fb4f20bb8..9e41cddd102 100644 --- a/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java @@ -1038,7 +1038,7 @@ public String cancel() { */ public boolean isDuplicate(FileMetadata fileMetadata) { - return DuplicateFileChecker.IsDuplicateOriginalWay(workingVersion, fileMetadata); + return DuplicateFileChecker.isDuplicateOriginalWay(workingVersion, fileMetadata); } private HttpClient getClient() { diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java index 0026ec85a6b..921a72277b7 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java @@ -1,5 +1,6 @@ package edu.harvard.iq.dataverse.api; + import edu.harvard.iq.dataverse.Dataverse; import edu.harvard.iq.dataverse.EMailValidator; import edu.harvard.iq.dataverse.actionlogging.ActionLogRecord; @@ -30,7 +31,6 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.Response; - import static edu.harvard.iq.dataverse.util.json.NullSafeJsonBuilder.jsonObjectBuilder; import static edu.harvard.iq.dataverse.util.json.JsonPrinter.*; import java.io.StringReader; @@ -543,5 +543,14 @@ public Response convertUserFromBcryptToSha1(String json) { BuiltinUser savedUser = builtinUserService.save(builtinUser); return okResponse("foo: " + savedUser); } - + + + @Path("mymy") + @GET + public Response testIt_001() { + + return okResponse("hullo, system!"); + } + + } From 53616da18ade89048b89950f67d98f15e8d74d6c Mon Sep 17 00:00:00 2001 From: Raman Prasad Date: Thu, 22 Sep 2016 14:56:27 -0400 Subject: [PATCH 06/86] should have been in last commit with typo fix --- .../iq/dataverse/datasetutility/DuplicateFileChecker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/datasetutility/DuplicateFileChecker.java b/src/main/java/edu/harvard/iq/dataverse/datasetutility/DuplicateFileChecker.java index 7be3ae428fc..d2e38d50582 100644 --- a/src/main/java/edu/harvard/iq/dataverse/datasetutility/DuplicateFileChecker.java +++ b/src/main/java/edu/harvard/iq/dataverse/datasetutility/DuplicateFileChecker.java @@ -122,7 +122,7 @@ public Map getDatasetHashesFromDatabase(DatasetVersion datasetV * @param fileMetadata * @return */ - public static boolean IsDuplicateOriginalWay(DatasetVersion workingVersion, FileMetadata fileMetadata) { + public static boolean isDuplicateOriginalWay(DatasetVersion workingVersion, FileMetadata fileMetadata) { if (workingVersion == null){ throw new NullPointerException("datasetVersion cannot be null"); } From 26afcdf3d2fccb321bf8dba293ebc8f9716d040b Mon Sep 17 00:00:00 2001 From: Raman Prasad Date: Thu, 22 Sep 2016 16:56:22 -0400 Subject: [PATCH 07/86] Work in progress. Lots of debug stmts --- .../iq/dataverse/EditDatafilesPage.java | 31 +-- .../harvard/iq/dataverse/api/FileUpload.java | 249 ++++++++++++++++++ .../datasetutility/AddReplaceFileHelper.java | 101 +++++++ 3 files changed, 351 insertions(+), 30 deletions(-) create mode 100644 src/main/java/edu/harvard/iq/dataverse/api/FileUpload.java create mode 100644 src/main/java/edu/harvard/iq/dataverse/datasetutility/AddReplaceFileHelper.java diff --git a/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java b/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java index 9e41cddd102..f45032282bc 100644 --- a/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/EditDatafilesPage.java @@ -6,35 +6,16 @@ import edu.harvard.iq.dataverse.authorization.AuthenticationServiceBean; import edu.harvard.iq.dataverse.authorization.Permission; -import edu.harvard.iq.dataverse.authorization.providers.builtin.BuiltinUserServiceBean; -import edu.harvard.iq.dataverse.authorization.users.ApiToken; -import edu.harvard.iq.dataverse.authorization.users.User; import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser; import edu.harvard.iq.dataverse.datasetutility.DuplicateFileChecker; -import edu.harvard.iq.dataverse.datavariable.VariableServiceBean; import edu.harvard.iq.dataverse.engine.command.Command; import edu.harvard.iq.dataverse.engine.command.exception.CommandException; -import edu.harvard.iq.dataverse.engine.command.impl.CreateDatasetCommand; -import edu.harvard.iq.dataverse.engine.command.impl.CreateGuestbookResponseCommand; -import edu.harvard.iq.dataverse.engine.command.impl.DeaccessionDatasetVersionCommand; import edu.harvard.iq.dataverse.engine.command.impl.DeleteDataFileCommand; -import edu.harvard.iq.dataverse.engine.command.impl.DeleteDatasetVersionCommand; -import edu.harvard.iq.dataverse.engine.command.impl.DestroyDatasetCommand; -import edu.harvard.iq.dataverse.engine.command.impl.LinkDatasetCommand; -import edu.harvard.iq.dataverse.engine.command.impl.PublishDatasetCommand; -import edu.harvard.iq.dataverse.engine.command.impl.PublishDataverseCommand; import edu.harvard.iq.dataverse.engine.command.impl.UpdateDatasetCommand; 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; -import edu.harvard.iq.dataverse.util.FileSortFieldAndOrder; import edu.harvard.iq.dataverse.util.JsfHelper; import static edu.harvard.iq.dataverse.util.JsfHelper.JH; import edu.harvard.iq.dataverse.util.StringUtil; @@ -45,24 +26,20 @@ 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; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.logging.Logger; import javax.ejb.EJB; import javax.ejb.EJBException; import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext; import javax.faces.event.ActionEvent; -import javax.faces.event.ValueChangeEvent; import javax.faces.view.ViewScoped; import javax.inject.Inject; import javax.inject.Named; @@ -72,16 +49,10 @@ 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 javax.faces.model.SelectItem; import java.util.logging.Level; import javax.faces.event.AjaxBehaviorEvent; @@ -1201,9 +1172,9 @@ public void handleDropBoxUpload(ActionEvent event) { public void handleFileUpload(FileUploadEvent event) { UploadedFile uFile = event.getFile(); + List dFileList = null; - try { // Note: A single file may be unzipped into multiple files dFileList = ingestService.createDataFiles(workingVersion, uFile.getInputstream(), uFile.getFileName(), uFile.getContentType()); diff --git a/src/main/java/edu/harvard/iq/dataverse/api/FileUpload.java b/src/main/java/edu/harvard/iq/dataverse/api/FileUpload.java new file mode 100644 index 00000000000..712b7c52ecc --- /dev/null +++ b/src/main/java/edu/harvard/iq/dataverse/api/FileUpload.java @@ -0,0 +1,249 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package edu.harvard.iq.dataverse.api; + +//import com.sun.jersey.core.header.FormDataContentDisposition; +//import com.sun.jersey.multipart.FormDataParam; +import edu.harvard.iq.dataverse.DataFile; +import edu.harvard.iq.dataverse.Dataset; +import edu.harvard.iq.dataverse.DatasetServiceBean; +import edu.harvard.iq.dataverse.DatasetVersion; +import edu.harvard.iq.dataverse.DatasetVersionServiceBean; +import edu.harvard.iq.dataverse.DataverseServiceBean; +import edu.harvard.iq.dataverse.FileMetadata; +import edu.harvard.iq.dataverse.Template; +import edu.harvard.iq.dataverse.ingest.IngestServiceBean; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.ejb.EJB; +import javax.ejb.Stateless; +import javax.ws.rs.Consumes; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +/** + * + * @author rmp553 + */ +@Stateless +@Path("upload") +public class FileUpload extends AbstractApiBean { + + @EJB + DatasetServiceBean datasetService; + @EJB + DatasetVersionServiceBean datasetVersionService; + @EJB + DataverseServiceBean dataverseService; + @EJB + IngestServiceBean ingestService; + + private static final Logger logger = Logger.getLogger(FileUpload.class.getName()); + + // for testing + private static final String SERVER_UPLOAD_LOCATION_FOLDER = "/Users/rmp553/Documents/iqss-git/dataverse-helper-scripts/src/api_scripts/output/"; + + /* + @POST + @Path("hello") //Your Path or URL to call this service + @Consumes(MediaType.MULTIPART_FORM_DATA) + public Response uploadFile( + @DefaultValue("true") @FormDataParam("enabled") boolean enabled, + @FormDataParam("file") InputStream uploadedInputStream, + @FormDataParam("file") FormDataContentDisposition fileDetail) { + //Your local disk path where you want to store the file + String uploadedFileLocation = SERVER_UPLOAD_LOCATION_FOLDER + fileDetail.getFileName(); + System.out.println(uploadedFileLocation); + // save it + File objFile=new File(uploadedFileLocation); + if(objFile.exists()) + { + objFile.delete(); + + } + + saveToFile(uploadedInputStream, uploadedFileLocation); + + String userMsg = "File uploaded via Jersey based RESTFul Webservice to: " + uploadedFileLocation; + + return okResponse(userMsg); + } + + private void saveToFile(InputStream uploadedInputStream, + String uploadedFileLocation) { + + try { + OutputStream out = null; + int read = 0; + byte[] bytes = new byte[1024]; + + out = new FileOutputStream(new File(uploadedFileLocation)); + while ((read = uploadedInputStream.read(bytes)) != -1) { + out.write(bytes, 0, read); + } + out.flush(); + out.close(); + } catch (IOException e) { + + e.printStackTrace(); + } + } + */ + /* + @POST + @Path("hello") + @Consumes(MediaType.MULTIPART_FORM_DATA) + public Response uploadFile( + @FormDataParam("file") InputStream fileInputStream, + @FormDataParam("file") FormDataContentDisposition contentDispositionHeader) { + + String filePath = SERVER_UPLOAD_LOCATION_FOLDER + contentDispositionHeader.getFileName(); + + // save the file to the server + saveFile(fileInputStream, filePath); + + String output = "File saved to server location : " + filePath; + + return okResponse(output); + //return Response.status(200).entity(output).build(); + + } + + // save uploaded file to a defined location on the server + private void saveFile(InputStream uploadedInputStream, + String serverLocation) { + + try { + OutputStream outpuStream = new FileOutputStream(new File(serverLocation)); + int read = 0; + byte[] bytes = new byte[1024]; + + outpuStream = new FileOutputStream(new File(serverLocation)); + while ((read = uploadedInputStream.read(bytes)) != -1) { + outpuStream.write(bytes, 0, read); + } + outpuStream.flush(); + outpuStream.close(); + } catch (IOException e) { + + e.printStackTrace(); + } + + } + */ + + private InputStream getSampleFile(){ + + InputStream is = null; + String testFileName = "/Users/rmp553/Documents/iqss-git/dataverse-helper-scripts/src/api_scripts/input/howdy.txt"; + //testFileName = "/Users/rmp553/NetBeansProjects/dataverse/src/main/java/edu/harvard/iq/dataverse/datasetutility/howdy.txt"; + try { + is = new FileInputStream(testFileName); + //is.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + return null; + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + + return is; + + } + + private void msg(String m){ + System.out.println(m); + } + private void dashes(){ + msg("----------------"); + } + + @GET + @Path("hi") + public Response hi(){ + + InputStream testFile = getSampleFile(); + if (testFile == null){ + return okResponse("Couldn't find the file!!"); + } + DatasetVersion workingVersion = datasetVersionService.find(new Long(3)); + Dataset dataset = workingVersion.getDataset(); //datasetService.find(new Long(26)); + + int cnt = 0; + for (FileMetadata fm : workingVersion.getFileMetadatas()){ + cnt++; + msg("File " + cnt + ": " + fm.getLabel()); + } + dashes(); + //DatasetVersion workingVersion = null; + + /* + ------------------------------------------ + ------------------------------------------ + Set up the workingVersion for editing + - copied from DatasetPage* + * undisputed king of tech debt... + ------------------------------------------ + */ + List