1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package com.xpn.xwiki.plugin.webdav.resources.domain

File DavPage.java

 

Coverage histogram

../../../../../../../img/srcFileCovDistChart5.png
74% of files have more coverage

Code metrics

50
135
13
1
310
244
47
0.35
10.38
13
3.62

Classes

Class Line # Actions
DavPage 49 135 0% 47 110
0.4444444544.4%
 

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.plugin.webdav.resources.domain;
21   
22    import java.io.IOException;
23    import java.util.ArrayList;
24    import java.util.List;
25   
26    import org.apache.jackrabbit.server.io.IOUtil;
27    import org.apache.jackrabbit.webdav.DavConstants;
28    import org.apache.jackrabbit.webdav.DavException;
29    import org.apache.jackrabbit.webdav.DavResource;
30    import org.apache.jackrabbit.webdav.DavResourceIterator;
31    import org.apache.jackrabbit.webdav.DavResourceIteratorImpl;
32    import org.apache.jackrabbit.webdav.DavServletResponse;
33    import org.apache.jackrabbit.webdav.io.InputContext;
34    import org.apache.jackrabbit.webdav.io.OutputContext;
35    import org.apache.jackrabbit.webdav.property.DavPropertyName;
36    import org.apache.jackrabbit.webdav.property.DefaultDavProperty;
37    import org.slf4j.Logger;
38    import org.slf4j.LoggerFactory;
39   
40    import com.xpn.xwiki.doc.XWikiDocument;
41    import com.xpn.xwiki.plugin.webdav.resources.XWikiDavResource;
42    import com.xpn.xwiki.plugin.webdav.resources.partial.AbstractDavResource;
43   
44    /**
45    * The collection resource which represents a page {@link XWikiDocument} of XWiki.
46    *
47    * @version $Id: 7e2fb01ff83aeef62b9ba6d6972527d1938526c0 $
48    */
 
