@Override protected void onRun() throws Exception { // TODO: When the rest of storage is rewritten using TransactionRunnable, // this method should be disolved. final Session session = this.context.getWiki().getHibernateStore().getSession(this.context); // Delete the content from the attachment. // In case it was stored in the database by XWikiHibernateAttachmentStore. session.delete(new XWikiAttachmentContent(this.attachment)); // Update the document if required. if (this.updateDocument) { final String filename = this.attachment.getFilename(); final List<XWikiAttachment> list = attachment.getDoc().getAttachmentList(); for (int i = 0; i < list.size(); i++) { if (filename.equals(list.get(i).getFilename())) { list.remove(i); break; } } this.context .getWiki() .getStore() .saveXWikiDoc(this.attachment.getDoc(), this.context, false); } // Delete the attachment metadata. session.delete(this.attachment); }
/** * Make sure the attachment is associated with a document. * * @param attachment the attachment to check. * @throws IllegalArgumentException if attachment.getDoc() yields null. */ private static void checkAttachedToDocument(final XWikiAttachment attachment) { if (attachment.getDoc() == null) { throw new IllegalArgumentException( "In order to use this function, the attachment [" + attachment.getFilename() + "] must be associated with a document."); } }
/** * Construct a TransactionRunnable for saving the attachment content. * * @param attachment the XWikiAttachment whose content should be saved. * @param updateDocument whether or not to update the document at the same time. * @param context the XWikiContext for the request. * @param attachFile the File to store the attachment in. * @param tempFile the File to put the attachment content in until the transaction is complete. * @param backupFile the File to backup the content of the existing attachment in. * @param lock this Lock will be locked while the attachment file is being written to. * @throws XWikiException if thrown by {@link XWikiAttachment#updateContentArchive(XWikiContext)} * or {@link FilesystemAttachmentVersioningStore# * getArchiveSaveRunnable(XWikiAttachmentArchive, XWikiContext) */ AttachmentSaveTransactionRunnable( final XWikiAttachment attachment, final boolean updateDocument, final XWikiContext context, final File attachFile, final File tempFile, final File backupFile, final ReadWriteLock lock) throws XWikiException { final StreamProvider provider = new AttachmentContentStreamProvider(attachment, context); new FileSaveTransactionRunnable(attachFile, tempFile, backupFile, lock, provider).runIn(this); // If the versioning store supports TransactionRunnable then use it, otherwise don't. final AttachmentVersioningStore avs = context.getWiki().getAttachmentVersioningStore(); final XWikiAttachmentArchive archive = attachment.getAttachment_archive(); if (avs instanceof FilesystemAttachmentVersioningStore) { final FilesystemAttachmentVersioningStore favs = (FilesystemAttachmentVersioningStore) avs; // If first save then create a new archive. if (archive == null) { favs.getArchiveSaveRunnable(new ListAttachmentArchive(attachment), context).runIn(this); } else { favs.getArchiveSaveRunnable(archive, context).runIn(this); } } else { new TransactionRunnable<XWikiHibernateTransaction>() { protected void onRun() throws XWikiException { avs.saveArchive(archive, context, false); } }.runIn(this); } // If updating of the parent document is required then add a TransactionRunnable to do that. if (updateDocument) { final XWikiStoreInterface store = context.getWiki().getStore(); final XWikiDocument doc = attachment.getDoc(); new TransactionRunnable<XWikiHibernateTransaction>() { protected void onRun() throws XWikiException { store.saveXWikiDoc(doc, context, false); } }.runIn(this); } this.attachment = attachment; this.updateDocument = updateDocument; this.context = context; }