1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package com.xpn.xwiki.web

File DeleteAction.java

 

Coverage histogram

../../../../img/srcFileCovDistChart9.png
38% of files have more coverage

Code metrics

32
70
10
1
224
150
29
0.41
7
10
2.9

Classes

Class Line # Actions
DeleteAction 43 70 0% 29 18
0.8392857383.9%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package com.xpn.xwiki.web;
21   
22    import java.util.List;
23   
24    import org.apache.commons.lang3.StringUtils;
25    import org.xwiki.job.Job;
26    import org.xwiki.model.reference.DocumentReference;
27    import org.xwiki.model.reference.EntityReference;
28    import org.xwiki.refactoring.script.RefactoringScriptService;
29    import org.xwiki.script.service.ScriptService;
30   
31    import com.xpn.xwiki.XWiki;
32    import com.xpn.xwiki.XWikiContext;
33    import com.xpn.xwiki.XWikiException;
34    import com.xpn.xwiki.api.DeletedDocument;
35    import com.xpn.xwiki.doc.XWikiDeletedDocument;
36    import com.xpn.xwiki.doc.XWikiDocument;
37   
38    /**
39    * Action for delete document to recycle bin and for delete documents from recycle bin.
40    *
41    * @version $Id: 6bff1202d204f2b9e4ba089d8fdc02566bbfe87b $
42    */
 
