Search in sources :

Example 11 with CommandException

use of edu.harvard.iq.dataverse.engine.command.exception.CommandException in project dataverse by IQSS.

the class MediaResourceManagerImpl method replaceOrAddFiles.

DepositReceipt replaceOrAddFiles(String uri, Deposit deposit, AuthCredentials authCredentials, SwordConfiguration swordConfiguration, boolean shouldReplace) throws SwordError, SwordAuthException, SwordServerException {
    AuthenticatedUser user = swordAuth.auth(authCredentials);
    DataverseRequest dvReq = new DataverseRequest(user, httpRequest);
    urlManager.processUrl(uri);
    String globalId = urlManager.getTargetIdentifier();
    if (urlManager.getTargetType().equals("study") && globalId != null) {
        logger.fine("looking up dataset with globalId " + globalId);
        Dataset dataset = datasetService.findByGlobalId(globalId);
        if (dataset == null) {
            throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Could not find dataset with global ID of " + globalId);
        }
        UpdateDatasetCommand updateDatasetCommand = new UpdateDatasetCommand(dataset, dvReq);
        if (!permissionService.isUserAllowedOn(user, updateDatasetCommand, dataset)) {
            throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "user " + user.getDisplayInfo().getTitle() + " is not authorized to modify dataset with global ID " + dataset.getGlobalId());
        }
        // -------------------------------------
        if (DataCaptureModuleUtil.rsyncSupportEnabled(settingsSvc.getValueForKey(SettingsServiceBean.Key.UploadMethods))) {
            throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, SettingsServiceBean.Key.UploadMethods + " contains " + SystemConfig.FileUploadMethods.RSYNC + ". Please use rsync file upload.");
        }
        /**
         * @todo decide if we want non zip files to work. Technically, now
         * that we're letting ingestService.createDataFiles unpack the zip
         * for us, the following *does* work:
         *
         * curl--data-binary @path/to/trees.png -H "Content-Disposition:
         * filename=trees.png" -H "Content-Type: image/png" -H "Packaging:
         * http://purl.org/net/sword/package/SimpleZip"
         *
         * We *might* want to continue to force API users to only upload zip
         * files so that some day we can support a including a file or files
         * that contain the metadata (i.e. description) for each file in the
         * zip: https://github.com/IQSS/dataverse/issues/723
         */
        if (!deposit.getPackaging().equals(UriRegistry.PACKAGE_SIMPLE_ZIP)) {
            throw new SwordError(UriRegistry.ERROR_CONTENT, 415, "Package format " + UriRegistry.PACKAGE_SIMPLE_ZIP + " is required but format specified in 'Packaging' HTTP header was " + deposit.getPackaging());
        }
        String uploadedZipFilename = deposit.getFilename();
        DatasetVersion editVersion = dataset.getEditVersion();
        if (deposit.getInputStream() == null) {
            throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Deposit input stream was null.");
        }
        int bytesAvailableInInputStream = 0;
        try {
            bytesAvailableInInputStream = deposit.getInputStream().available();
        } catch (IOException ex) {
            throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Could not determine number of bytes available in input stream: " + ex);
        }
        if (bytesAvailableInInputStream == 0) {
            throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Bytes available in input stream was " + bytesAvailableInInputStream + ". Please check the file you are attempting to deposit.");
        }
        /**
         * @todo Think about if we should instead pass in "application/zip"
         * rather than letting ingestService.createDataFiles() guess the
         * contentType by passing it "null". See also the note above about
         * SimpleZip vs. other contentTypes.
         */
        String guessContentTypeForMe = null;
        List<DataFile> dataFiles = new ArrayList<>();
        try {
            try {
                dataFiles = FileUtil.createDataFiles(editVersion, deposit.getInputStream(), uploadedZipFilename, guessContentTypeForMe, systemConfig);
            } catch (EJBException ex) {
                Throwable cause = ex.getCause();
                if (cause != null) {
                    if (cause instanceof IllegalArgumentException) {
                        /**
                         * @todo should be safe to remove this catch of
                         * EJBException and IllegalArgumentException once
                         * this ticket is resolved:
                         *
                         * IllegalArgumentException: MALFORMED when
                         * uploading certain zip files
                         * https://github.com/IQSS/dataverse/issues/1021
                         */
                        throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Exception caught calling ingestService.createDataFiles. Problem with zip file, perhaps: " + cause);
                    } else {
                        throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Exception caught calling ingestService.createDataFiles: " + cause);
                    }
                } else {
                    throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Exception caught calling ingestService.createDataFiles. No cause: " + ex.getMessage());
                }
            }
        /*TODO: L.A. 4.6! catch (FileExceedsMaxSizeException ex) {
                    throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Exception caught calling ingestService.createDataFiles: " + ex.getMessage());
                    //Logger.getLogger(MediaResourceManagerImpl.class.getName()).log(Level.SEVERE, null, ex);
                }*/
        } catch (IOException ex) {
            throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Unable to add file(s) to dataset: " + ex.getMessage());
        }
        if (!dataFiles.isEmpty()) {
            Set<ConstraintViolation> constraintViolations = editVersion.validate();
            if (constraintViolations.size() > 0) {
                ConstraintViolation violation = constraintViolations.iterator().next();
                throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Unable to add file(s) to dataset: " + violation.getMessage() + " The invalid value was \"" + violation.getInvalidValue() + "\".");
            } else {
                ingestService.addFiles(editVersion, dataFiles);
            }
        } else {
            throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "No files to add to dataset. Perhaps the zip file was empty.");
        }
        try {
            dataset = commandEngine.submit(updateDatasetCommand);
        } catch (CommandException ex) {
            throw returnEarly("Couldn't update dataset " + ex);
        } catch (EJBException ex) {
            /**
             * @todo stop bothering to catch an EJBException once this has
             * been implemented:
             *
             * Have commands catch ConstraintViolationException and turn
             * them into something that inherits from CommandException ·
             * https://github.com/IQSS/dataverse/issues/1009
             */
            Throwable cause = ex;
            StringBuilder sb = new StringBuilder();
            sb.append(ex.getLocalizedMessage());
            while (cause.getCause() != null) {
                cause = cause.getCause();
                sb.append(cause + " ");
                if (cause instanceof ConstraintViolationException) {
                    ConstraintViolationException constraintViolationException = (ConstraintViolationException) cause;
                    for (ConstraintViolation<?> violation : constraintViolationException.getConstraintViolations()) {
                        sb.append(" Invalid value \"").append(violation.getInvalidValue()).append("\" for ").append(violation.getPropertyPath()).append(" at ").append(violation.getLeafBean()).append(" - ").append(violation.getMessage());
                    }
                }
            }
            throw returnEarly("EJBException: " + sb.toString());
        }
        ingestService.startIngestJobs(dataset, user);
        ReceiptGenerator receiptGenerator = new ReceiptGenerator();
        String baseUrl = urlManager.getHostnamePlusBaseUrlPath(uri);
        DepositReceipt depositReceipt = receiptGenerator.createDatasetReceipt(baseUrl, dataset);
        return depositReceipt;
    } else {
        throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Unable to determine target type or identifier from URL: " + uri);
    }
}
Also used : SwordError(org.swordapp.server.SwordError) Dataset(edu.harvard.iq.dataverse.Dataset) ArrayList(java.util.ArrayList) DatasetVersion(edu.harvard.iq.dataverse.DatasetVersion) IOException(java.io.IOException) CommandException(edu.harvard.iq.dataverse.engine.command.exception.CommandException) AuthenticatedUser(edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser) DataverseRequest(edu.harvard.iq.dataverse.engine.command.DataverseRequest) DataFile(edu.harvard.iq.dataverse.DataFile) DepositReceipt(org.swordapp.server.DepositReceipt) ConstraintViolation(javax.validation.ConstraintViolation) ConstraintViolationException(javax.validation.ConstraintViolationException) EJBException(javax.ejb.EJBException) UpdateDatasetCommand(edu.harvard.iq.dataverse.engine.command.impl.UpdateDatasetCommand)

