/* * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package com.xpn.xwiki.doc; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Date; import org.xwiki.filter.input.DefaultReaderInputSource; import org.xwiki.filter.output.DefaultWriterOutputTarget; import com.xpn.xwiki.XWikiContext; import com.xpn.xwiki.XWikiException; import com.xpn.xwiki.internal.file.TemporaryDeferredFileRepository; import com.xpn.xwiki.internal.file.TemporaryDeferredFileRepository.TemporaryDeferredStringFile; import com.xpn.xwiki.util.AbstractSimpleClass; import com.xpn.xwiki.web.Utils; /** * Archive of deleted attachment, stored in {@link com.xpn.xwiki.store.AttachmentRecycleBinStore}. Immutable, because * deleted attachments should not be modified. * * @version $Id: 2cf7430e532fa893b33f4c1523f042c0a09a26f5 $ * @since 1.4M1 */ public class DeletedAttachment extends AbstractSimpleClass { /** Synthetic id, generated by Hibernate. This is used to address entries in the recycle bin. */ private long id; /** The ID of the document this attachment belonged to. */ private long docId; /** The name of the document this attachment belonged to. */ private String docName; /** The name of the attachment. */ private String filename; /** Date of delete action. */ private Date date; /** The user who deleted the attachment, in the <tt>XWiki.UserName</tt> format. */ private String deleter; private TemporaryDeferredStringFile xml = Utils.getComponent(TemporaryDeferredFileRepository.class) .createTemporaryDeferredStringFile("deleted-attachments-xml", StandardCharsets.UTF_8); /** Default constructor. Used only by hibernate when restoring objects from the database. */ protected DeletedAttachment() { } /** * A constructor with all the information about the deleted attachment. * * @param attachment Deleted attachment. * @param deleter User which deleted the attachment. * @param deleteDate Date of delete action. * @param context The current context. Used for determining the encoding. * @throws XWikiException If the attachment cannot be exported to XML. */ public DeletedAttachment(XWikiAttachment attachment, String deleter, Date deleteDate, XWikiContext context) throws XWikiException { this.docId = attachment.getDocId(); this.docName = attachment.getDoc().getFullName(); this.filename = attachment.getFilename(); this.deleter = deleter; this.date = deleteDate; setAttachment(attachment, context); } /** * Getter for {@link #id}. * * @return The synthetic id of this deleted attachment. Uniquely identifies an entry in the recycle bin. */ public long getId() { return this.id; } /** * Setter for {@link #id}. * * @param id The synthetic id to set. Used only by hibernate. */ protected void setId(long id) { this.id = id; } /** * Getter for {@link #docId}. * * @return The id of the document this attachment belonged to. */ public long getDocId() { return this.docId; } /** * Setter for {@link #docId}. * * @param docId The id of the document to set. Used only by hibernate. */ protected void setDocId(long docId) { this.docId = docId; } /** * Getter for {@link #docName}. * * @return The name of the document this attachment belonged to. */ public String getDocName() { return this.docName; } /** * Setter for {@link #docName}. * * @param docName The document name to set. Used only by hibernate. */ protected void setDocName(String docName) { this.docName = docName; } /** * Getter for {@link #filename}. * * @return The name of the attachment. */ public String getFilename() { return this.filename; } /** * Setter for {@link #filename}. * * @param filename The attachment filename to set. Used only by hibernate. */ protected void setFilename(String filename) { this.filename = filename; } /** * Getter for {@link #date}. * * @return The date of the delete action. */ public Date getDate() { return this.date; } /** * Setter for {@link #date}. * * @param date The date of the delete action to set. Used only by Hibernate. */ protected void setDate(Date date) { this.date = date; } /** * Getter for {@link #deleter}. * * @return the user who deleted the attachment, as its document name (e.g. {@code XWiki.Admin}) */ public String getDeleter() { return this.deleter; } /** * Setter for {@link #deleter}. * * @param deleter The user which has removed the document to set. Used only by Hibernate. */ protected void setDeleter(String deleter) { this.deleter = deleter; } /** * Getter for {@link #xml}. * * @return XML serialization of {@link XWikiAttachment} */ public String getXml() { try { return this.xml.getString(); } catch (IOException e) { throw new RuntimeException("Failed to read XML", e); } } /** * Setter for {@link #xml}. * * @param xml XML serialization of {@link XWikiAttachment}. Used only by Hibernate. */ protected void setXml(String xml) { try { this.xml.setString(xml); } catch (IOException e) { throw new RuntimeException("Failed to write xml", e); } } /** * Export {@link XWikiAttachment} to {@link DeletedAttachment}. * * @param attachment the deleted attachment * @param context the current context, used in the XML export * @throws XWikiException if an exception occurs during the XML export */ protected void setAttachment(XWikiAttachment attachment, XWikiContext context) throws XWikiException { try { attachment.toXML(new DefaultWriterOutputTarget(this.xml.getWriter(), true), true, true, false, context); } catch (IOException e) { throw new XWikiException(XWikiException.MODULE_XWIKI_DOC, XWikiException.ERROR_DOC_XML_PARSING, "Error serializing attachment to xml", e, null); } } /** * Restore a {@link XWikiAttachment} from a {@link DeletedAttachment}. Note that this method does not actually * restore the attachment to its owner document, it simply recomposes an {@link XWikiAttachment} object from the * saved data. * * @return restored attachment * @param attachment optional object where to put the attachment data, if not <code>null</code> * @param context the current {@link XWikiContext context} * @throws XWikiException If an exception occurs while the Attachment is restored from the XML. See * {@link XWikiAttachment#fromXML(String)}. */ public XWikiAttachment restoreAttachment(XWikiAttachment attachment, XWikiContext context) throws XWikiException { XWikiAttachment result = attachment; if (result == null) { result = new XWikiAttachment(); } try { result.fromXML(new DefaultReaderInputSource(this.xml.getReader(), true)); } catch (IOException e) { throw new XWikiException(XWikiException.MODULE_XWIKI_DOC, XWikiException.ERROR_DOC_XML_PARSING, "Error restoring attachment from xml", e, null); } if (result.getDoc() == null || !(this.getDocName().equals(result.getDoc().getFullName()))) { result.setDoc(context.getWiki().getDocument(this.getDocName(), context)); } return result; } }