/*
* 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.api;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xwiki.model.reference.DocumentReference;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.XWikiDeletedDocument;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.util.Programming;
/**
* Information about a deleted document in the recycle bin.
*
* @version $Id: e6ef027a82bfb534e51f7cd9bdba6cfe9a26e6a4 $
*/
public class DeletedDocument extends Api
{
private static final String ADMIN_RIGHT = "admin";
/** Logging helper object. */
private static final Logger LOGGER = LoggerFactory.getLogger(DeletedDocument.class);
/**
* The internal object wrapped by this API.
*/
private final XWikiDeletedDocument deletedDoc;
/**
* Simple constructor, initializes a new API object with the current {@link com.xpn.xwiki.XWikiContext context} and
* the specified protected {@link com.xpn.xwiki.doc.XWikiDeletedDocument deleted document} object.
*
* @param deletedDoc the internal object wrapped by this API
* @param context the current request context
*/
public DeletedDocument(XWikiDeletedDocument deletedDoc, XWikiContext context)
{
super(context);
this.deletedDoc = deletedDoc;
}
/**
* @return full name of document (ie: Main.WebHome)
*/
public String getFullName()
{
return this.deletedDoc.getFullName();
}
/**
* @return locale of document
* @deprecated since 8.0M1, use {@link #getLocale()} instead
*/
@Deprecated
public String getLanguage()
{
return this.deletedDoc.getLanguage();
}
/**
* @return locale of document
* @since 8.0M1
*/
public Locale getLocale()
{
return this.deletedDoc.getLocale();
}
/**
* @return date of delete action
*/
public Date getDate()
{
return this.deletedDoc.getDate();
}
/**
* @return user which delete document
*/
public String getDeleter()
{
return this.deletedDoc.getDeleter();
}
/**
* @return id of deleted document. id is unique only for this document.
*/
public long getId()
{
return this.deletedDoc.getId();
}
/**
* @return the id of the operation that deleted multiple documents at the same time, including this one
* @since 9.4RC1
*/
public String getBatchId()
{
return this.deletedDoc.getBatchId();
}
/**
* Check if the current user has the right to restore the document.
*
* @return {@code true} if the current user can restore this document, {@code false} otherwise
*/
public boolean canUndelete()
{
try {
return hasAccessLevel(ADMIN_RIGHT, getFullName()) || hasAccessLevel("undelete", getFullName());
} catch (XWikiException ex) {
// Public APIs should not throw exceptions
LOGGER.warn("Exception while checking if entry [{}] can be restored from the recycle bin", getId(), ex);
return false;
}
}
/**
* @return {@code true} if the current user can permanently delete this document, {@code false} otherwise
* @xwiki.xwikicfg xwiki.store.recyclebin.adminWaitDays How many days should an administrator wait before being able
* to permanently delete this document from the recycle bin. 0 by default.
* @xwiki.xwikicfg xwiki.store.recyclebin.waitDays How many days should a normal user with "delete" right wait
* before being able to permanently delete this document from the recycle bin. 7 by default.
*/
public boolean canDelete()
{
try {
XWikiDocument doc = new XWikiDocument();
doc.setFullName(getFullName(), this.context);
if (!hasAccessLevel(ADMIN_RIGHT, getFullName())
&& !getXWikiContext().getWiki().getRightService().checkAccess("delete", doc, this.context)) {
return false;
}
String waitdays;
if (hasAccessLevel(ADMIN_RIGHT, getFullName())) {
waitdays = getXWikiContext().getWiki().Param("xwiki.store.recyclebin.adminWaitDays", "0");
} else {
waitdays = getXWikiContext().getWiki().Param("xwiki.store.recyclebin.waitDays", "7");
}
int seconds = (int) (Double.parseDouble(waitdays) * 24 * 60 * 60 + 0.5);
Calendar cal = Calendar.getInstance();
cal.setTime(getDate());
cal.add(Calendar.SECOND, seconds);
return cal.before(Calendar.getInstance());
} catch (Exception ex) {
// Public APIs should not throw exceptions
LOGGER.warn("Exception while checking if entry [{}] can be removed from the recycle bin", getId(), ex);
return false;
}
}
/**
* @return original deleted document if user has programming rights, else {@code null}.
*/
@Programming
public XWikiDeletedDocument getDeletedDocument()
{
if (hasProgrammingRights()) {
return this.deletedDoc;
} else {
return null;
}
}
/**
* @return the document as it is in the recycle bin if the user is allowed to restore it, {@code null} otherwise
*/
public Document getDocument()
{
if (canUndelete()) {
try {
return new Document(this.deletedDoc.restoreDocument(null, this.context), this.context);
} catch (XWikiException e) {
LOGGER.warn("Failed to parse deleted document [{}]", getFullName(), e);
}
}
return null;
}
/**
* @return the document reference for the deleted document, including any locale information
* @since 9.4RC1
*/
public DocumentReference getDocumentReference()
{
return this.deletedDoc.getDocumentReference();
}
}