Example 12 with CommandException

use of edu.harvard.iq.dataverse.engine.command.exception.CommandException in project dataverse by IQSS.

the class MediaResourceManagerImpl method deleteMediaResource.

@Override
public void deleteMediaResource(String uri, AuthCredentials authCredentials, SwordConfiguration swordConfiguration) throws SwordError, SwordServerException, SwordAuthException {
    AuthenticatedUser user = swordAuth.auth(authCredentials);
    DataverseRequest dvReq = new DataverseRequest(user, httpRequest);
    urlManager.processUrl(uri);
    String targetType = urlManager.getTargetType();
    String fileId = urlManager.getTargetIdentifier();
    if (targetType != null && fileId != null) {
        if ("file".equals(targetType)) {
            String fileIdString = urlManager.getTargetIdentifier();
            if (fileIdString != null) {
                Long fileIdLong;
                try {
                    fileIdLong = Long.valueOf(fileIdString);
                } catch (NumberFormatException ex) {
                    throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "File id must be a number, not '" + fileIdString + "'. URL was: " + uri);
                }
                if (fileIdLong != null) {
                    logger.fine("preparing to delete file id " + fileIdLong);
                    DataFile fileToDelete = dataFileService.find(fileIdLong);
                    if (fileToDelete != null) {
                        Dataset dataset = fileToDelete.getOwner();
                        Dataset datasetThatOwnsFile = fileToDelete.getOwner();
                        Dataverse dataverseThatOwnsFile = datasetThatOwnsFile.getOwner();
                        /**
                         * @todo it would be nice to have this check higher
                         * up. Do we really need the file ID? Should the
                         * last argument to isUserAllowedOn be changed from
                         * "dataset" to "fileToDelete"?
                         */
                        UpdateDatasetCommand updateDatasetCommand = new UpdateDatasetCommand(dataset, dvReq, fileToDelete);
                        if (!permissionService.isUserAllowedOn(user, updateDatasetCommand, dataset)) {
                            throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "User " + user.getDisplayInfo().getTitle() + " is not authorized to modify " + dataverseThatOwnsFile.getAlias());
                        }
                        try {
                            commandEngine.submit(updateDatasetCommand);
                        } catch (CommandException ex) {
                            throw SwordUtil.throwSpecialSwordErrorWithoutStackTrace(UriRegistry.ERROR_BAD_REQUEST, "Could not delete file: " + ex);
                        }
                    } else {
                        throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Unable to find file id " + fileIdLong + " from URL: " + uri);
                    }
                } else {
                    throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Unable to find file id in URL: " + uri);
                }
            } else {
                throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Could not file file to delete in URL: " + uri);
            }
        } else {
            throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Unsupported file type found in URL: " + uri);
        }
    } else {
        throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Target or identifer not specified in URL: " + uri);
    }
}
Also used : DataverseRequest(edu.harvard.iq.dataverse.engine.command.DataverseRequest) DataFile(edu.harvard.iq.dataverse.DataFile) SwordError(org.swordapp.server.SwordError) Dataset(edu.harvard.iq.dataverse.Dataset) CommandException(edu.harvard.iq.dataverse.engine.command.exception.CommandException) AuthenticatedUser(edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser) Dataverse(edu.harvard.iq.dataverse.Dataverse) UpdateDatasetCommand(edu.harvard.iq.dataverse.engine.command.impl.UpdateDatasetCommand)