43    public class DeleteAction extends XWikiAction
44    {
45    /** confirm parameter name. */
46    protected static final String CONFIRM_PARAM = "confirm";
47   
48    protected static final String ACTION_NAME = "delete";
49   
50    protected static final String ASYNC_PARAM = "async";
51   
52    protected static final String RECYCLED_DOCUMENT_ID_PARAM = "id";
53   
 
54  20 toggle private boolean isAsync(XWikiRequest request)
55    {
56  20 return "true".equals(request.get(ASYNC_PARAM));
57    }
58   
 
59  13 toggle private boolean doesAffectChildren(XWikiRequest request, DocumentReference documentReference)
60    {
61    // Security check: we do not "affect children" of a terminal document
62  13 return StringUtils.isNotEmpty(request.getParameter("affectChildren"))
63    && "WebHome".equals(documentReference.getName());
64    }
65   
 
66  63 toggle @Override
67    public boolean action(XWikiContext context) throws XWikiException
68    {
69  63 XWikiRequest request = context.getRequest();
70   
71    // If confirm=1 then delete the page. If not, the render action will go to the "delete" page so that the
72    // user can confirm. That "delete" page will then call the delete action again with confirm=1.
73  63 if (!"1".equals(request.getParameter(CONFIRM_PARAM))) {
74  11 return true;
75    }
76   
77    // CSRF prevention
78  52 if (!csrfTokenCheck(context)) {
79  0 return false;
80    }
81   
82  52 boolean redirected = delete(context);
83   
84  52 if (!redirected) {
85    // If a xredirect param is passed then redirect to the page specified instead of going to the default
86    // confirmation page.
87  11 String redirect = Utils.getRedirect(request, null);
88  11 if (redirect != null) {
89  1 sendRedirect(context.getResponse(), redirect);
90  1 redirected = true;
91    }
92    }
93   
94  52 return !redirected;
95    }
96   
 
97  14 toggle @Override
98    public String render(XWikiContext context) throws XWikiException
99    {
100  14 XWikiRequest request = context.getRequest();
101  14 XWikiDocument doc = context.getDoc();
102  14 String sindex = request.getParameter(RECYCLED_DOCUMENT_ID_PARAM);
103  14 boolean recycleIdIsValid = false;
104  14 if (sindex != null) {
105  0 long index = Long.parseLong(sindex);
106  0 if (context.getWiki().getRecycleBinStore().getDeletedDocument(doc, index, context, true) != null) {
107  0 recycleIdIsValid = true;
108    }
109    }
110   
111  14 if ("1".equals(request.getParameter(CONFIRM_PARAM))) {
112  3 return "deleted";
113    }
114  11 if (doc.isNew() && !recycleIdIsValid) {
115  0 return Utils.getPage(request, "docdoesnotexist");
116    }
117   
118  11 return ACTION_NAME;
119    }
120   
 
121  45 toggle protected boolean delete(XWikiContext context) throws XWikiException
122    {
123  45 XWiki xwiki = context.getWiki();
124  45 XWikiRequest request = context.getRequest();
125  45 XWikiResponse response = context.getResponse();
126  45 XWikiDocument doc = context.getDoc();
127   
128  45 String sindex = request.getParameter(RECYCLED_DOCUMENT_ID_PARAM);
129  45 if (sindex != null && xwiki.hasRecycleBin(context)) {
130  2 deleteFromRecycleBin(Long.parseLong(sindex), context);
131  2 return true;
132  43 } else if (doc.isNew()) {
133    // Redirect the user to the view template so that he gets the "document doesn't exist" dialog box.
134  30 sendRedirect(response, Utils.getRedirect("view", context));
135  30 return true;
136    } else {
137    // Delete to recycle bin.
138  13 return deleteToRecycleBin(context);
139    }
140    }
141   
 
142  2 toggle private void deleteFromRecycleBin(long index, XWikiContext context) throws XWikiException
143    {
144  2 XWiki xwiki = context.getWiki();
145  2 XWikiResponse response = context.getResponse();
146  2 XWikiDocument doc = context.getDoc();
147   
148  2 XWikiDeletedDocument dd = xwiki.getRecycleBinStore().getDeletedDocument(doc, index, context, true);
149    // If the document hasn't been previously deleted (i.e. it's not in the deleted document store) then
150    // don't try to delete it and instead redirect to the view page.
151  2 if (dd != null) {
152  2 DeletedDocument ddapi = new DeletedDocument(dd, context);
153  2 if (!ddapi.canDelete()) {
154  0 throw new XWikiException(XWikiException.MODULE_XWIKI_ACCESS, XWikiException.ERROR_XWIKI_ACCESS_DENIED,
155    "You are not allowed to delete a document from the trash "
156    + "immediately after it has been deleted from the wiki");
157    }
158  2 if (!dd.getFullName().equals(doc.getFullName())) {
159  0 throw new XWikiException(XWikiException.MODULE_XWIKI_APP, XWikiException.ERROR_XWIKI_APP_URL_EXCEPTION,
160    "The specified trash entry does not match the current document");
161    }
162  2 xwiki.getRecycleBinStore().deleteFromRecycleBin(doc, index, context, true);
163    }
164  2 sendRedirect(response, Utils.getRedirect("view", context));
165    }
166   
 
167  13 toggle private boolean deleteToRecycleBin(XWikiContext context) throws XWikiException
168    {
169  13 XWikiRequest request = context.getRequest();
170  13 XWikiDocument doc = context.getDoc();
171   
172  13 EntityReference documentReference =
173  13 doesAffectChildren(request, doc.getDocumentReference()) ? doc.getDocumentReference()
174    .getLastSpaceReference() : doc.getTranslatedDocument(context).getDocumentReferenceWithLocale();
175   
176  13 return deleteToRecycleBin(documentReference, context);
177    }
178   
 
179  20 toggle protected boolean deleteToRecycleBin(EntityReference entityReference, XWikiContext context) throws XWikiException
180    {
181  20 Job deleteJob = startDeleteJob(entityReference);
182   
183    // If the user have asked for an asynchronous delete action...
184  20 if (isAsync(context.getRequest())) {
185  9 List<String> jobId = deleteJob.getRequest().getId();
186    // We don't redirect to the delete action because by the time the redirect request reaches the server the
187    // specified entity may be already deleted and the current user may not have the delete right anymore (e.g.
188    // the current user is no longer the creator).
189  9 sendRedirect(context.getResponse(),
190    Utils.getRedirect("view", "xpage=delete&jobId=" + serializeJobId(jobId), context));
191   
192    // A redirect has been performed.
193  9 return true;
194    }
195   
196    // Otherwise...
197  11 try {
198  11 deleteJob.join();
199    } catch (InterruptedException e) {
200  0 throw new XWikiException(String.format("Failed to delete [%s]", entityReference), e);
201    }
202   
203    // No redirect has been performed.
204  11 return false;
205    }
206   
 
207  9 toggle private String serializeJobId(List<String> jobId)
208    {
209  9 return StringUtils.join(jobId, "/");
210    }
211   
 
212  20 toggle private Job startDeleteJob(EntityReference entityReference) throws XWikiException
213    {
214  20 RefactoringScriptService refactoring =
215    (RefactoringScriptService) Utils.getComponent(ScriptService.class, "refactoring");
216  20 Job deleteJob = refactoring.delete(entityReference);
217  20 if (deleteJob != null) {
218  20 return deleteJob;
219    } else {
220  0 throw new XWikiException(String.format("Failed to schedule the delete job for [%s]", entityReference),
221    refactoring.getLastError());
222    }
223    }
224    }