package edu.harvard.iq.dataverse.engine.command.impl; import edu.harvard.iq.dataverse.DataFile; import edu.harvard.iq.dataverse.Dataset; import edu.harvard.iq.dataverse.Dataverse; import edu.harvard.iq.dataverse.authorization.DataverseRole; import edu.harvard.iq.dataverse.search.IndexServiceBean; import edu.harvard.iq.dataverse.RoleAssignment; import edu.harvard.iq.dataverse.authorization.Permission; import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser; import edu.harvard.iq.dataverse.engine.command.AbstractVoidCommand; import edu.harvard.iq.dataverse.engine.command.CommandContext; import edu.harvard.iq.dataverse.engine.command.DataverseRequest; import edu.harvard.iq.dataverse.engine.command.RequiredPermissions; import edu.harvard.iq.dataverse.engine.command.exception.CommandException; import edu.harvard.iq.dataverse.engine.command.exception.PermissionException; import edu.harvard.iq.dataverse.search.IndexResponse; import edu.harvard.iq.dataverse.settings.SettingsServiceBean; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; /** * Same as {@link DeleteDatasetCommand}, but does not stop if the dataset is * published. This command is reserved for super-users, if at all. * * @author michael */ // Since this is used by DeleteDatasetCommand, must have at least that permission // (for released, user is checked for superuser) @RequiredPermissions( Permission.DeleteDatasetDraft ) public class DestroyDatasetCommand extends AbstractVoidCommand { private static final Logger logger = Logger.getLogger(DestroyDatasetCommand.class.getCanonicalName()); private final Dataset doomed; public DestroyDatasetCommand(Dataset doomed, DataverseRequest aRequest) { super(aRequest, doomed); this.doomed = doomed; } @Override protected void executeImpl(CommandContext ctxt) throws CommandException { // first check if dataset is released, and if so, if user is a superuser if ( doomed.isReleased() && (!(getUser() instanceof AuthenticatedUser) || !getUser().isSuperuser() ) ) { throw new PermissionException("Destroy can only be called by superusers.", this, Collections.singleton(Permission.DeleteDatasetDraft), doomed); } final Dataset managedDoomed = ctxt.em().merge(doomed); List<String> datasetAndFileSolrIdsToDelete = new ArrayList<>(); // files need to iterate through and remove 'by hand' to avoid // optimistic lock issues.... Iterator <DataFile> dfIt = doomed.getFiles().iterator(); while (dfIt.hasNext()){ DataFile df = dfIt.next(); // Gather potential Solr IDs of files. As of this writing deaccessioned files are never indexed. String solrIdOfPublishedFile = IndexServiceBean.solrDocIdentifierFile + df.getId(); datasetAndFileSolrIdsToDelete.add(solrIdOfPublishedFile); String solrIdOfDraftFile = IndexServiceBean.solrDocIdentifierFile + df.getId() + IndexServiceBean.draftSuffix; datasetAndFileSolrIdsToDelete.add(solrIdOfDraftFile); ctxt.engine().submit(new DeleteDataFileCommand(df, getRequest(), true)); dfIt.remove(); } // ASSIGNMENTS for (RoleAssignment ra : ctxt.roles().directRoleAssignments(doomed)) { ctxt.em().remove(ra); } // ROLES for (DataverseRole ra : ctxt.roles().findByOwnerId(doomed.getId())) { ctxt.em().remove(ra); } //Register Cache if(ctxt.settings().getValueForKey(SettingsServiceBean.Key.DoiProvider, "").equals("DataCite")){ ctxt.doiDataCite().deleteRecordFromCache(doomed); } Dataverse toReIndex = managedDoomed.getOwner(); // dataset ctxt.em().remove(managedDoomed); // add potential Solr IDs of datasets to list for deletion String solrIdOfPublishedDatasetVersion = IndexServiceBean.solrDocIdentifierDataset + doomed.getId(); datasetAndFileSolrIdsToDelete.add(solrIdOfPublishedDatasetVersion); String solrIdOfDraftDatasetVersion = IndexServiceBean.solrDocIdentifierDataset + doomed.getId() + IndexServiceBean.draftSuffix; datasetAndFileSolrIdsToDelete.add(solrIdOfDraftDatasetVersion); String solrIdOfDeaccessionedDatasetVersion = IndexServiceBean.solrDocIdentifierDataset + doomed.getId() + IndexServiceBean.deaccessionedSuffix; datasetAndFileSolrIdsToDelete.add(solrIdOfDeaccessionedDatasetVersion); IndexResponse resultOfSolrDeletionAttempt = ctxt.solrIndex().deleteMultipleSolrIds(datasetAndFileSolrIdsToDelete); logger.log(Level.FINE, "Result of attempt to delete dataset and file IDs from the search index: {0}", resultOfSolrDeletionAttempt.getMessage()); ctxt.index().indexDataverse(toReIndex); } }