Example 13 with CommandException

use of edu.harvard.iq.dataverse.engine.command.exception.CommandException in project dataverse by IQSS.

the class CollectionDepositManagerImpl method createNew.

@Override
public DepositReceipt createNew(String collectionUri, Deposit deposit, AuthCredentials authCredentials, SwordConfiguration config) throws SwordError, SwordServerException, SwordAuthException {
    AuthenticatedUser user = swordAuth.auth(authCredentials);
    DataverseRequest dvReq = new DataverseRequest(user, request);
    urlManager.processUrl(collectionUri);
    String dvAlias = urlManager.getTargetIdentifier();
    if (urlManager.getTargetType().equals("dataverse") && dvAlias != null) {
        logger.log(Level.FINE, "attempting deposit into this dataverse alias: {0}", dvAlias);
        Dataverse dvThatWillOwnDataset = dataverseService.findByAlias(dvAlias);
        if (dvThatWillOwnDataset != null) {
            logger.log(Level.FINE, "multipart: {0}", deposit.isMultipart());
            logger.log(Level.FINE, "binary only: {0}", deposit.isBinaryOnly());
            logger.log(Level.FINE, "entry only: {0}", deposit.isEntryOnly());
            logger.log(Level.FINE, "in progress: {0}", deposit.isInProgress());
            logger.log(Level.FINE, "metadata relevant: {0}", deposit.isMetadataRelevant());
            if (deposit.isEntryOnly()) {
                // do a sanity check on the XML received
                try {
                    SwordEntry swordEntry = deposit.getSwordEntry();
                    logger.log(Level.FINE, "deposit XML received by createNew():\n{0}", swordEntry.toString());
                } catch (ParseException ex) {
                    throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Can not create dataset due to malformed Atom entry: " + ex);
                }
                Dataset dataset = new Dataset();
                dataset.setOwner(dvThatWillOwnDataset);
                String nonNullDefaultIfKeyNotFound = "";
                String protocol = settingsService.getValueForKey(SettingsServiceBean.Key.Protocol, nonNullDefaultIfKeyNotFound);
                String authority = settingsService.getValueForKey(SettingsServiceBean.Key.Authority, nonNullDefaultIfKeyNotFound);
                String separator = settingsService.getValueForKey(SettingsServiceBean.Key.DoiSeparator, nonNullDefaultIfKeyNotFound);
                dataset.setProtocol(protocol);
                dataset.setAuthority(authority);
                dataset.setDoiSeparator(separator);
                // Wait until the create command before actually getting an identifier
                // dataset.setIdentifier(datasetService.generateDatasetIdentifier(protocol, authority, separator));
                logger.log(Level.FINE, "DS Deposit identifier: {0}", dataset.getIdentifier());
                CreateDatasetCommand createDatasetCommand = new CreateDatasetCommand(dataset, dvReq, false);
                if (!permissionService.isUserAllowedOn(user, createDatasetCommand, dataset)) {
                    throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "user " + user.getDisplayInfo().getTitle() + " is not authorized to create a dataset in this dataverse.");
                }
                DatasetVersion newDatasetVersion = dataset.getEditVersion();
                String foreignFormat = SwordUtil.DCTERMS;
                try {
                    importGenericService.importXML(deposit.getSwordEntry().toString(), foreignFormat, newDatasetVersion);
                } catch (Exception ex) {
                    throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "problem calling importXML: " + ex);
                }
                swordService.addDatasetContact(newDatasetVersion, user);
                swordService.addDatasetDepositor(newDatasetVersion, user);
                swordService.addDatasetSubjectIfMissing(newDatasetVersion);
                swordService.setDatasetLicenseAndTermsOfUse(newDatasetVersion, deposit.getSwordEntry());
                Dataset createdDataset = null;
                try {
                    createdDataset = engineSvc.submit(createDatasetCommand);
                } catch (EJBException | CommandException ex) {
                    Throwable cause = ex;
                    StringBuilder sb = new StringBuilder();
                    sb.append(ex.getLocalizedMessage());
                    while (cause.getCause() != null) {
                        cause = cause.getCause();
                        /**
                         * @todo move this ConstraintViolationException
                         * check to CreateDatasetCommand. Can be triggered
                         * if you don't call dataset.setIdentifier() or if
                         * you feed it date format we don't like. Once this
                         * is done we should be able to drop EJBException
                         * from the catch above and only catch
                         * CommandException
                         *
                         * See also Have commands catch
                         * ConstraintViolationException and turn them into
                         * something that inherits from CommandException ·
                         * Issue #1009 · IQSS/dataverse -
                         * https://github.com/IQSS/dataverse/issues/1009
                         */
                        if (cause instanceof ConstraintViolationException) {
                            ConstraintViolationException constraintViolationException = (ConstraintViolationException) cause;
                            for (ConstraintViolation<?> violation : constraintViolationException.getConstraintViolations()) {
                                sb.append(" Invalid value: '").append(violation.getInvalidValue()).append("' for ").append(violation.getPropertyPath()).append(" at ").append(violation.getLeafBean()).append(" - ").append(violation.getMessage());
                            }
                        }
                    }
                    logger.info(sb.toString());
                    throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Couldn't create dataset: " + sb.toString());
                }
                if (createdDataset != null) {
                    ReceiptGenerator receiptGenerator = new ReceiptGenerator();
                    String baseUrl = urlManager.getHostnamePlusBaseUrlPath(collectionUri);
                    DepositReceipt depositReceipt = receiptGenerator.createDatasetReceipt(baseUrl, createdDataset);
                    return depositReceipt;
                } else {
                    throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Problem creating dataset. Null returned.");
                }
            } else if (deposit.isBinaryOnly()) {
                // curl --insecure -s --data-binary "@example.zip" -H "Content-Disposition: filename=example.zip" -H "Content-Type: application/zip" https://sword:sword@localhost:8181/dvn/api/data-deposit/v1/swordv2/collection/dataverse/sword/
                throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Binary deposit to the collection IRI via POST is not supported. Please POST an Atom entry instead.");
            } else if (deposit.isMultipart()) {
                // "Yeah, multipart is critically broken across all implementations" -- http://www.mail-archive.com/sword-app-tech@lists.sourceforge.net/msg00327.html
                throw new UnsupportedOperationException("Not yet implemented");
            } else {
                throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "expected deposit types are isEntryOnly, isBinaryOnly, and isMultiPart");
            }
        } else {
            throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Could not find dataverse: " + dvAlias);
        }
    } else {
        throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Could not determine target type or identifier from URL: " + collectionUri);
    }
}
Also used : SwordError(org.swordapp.server.SwordError) Dataset(edu.harvard.iq.dataverse.Dataset) CreateDatasetCommand(edu.harvard.iq.dataverse.engine.command.impl.CreateDatasetCommand) DatasetVersion(edu.harvard.iq.dataverse.DatasetVersion) CommandException(edu.harvard.iq.dataverse.engine.command.exception.CommandException) AuthenticatedUser(edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser) Dataverse(edu.harvard.iq.dataverse.Dataverse) SwordAuthException(org.swordapp.server.SwordAuthException) SwordServerException(org.swordapp.server.SwordServerException) CommandException(edu.harvard.iq.dataverse.engine.command.exception.CommandException) EJBException(javax.ejb.EJBException) ConstraintViolationException(javax.validation.ConstraintViolationException) ParseException(org.apache.abdera.parser.ParseException) DataverseRequest(edu.harvard.iq.dataverse.engine.command.DataverseRequest) DepositReceipt(org.swordapp.server.DepositReceipt) ConstraintViolation(javax.validation.ConstraintViolation) SwordEntry(org.swordapp.server.SwordEntry) ConstraintViolationException(javax.validation.ConstraintViolationException) ParseException(org.apache.abdera.parser.ParseException) EJBException(javax.ejb.EJBException)