49    public class DavPage extends AbstractDavResource
50    {
51    /**
52    * Logger instance.
53    */
54    private static final Logger logger = LoggerFactory.getLogger(DavPage.class);
55   
56    /**
57    * The name of the space to which this page belongs to.
58    */
59    private String spaceName;
60   
61    /**
62    * The {@link XWikiDocument} represented by this resource.
63    */
64    private XWikiDocument doc;
65   
 
66  20 toggle @Override
67    public void init(XWikiDavResource parent, String name, String relativePath) throws DavException
68    {
69  20 super.init(parent, name, relativePath);
70  20 int dot = name.lastIndexOf('.');
71  20 if (dot != -1) {
72  20 this.spaceName = name.substring(0, dot);
73    } else {
74  0 throw new DavException(DavServletResponse.SC_BAD_REQUEST);
75    }
76  20 this.doc = getContext().getDocument(this.name);
77  20 String timeStamp = DavConstants.creationDateFormat.format(doc.getCreationDate());
78  20 getProperties().add(new DefaultDavProperty(DavPropertyName.CREATIONDATE, timeStamp));
79  20 timeStamp = DavConstants.modificationDateFormat.format(doc.getContentUpdateDate());
80  20 getProperties().add(new DefaultDavProperty(DavPropertyName.GETLASTMODIFIED, timeStamp));
81  20 getProperties().add(new DefaultDavProperty(DavPropertyName.GETETAG, timeStamp));
82  20 getProperties().add(new DefaultDavProperty(DavPropertyName.GETCONTENTTYPE, "text/directory"));
83  20 getProperties().add(new DefaultDavProperty(DavPropertyName.GETCONTENTLANGUAGE, doc.getLanguage()));
84  20 getProperties().add(new DefaultDavProperty(DavPropertyName.GETCONTENTLENGTH, 0));
85    }
86   
 
87  9 toggle @Override
88    public XWikiDavResource decode(String[] tokens, int next) throws DavException
89    {
90  9 String nextToken = tokens[next];
91  9 boolean last = (next == tokens.length - 1);
92  9 XWikiDavResource resource = null;
93  9 String relativePath = "/" + nextToken;
94  9 if (isTempResource(nextToken)) {
95  0 return super.decode(tokens, next);
96  9 } else if (nextToken.equals(DavWikiFile.WIKI_TXT) || nextToken.equals(DavWikiFile.WIKI_XML)) {
97  5 resource = new DavWikiFile();
98  5 resource.init(this, nextToken, relativePath);
99  4 } else if (doc.getAttachment(nextToken) != null || (last && getContext().isCreateFileRequest())
100    || (last && getContext().isMoveAttachmentRequest(doc))) {
101  3 resource = new DavAttachment();
102  3 resource.init(this, nextToken, relativePath);
103    } else {
104  1 int dot = nextToken.indexOf('.');
105  1 String pageName = (dot != -1) ? nextToken : this.spaceName + "." + nextToken;
106  1 resource = new DavPage();
107  1 resource.init(this, pageName, relativePath);
108    }
109  9 return last ? resource : resource.decode(tokens, next + 1);
110    }
111   
 
112  21 toggle @Override
113    public boolean exists()
114    {
115  21 return !doc.isNew();
116    }
117   
 
118  0 toggle @SuppressWarnings("unchecked")
119    @Override
120    public DavResourceIterator getMembers()
121    {
122    // Protect against direct url referencing.
123  0 List<DavResource> children = new ArrayList<DavResource>();
124  0 if (!getContext().hasAccess("view", this.name)) {
125  0 return new DavResourceIteratorImpl(children);
126    }
127  0 try {
128  0 String sql = "where doc.parent='" + this.name + "'";
129  0 List<String> docNames = getContext().searchDocumentsNames(sql);
130  0 for (String docName : docNames) {
131  0 if (!createsCycle(docName) && getContext().hasAccess("view", docName)) {
132  0 XWikiDocument childDoc = getContext().getDocument(docName);
133  0 DavPage page = new DavPage();
134  0 if (childDoc.getSpace().equals(this.spaceName)) {
135  0 page.init(this, docName, "/" + childDoc.getName());
136    } else {
137  0 page.init(this, docName, "/" + docName);
138    }
139  0 children.add(page);
140    }
141    }
142  0 sql =
143    "select attach.filename from XWikiAttachment as attach, "
144    + "XWikiDocument as doc where attach.docId=doc.id and doc.fullName='" + this.name + "'";
145  0 List attachments = getContext().search(sql);
146  0 for (int i = 0; i < attachments.size(); i++) {
147  0 String filename = (String) attachments.get(i);
148  0 DavAttachment attachment = new DavAttachment();
149  0 attachment.init(this, filename, "/" + filename);
150  0 children.add(attachment);
151    }
152  0 children.addAll(getVirtualMembers());
153    } catch (DavException e) {
154  0 logger.error("Unexpected Error : ", e);
155    }
156  0 return new DavResourceIteratorImpl(children);
157    }
158   
 
159  3 toggle @Override
160    public void addMember(DavResource resource, InputContext inputContext) throws DavException
161    {
162  3 getContext().checkAccess("edit", this.name);
163  3 boolean isFile = (inputContext.getInputStream() != null);
164  3 if (resource instanceof DavTempFile) {
165  0 addVirtualMember(resource, inputContext);
166  3 } else if (resource instanceof DavPage) {
167  0 String pName = resource.getDisplayName();
168  0 getContext().checkAccess("edit", pName);
169  0 XWikiDocument childDoc = getContext().getDocument(pName);
170  0 childDoc.setContent("This page was created through the WebDAV interface.");
171  0 childDoc.setParent(this.name);
172  0 getContext().saveDocument(childDoc);
173  3 } else if (isFile) {
174  3 String fName = resource.getDisplayName();
175  3 byte[] data = getContext().getFileContentAsBytes(inputContext.getInputStream());
176  3 if (fName.equals(DavWikiFile.WIKI_TXT)) {
177  1 doc.setContent(new String(data));
178  1 getContext().saveDocument(doc);
179  2 } else if (fName.equals(DavWikiFile.WIKI_XML)) {
180  1 throw new DavException(DavServletResponse.SC_METHOD_NOT_ALLOWED);
181    } else {
182  1 getContext().addAttachment(doc, data, fName);
183    }
184    } else {
185  0 throw new DavException(DavServletResponse.SC_INTERNAL_SERVER_ERROR);
186    }
187    }
188   
 
189  1 toggle @Override
190    public void removeMember(DavResource member) throws DavException
191    {
192  1 getContext().checkAccess("edit", this.name);
193  1 XWikiDavResource dResource = (XWikiDavResource) member;
194  1 String mName = dResource.getDisplayName();
195  1 if (dResource instanceof DavTempFile) {
196  0 removeVirtualMember(dResource);
197  1 } else if (dResource instanceof DavWikiFile) {
198  0 getContext().checkAccess("delete", this.name);
199  0 removeVirtualMember(dResource);
200  1 } else if (dResource instanceof DavAttachment) {
201  1 getContext().deleteAttachment(doc.getAttachment(mName));
202  0 } else if (dResource instanceof DavPage) {
203  0 XWikiDocument childDoc = getContext().getDocument(mName);
204  0 getContext().checkAccess("delete", childDoc.getFullName());
205  0 if (!childDoc.isNew()) {
206  0 getContext().deleteDocument(childDoc);
207    }
208    } else {
209  0 throw new DavException(DavServletResponse.SC_INTERNAL_SERVER_ERROR);
210    }
211  1 dResource.clearCache();
212    }
213   
 
214  0 toggle @Override
215    public void move(DavResource destination) throws DavException
216    {
217    // Renaming a page requires edit rights on the current document, overwrite rights on the
218    // target document and edit rights on all the children of current document.
219  0 getContext().checkAccess("edit", this.name);
220  0 if (destination instanceof DavPage) {
221  0 DavPage dPage = (DavPage) destination;
222  0 XWikiDocument dDoc = dPage.getDocument();
223  0 List<String> spaces = getContext().getSpaces();
224  0 if (spaces.contains(dDoc.getSpace())) {
225  0 String newDocName = dDoc.getFullName();
226  0 String sql = "where doc.parent='" + this.name + "'";
227  0 List<String> childDocNames = getContext().searchDocumentsNames(sql);
228    // Validate access rights for the destination page.
229  0 getContext().checkAccess("overwrite", newDocName);
230    // Validate access rights for all the child pages.
231  0 for (String childDocName : childDocNames) {
232  0 getContext().checkAccess("edit", childDocName);
233    }
234  0 getContext().renameDocument(doc, newDocName);
235  0 for (String childDocName : childDocNames) {
236  0 XWikiDocument childDoc = getContext().getDocument(childDocName);
237  0 childDoc.setParent(newDocName);
238  0 getContext().saveDocument(childDoc);
239    }
240    }
241    } else {
242  0 throw new DavException(DavServletResponse.SC_BAD_REQUEST);
243    }
244  0 clearCache();
245    }
246   
 
247  2 toggle @Override
248    public List<XWikiDavResource> getInitMembers()
249    {
250  2 List<XWikiDavResource> initialMembers = new ArrayList<XWikiDavResource>();
251  2 try {
252  2 DavWikiFile wikiText = new DavWikiFile();
253  2 wikiText.init(this, DavWikiFile.WIKI_TXT, "/" + DavWikiFile.WIKI_TXT);
254  2 initialMembers.add(wikiText);
255  2 DavWikiFile wikiXml = new DavWikiFile();
256  2 wikiXml.init(this, DavWikiFile.WIKI_XML, "/" + DavWikiFile.WIKI_XML);
257  2 initialMembers.add(wikiXml);
258    } catch (DavException ex) {
259  0 logger.error("Error while initializing members.", ex);
260    }
261  2 return initialMembers;
262    }
263   
 
264  20 toggle @Override
265    public boolean isCollection()
266    {
267  20 return true;
268    }
269   
 
270  0 toggle @Override
271    public void spool(OutputContext outputContext) throws IOException
272    {
273  0 throw new IOException("Collection resources can't be spooled");
274    }
275   
 
276  0 toggle @Override
277    public long getModificationTime()
278    {
279  0 if (exists()) {
280  0 return doc.getContentUpdateDate().getTime();
281    }
282  0 return IOUtil.UNDEFINED_TIME;
283    }
284   
285    /**
286    * @return The document represented by this resource.
287    */
 
288  12 toggle public XWikiDocument getDocument()
289    {
290  12 return this.doc;
291    }
292   
293    /**
294    * Utility method to verify that a member of this resource doesn't give rise to a cycle.
295    *
296    * @param childDocName Name of the want-to-be-member resource.
297    * @return True if the childPageName has occured before, false otherwise.
298    */
 
299  0 toggle public boolean createsCycle(String childDocName)
300    {
301  0 DavResource ancestor = this;
302  0 while (ancestor instanceof DavPage && ancestor != null) {
303  0 if (ancestor.getDisplayName().equals(childDocName)) {
304  0 return true;
305    }
306  0 ancestor = ancestor.getCollection();
307    }
308  0 return false;
309    }
310    }