Example 14 with CommandException

use of edu.harvard.iq.dataverse.engine.command.exception.CommandException in project dataverse by IQSS.

the class ImportServiceBean method doImport.

public JsonObjectBuilder doImport(DataverseRequest dataverseRequest, Dataverse owner, String xmlToParse, String fileName, ImportType importType, PrintWriter cleanupLog) throws ImportException, IOException {
    String status = "";
    Long createdId = null;
    DatasetDTO dsDTO = null;
    try {
        dsDTO = importDDIService.doImport(importType, xmlToParse);
    } catch (XMLStreamException e) {
        throw new ImportException("XMLStreamException" + e);
    }
    // convert DTO to Json,
    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    String json = gson.toJson(dsDTO);
    JsonReader jsonReader = Json.createReader(new StringReader(json));
    JsonObject obj = jsonReader.readObject();
    // and call parse Json to read it into a dataset
    try {
        JsonParser parser = new JsonParser(datasetfieldService, metadataBlockService, settingsService);
        parser.setLenient(!importType.equals(ImportType.NEW));
        Dataset ds = parser.parseDataset(obj);
        // we support, it will be rejected.
        if (importType.equals(ImportType.NEW)) {
            if (ds.getGlobalId() != null && !ds.getProtocol().equals(settingsService.getValueForKey(SettingsServiceBean.Key.Protocol, ""))) {
                throw new ImportException("Could not register id " + ds.getGlobalId() + ", protocol not supported");
            }
        }
        ds.setOwner(owner);
        ds.getLatestVersion().setDatasetFields(ds.getLatestVersion().initDatasetFields());
        // Check data against required contraints
        List<ConstraintViolation<DatasetField>> violations = ds.getVersions().get(0).validateRequired();
        if (!violations.isEmpty()) {
            if (importType.equals(ImportType.MIGRATION) || importType.equals(ImportType.HARVEST)) {
                // For migration and harvest, add NA for missing required values
                for (ConstraintViolation<DatasetField> v : violations) {
                    DatasetField f = v.getRootBean();
                    f.setSingleValue(DatasetField.NA_VALUE);
                }
            } else {
                // when importing a new dataset, the import will fail
                // if required values are missing.
                String errMsg = "Error importing data:";
                for (ConstraintViolation<DatasetField> v : violations) {
                    errMsg += " " + v.getMessage();
                }
                throw new ImportException(errMsg);
            }
        }
        // Check data against validation constraints
        // If we are migrating and "scrub migration data" is true we attempt to fix invalid data
        // if the fix fails stop processing of this file by throwing exception
        Set<ConstraintViolation> invalidViolations = ds.getVersions().get(0).validate();
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();
        if (!invalidViolations.isEmpty()) {
            for (ConstraintViolation<DatasetFieldValue> v : invalidViolations) {
                DatasetFieldValue f = v.getRootBean();
                boolean fixed = false;
                boolean converted = false;
                if ((importType.equals(ImportType.MIGRATION) || importType.equals(ImportType.HARVEST)) && settingsService.isTrueForKey(SettingsServiceBean.Key.ScrubMigrationData, false)) {
                    fixed = processMigrationValidationError(f, cleanupLog, fileName);
                    converted = true;
                    if (fixed) {
                        Set<ConstraintViolation<DatasetFieldValue>> scrubbedViolations = validator.validate(f);
                        if (!scrubbedViolations.isEmpty()) {
                            fixed = false;
                        }
                    }
                }
                if (!fixed) {
                    if (importType.equals(ImportType.HARVEST)) {
                        String msg = "Data modified - File: " + fileName + "; Field: " + f.getDatasetField().getDatasetFieldType().getDisplayName() + "; " + "Invalid value:  '" + f.getValue() + "'" + " Converted Value:'" + DatasetField.NA_VALUE + "'";
                        cleanupLog.println(msg);
                        f.setValue(DatasetField.NA_VALUE);
                    } else {
                        String msg = " Validation error for ";
                        if (converted) {
                            msg += "converted ";
                        }
                        msg += "value: " + f.getValue() + ", " + f.getValidationMessage();
                        throw new ImportException(msg);
                    }
                }
            }
        }
        Dataset existingDs = datasetService.findByGlobalId(ds.getGlobalId());
        if (existingDs != null) {
            if (importType.equals(ImportType.HARVEST)) {
                // We will replace the current version with the imported version.
                if (existingDs.getVersions().size() != 1) {
                    throw new ImportException("Error importing Harvested Dataset, existing dataset has " + existingDs.getVersions().size() + " versions");
                }
                engineSvc.submit(new DestroyDatasetCommand(existingDs, dataverseRequest));
                Dataset managedDs = engineSvc.submit(new CreateDatasetCommand(ds, dataverseRequest, false, importType));
                status = " updated dataset, id=" + managedDs.getId() + ".";
            } else {
                // check that the version number isn't already in the dataset
                for (DatasetVersion dsv : existingDs.getVersions()) {
                    if (dsv.getVersionNumber().equals(ds.getLatestVersion().getVersionNumber())) {
                        throw new ImportException("VersionNumber " + ds.getLatestVersion().getVersionNumber() + " already exists in dataset " + existingDs.getGlobalId());
                    }
                }
                DatasetVersion dsv = engineSvc.submit(new CreateDatasetVersionCommand(dataverseRequest, existingDs, ds.getVersions().get(0)));
                status = " created datasetVersion, for dataset " + dsv.getDataset().getGlobalId();
                createdId = dsv.getId();
            }
        } else {
            Dataset managedDs = engineSvc.submit(new CreateDatasetCommand(ds, dataverseRequest, false, importType));
            status = " created dataset, id=" + managedDs.getId() + ".";
            createdId = managedDs.getId();
        }
    } catch (JsonParseException ex) {
        logger.log(Level.INFO, "Error parsing datasetVersion: {0}", ex.getMessage());
        throw new ImportException("Error parsing datasetVersion: " + ex.getMessage(), ex);
    } catch (CommandException ex) {
        logger.log(Level.INFO, "Error excuting Create dataset command: {0}", ex.getMessage());
        throw new ImportException("Error excuting dataverse command: " + ex.getMessage(), ex);
    }
    return Json.createObjectBuilder().add("message", status);
}
Also used : DatasetField(edu.harvard.iq.dataverse.DatasetField) CreateDatasetCommand(edu.harvard.iq.dataverse.engine.command.impl.CreateDatasetCommand) Gson(com.google.gson.Gson) JsonObject(javax.json.JsonObject) DatasetVersion(edu.harvard.iq.dataverse.DatasetVersion) JsonParseException(edu.harvard.iq.dataverse.util.json.JsonParseException) DatasetDTO(edu.harvard.iq.dataverse.api.dto.DatasetDTO) DatasetFieldValue(edu.harvard.iq.dataverse.DatasetFieldValue) StringReader(java.io.StringReader) JsonReader(javax.json.JsonReader) JsonParser(edu.harvard.iq.dataverse.util.json.JsonParser) CreateDatasetVersionCommand(edu.harvard.iq.dataverse.engine.command.impl.CreateDatasetVersionCommand) ValidatorFactory(javax.validation.ValidatorFactory) GsonBuilder(com.google.gson.GsonBuilder) Dataset(edu.harvard.iq.dataverse.Dataset) CommandException(edu.harvard.iq.dataverse.engine.command.exception.CommandException) XMLStreamException(javax.xml.stream.XMLStreamException) ConstraintViolation(javax.validation.ConstraintViolation) Validator(javax.validation.Validator) DestroyDatasetCommand(edu.harvard.iq.dataverse.engine.command.impl.DestroyDatasetCommand)

Example 15 with CommandException

use of edu.harvard.iq.dataverse.engine.command.exception.CommandException in project dataverse by IQSS.

the class ContainerManagerImpl method replaceMetadata.

@Override
public DepositReceipt replaceMetadata(String uri, Deposit deposit, AuthCredentials authCredentials, SwordConfiguration swordConfiguration) throws SwordError, SwordServerException, SwordAuthException {
    AuthenticatedUser user = swordAuth.auth(authCredentials);
    DataverseRequest dvReq = new DataverseRequest(user, httpRequest);
    logger.fine("replaceMetadata called with url: " + uri);
    urlManager.processUrl(uri);
    String targetType = urlManager.getTargetType();
    if (!targetType.isEmpty()) {
        logger.fine("operating on target type: " + urlManager.getTargetType());
        if ("dataverse".equals(targetType)) {
            throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Metadata replace of dataverse is not supported.");
        } else if ("study".equals(targetType)) {
            logger.fine("replacing metadata for dataset");
            // do a sanity check on the XML received
            try {
                SwordEntry swordEntry = deposit.getSwordEntry();
                logger.fine("deposit XML received by replaceMetadata():\n" + swordEntry);
            } catch (ParseException ex) {
                throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Can not replace dataset metadata due to malformed Atom entry: " + ex);
            }
            String globalId = urlManager.getTargetIdentifier();
            Dataset dataset = datasetService.findByGlobalId(globalId);
            if (dataset != null) {
                Dataverse dvThatOwnsDataset = dataset.getOwner();
                UpdateDatasetCommand updateDatasetCommand = new UpdateDatasetCommand(dataset, dvReq);
                if (!permissionService.isUserAllowedOn(user, updateDatasetCommand, dataset)) {
                    throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "User " + user.getDisplayInfo().getTitle() + " is not authorized to modify dataverse " + dvThatOwnsDataset.getAlias());
                }
                DatasetVersion datasetVersion = dataset.getEditVersion();
                // erase all metadata before creating populating dataset version
                List<DatasetField> emptyDatasetFields = new ArrayList<>();
                datasetVersion.setDatasetFields(emptyDatasetFields);
                String foreignFormat = SwordUtil.DCTERMS;
                try {
                    importGenericService.importXML(deposit.getSwordEntry().toString(), foreignFormat, datasetVersion);
                } catch (Exception ex) {
                    throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "problem calling importXML: " + ex);
                }
                swordService.addDatasetContact(datasetVersion, user);
                swordService.addDatasetDepositor(datasetVersion, user);
                swordService.addDatasetSubjectIfMissing(datasetVersion);
                swordService.setDatasetLicenseAndTermsOfUse(datasetVersion, deposit.getSwordEntry());
                try {
                    engineSvc.submit(updateDatasetCommand);
                } catch (CommandException ex) {
                    throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "problem updating dataset: " + ex);
                }
                ReceiptGenerator receiptGenerator = new ReceiptGenerator();
                String baseUrl = urlManager.getHostnamePlusBaseUrlPath(uri);
                DepositReceipt depositReceipt = receiptGenerator.createDatasetReceipt(baseUrl, dataset);
                return depositReceipt;
            } else {
                throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Could not find dataset based on global id (" + globalId + ") in URL: " + uri);
            }
        } else {
            throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "Unknown target type specified on which to replace metadata: " + uri);
        }
    } else {
        throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "No target specified on which to replace metadata: " + uri);
    }
}
Also used : SwordError(org.swordapp.server.SwordError) Dataset(edu.harvard.iq.dataverse.Dataset) DatasetVersion(edu.harvard.iq.dataverse.DatasetVersion) CommandException(edu.harvard.iq.dataverse.engine.command.exception.CommandException) AuthenticatedUser(edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser) Dataverse(edu.harvard.iq.dataverse.Dataverse) SwordAuthException(org.swordapp.server.SwordAuthException) SwordServerException(org.swordapp.server.SwordServerException) CommandException(edu.harvard.iq.dataverse.engine.command.exception.CommandException) EJBException(javax.ejb.EJBException) CommandExecutionException(edu.harvard.iq.dataverse.engine.command.exception.CommandExecutionException) ParseException(org.apache.abdera.parser.ParseException) DataverseRequest(edu.harvard.iq.dataverse.engine.command.DataverseRequest) DepositReceipt(org.swordapp.server.DepositReceipt) SwordEntry(org.swordapp.server.SwordEntry) ArrayList(java.util.ArrayList) List(java.util.List) ParseException(org.apache.abdera.parser.ParseException) UpdateDatasetCommand(edu.harvard.iq.dataverse.engine.command.impl.UpdateDatasetCommand)

Aggregations

CommandException (edu.harvard.iq.dataverse.engine.command.exception.CommandException)86 Dataset (edu.harvard.iq.dataverse.Dataset)21 AuthenticatedUser (edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser)20 IllegalCommandException (edu.harvard.iq.dataverse.engine.command.exception.IllegalCommandException)19 Test (org.junit.Test)16 PermissionException (edu.harvard.iq.dataverse.engine.command.exception.PermissionException)15 EJBException (javax.ejb.EJBException)13 DataverseRequest (edu.harvard.iq.dataverse.engine.command.DataverseRequest)12 DataFile (edu.harvard.iq.dataverse.DataFile)11 Dataverse (edu.harvard.iq.dataverse.Dataverse)9 UpdateDatasetCommand (edu.harvard.iq.dataverse.engine.command.impl.UpdateDatasetCommand)9 ConstraintViolation (javax.validation.ConstraintViolation)9 DatasetThumbnail (edu.harvard.iq.dataverse.dataset.DatasetThumbnail)8 IOException (java.io.IOException)8 Timestamp (java.sql.Timestamp)8 ArrayList (java.util.ArrayList)8 Date (java.util.Date)8 FacesMessage (javax.faces.application.FacesMessage)7 DatasetVersion (edu.harvard.iq.dataverse.DatasetVersion)6 SwordError (org.swordapp.server.SwordError)6