1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.rest.internal.resources

File BaseAttachmentsResource.java

 

Coverage histogram

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

Code metrics

30
119
6
2
338
244
23
0.19
19.83
3
3.83

Classes

Class Line # Actions
BaseAttachmentsResource 57 115 0% 20 25
0.831081183.1%
BaseAttachmentsResource.AttachmentInfo 64 4 0% 3 0
1.0100%
 

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 org.xwiki.rest.internal.resources;
21   
22    import java.io.ByteArrayInputStream;
23    import java.io.IOException;
24    import java.io.InputStream;
25    import java.net.URI;
26    import java.net.URL;
27    import java.util.Calendar;
28    import java.util.Formatter;
29    import java.util.HashMap;
30    import java.util.HashSet;
31    import java.util.List;
32    import java.util.Map;
33    import java.util.Set;
34   
35    import org.xwiki.query.Query;
36    import org.xwiki.query.QueryException;
37    import org.xwiki.rest.Relations;
38    import org.xwiki.rest.XWikiResource;
39    import org.xwiki.rest.XWikiRestException;
40    import org.xwiki.rest.internal.DomainObjectFactory;
41    import org.xwiki.rest.internal.RangeIterable;
42    import org.xwiki.rest.internal.Utils;
43    import org.xwiki.rest.model.jaxb.Attachment;
44    import org.xwiki.rest.model.jaxb.Attachments;
45    import org.xwiki.rest.model.jaxb.Link;
46    import org.xwiki.rest.resources.attachments.AttachmentResource;
47    import org.xwiki.rest.resources.pages.PageResource;
48   
49    import com.xpn.xwiki.XWikiException;
50    import com.xpn.xwiki.api.Document;
51    import com.xpn.xwiki.doc.XWikiAttachment;
52    import com.xpn.xwiki.doc.XWikiDocument;
53   
54    /**
55    * @version $Id: 5d0eea0896f5547cb4deb829c2b3687658963a2f $
56    */
 
57    public class BaseAttachmentsResource extends XWikiResource
58    {
59    /**
60    * Helper class that contains newly created attachment information to be returned to the client. It contains the
61    * JAXB attachment object and a boolean variable that states if the attachment existed before. This class is used by
62    * the storeAttachment utility method.
63    */
 
64    protected static class AttachmentInfo
65    {
66    protected Attachment attachment;
67   
68    protected boolean alreadyExisting;
69   
 
70  46 toggle public AttachmentInfo(Attachment attachment, boolean alreadyExisting)
71    {
72  46 this.attachment = attachment;
73  46 this.alreadyExisting = alreadyExisting;
74    }
75   
 
76  46 toggle public Attachment getAttachment()
77    {
78  46 return attachment;
79    }
80   
 
81  46 toggle public boolean isAlreadyExisting()
82    {
83  46 return alreadyExisting;
84    }
85    }
86   
87    /**
88    * Retrieves the attachments by filtering them.
89    *
90    * @param wikiName The virtual wiki.
91    * @param name Name filter (include only attachments that matches this name)
92    * @param page Page filter (include only attachments are attached to a page matches this string)
93    * @param space Space filter (include only attachments are attached to a page in a space matching this string)
94    * @param author Author filter (include only attachments from an author who matches this string)
95    * @param types A comma separated list of string that will be matched against the actual mime type of the
96    * attachments.
97    * @return The list of the retrieved attachments.
98    */
 
99  5 toggle public Attachments getAttachments(String wikiName, String name, String page, String space, String author,
100    String types, Integer start, Integer number, Boolean withPrettyNames) throws XWikiRestException
101    {
102  5 String database = Utils.getXWikiContext(componentManager).getWikiId();
103   
104  5 Attachments attachments = objectFactory.createAttachments();
105   
106    /* This try is just needed for executing the finally clause. */
107  5 try {
108  5 Utils.getXWikiContext(componentManager).setWikiId(wikiName);
109   
110  5 Map<String, String> filters = new HashMap<String, String>();
111  5 if (!name.equals("")) {
112  2 filters.put("name", name);
113    }
114  5 if (!page.equals("")) {
115  0 filters.put("page", name);
116    }
117  5 if (!space.equals("")) {
118  3 filters.put("space", Utils.getLocalSpaceId(parseSpaceSegments(space)));
119    }
120  5 if (!author.equals("")) {
121  0 filters.put("author", author);
122    }
123   
124    /* Build the query */
125  5 Formatter f = new Formatter();
126  5 f.format("select doc.space, doc.name, doc.version, attachment from XWikiDocument as doc,"
127    + " XWikiAttachment as attachment where (attachment.docId=doc.id ");
128   
129  5 if (filters.keySet().size() > 0) {
130  4 for (String param : filters.keySet()) {
131  5 if (param.equals("name")) {
132  2 f.format(" and upper(attachment.filename) like :name ");
133    }
134  5 if (param.equals("page")) {
135  0 f.format(" and upper(doc.fullName) like :page ");
136    }
137  5 if (param.equals("space")) {
138  3 f.format(" and upper(doc.space) like :space ");
139    }
140   
141  5 if (param.equals("author")) {
142  0 f.format(" and upper(attachment.author) like :author ");
143    }
144    }
145    }
146   
147  5 f.format(")");
148   
149  5 String queryString = f.toString();
150   
151    /* Execute the query by filling the parameters */
152  5 List<Object> queryResult = null;
153  5 try {
154  5 Query query = queryManager.createQuery(queryString, Query.XWQL).setLimit(number).setOffset(start);
155  5 for (String param : filters.keySet()) {
156  5 query.bindValue(param, String.format("%%%s%%", filters.get(param).toUpperCase()));
157    }
158   
159  5 queryResult = query.execute();
160    } catch (QueryException e) {
161  0 throw new XWikiRestException(e);
162    }
163   
164  5 Set<String> acceptedMimeTypes = new HashSet<String>();
165  5 if (!types.equals("")) {
166  0 String[] acceptedMimetypesArray = types.split(",");
167  0 for (String type : acceptedMimetypesArray) {
168  0 acceptedMimeTypes.add(type);
169    }
170    }
171   
172  5 for (Object object : queryResult) {
173  21 Object[] fields = (Object[]) object;
174  21 String pageSpaceId = (String) fields[0];
175  21 List<String> pageSpaces = Utils.getSpacesFromSpaceId(pageSpaceId);
176  21 String pageName = (String) fields[1];
177  21 String pageId = Utils.getPageId(wikiName, pageSpaces, pageName);
178  21 String pageVersion = (String) fields[2];
179  21 XWikiAttachment xwikiAttachment = (XWikiAttachment) fields[3];
180   
181  21 String mimeType = xwikiAttachment.getMimeType(Utils.getXWikiContext(componentManager));
182   
183  21 boolean add = true;
184   
185    /* Check the mime type filter */
186  21 if (acceptedMimeTypes.size() > 0) {
187  0 add = false;
188   
189  0 for (String type : acceptedMimeTypes) {
190  0 if (mimeType.toUpperCase().contains(type.toUpperCase())) {
191  0 add = true;
192  0 break;
193    }
194    }
195    }
196   
197  21 if (add) {
198    /*
199    * We manufacture attachments in place because we don't have all the data for calling the
200    * DomainObjectFactory method (doing so would require to retrieve an actual Document)
201    */
202  21 Attachment attachment = objectFactory.createAttachment();
203  21 attachment.setId(String.format("%s@%s", pageId, xwikiAttachment.getFilename()));
204  21 attachment.setName(xwikiAttachment.getFilename());
205  21 attachment.setSize(xwikiAttachment.getFilesize());
206  21 attachment.setMimeType(mimeType);
207  21 attachment.setAuthor(xwikiAttachment.getAuthor());
208  21 if (withPrettyNames) {
209  0 attachment.setAuthorName(Utils.getAuthorName(xwikiAttachment.getAuthorReference(), componentManager));
210    }
211   
212  21 Calendar calendar = Calendar.getInstance();
213  21 calendar.setTime(xwikiAttachment.getDate());
214  21 attachment.setDate(calendar);
215   
216  21 attachment.setPageId(pageId);
217  21 attachment.setPageVersion(pageVersion);
218  21 attachment.setVersion(xwikiAttachment.getVersion());
219   
220  21 URL absoluteUrl =
221    Utils
222    .getXWikiContext(componentManager)
223    .getURLFactory()
224    .createAttachmentURL(xwikiAttachment.getFilename(), pageSpaceId, pageName, "download",
225    null,
226    wikiName, Utils.getXWikiContext(componentManager));
227  21 attachment.setXwikiAbsoluteUrl(absoluteUrl.toString());
228  21 attachment.setXwikiRelativeUrl(Utils.getXWikiContext(componentManager).getURLFactory()
229    .getURL(absoluteUrl, Utils.getXWikiContext(componentManager)));
230   
231  21 URI pageUri =
232    Utils.createURI(uriInfo.getBaseUri(), PageResource.class, wikiName, pageSpaces, pageName);
233  21 Link pageLink = objectFactory.createLink();
234  21 pageLink.setHref(pageUri.toString());
235  21 pageLink.setRel(Relations.PAGE);
236  21 attachment.getLinks().add(pageLink);
237   
238  21 URI attachmentUri =
239    Utils.createURI(uriInfo.getBaseUri(), AttachmentResource.class, wikiName, pageSpaces, pageName,
240    xwikiAttachment.getFilename());
241  21 Link attachmentLink = objectFactory.createLink();
242  21 attachmentLink.setHref(attachmentUri.toString());
243  21 attachmentLink.setRel(Relations.ATTACHMENT_DATA);
244  21 attachment.getLinks().add(attachmentLink);
245   
246  21 attachments.getAttachments().add(attachment);
247    }
248    }
249    } finally {
250  5 Utils.getXWikiContext(componentManager).setWikiId(database);
251    }
252   
253  5 return attachments;
254    }
255   
 
256  3 toggle protected Attachments getAttachmentsForDocument(Document doc, int start, int number, Boolean withPrettyNames)
257    {
258  3 Attachments attachments = objectFactory.createAttachments();
259   
260  3 List<com.xpn.xwiki.api.Attachment> xwikiAttachments = doc.getAttachmentList();
261   
262  3 RangeIterable<com.xpn.xwiki.api.Attachment> ri =
263    new RangeIterable<com.xpn.xwiki.api.Attachment>(xwikiAttachments, start, number);
264   
265  3 for (com.xpn.xwiki.api.Attachment xwikiAttachment : ri) {
266  9 URL url =
267    Utils
268    .getXWikiContext(componentManager)
269    .getURLFactory()
270    .createAttachmentURL(xwikiAttachment.getFilename(), doc.getSpace(), doc.getName(),
271    "download",
272    null, doc.getWiki(), Utils.getXWikiContext(componentManager));
273  9 String attachmentXWikiAbsoluteUrl = url.toString();
274  9 String attachmentXWikiRelativeUrl =
275    Utils.getXWikiContext(componentManager).getURLFactory()
276    .getURL(url, Utils.getXWikiContext(componentManager));
277   
278  9 attachments.getAttachments().add(
279    DomainObjectFactory.createAttachment(objectFactory, uriInfo.getBaseUri(), xwikiAttachment,
280    attachmentXWikiRelativeUrl, attachmentXWikiAbsoluteUrl, Utils.getXWikiApi(componentManager),
281    withPrettyNames));
282    }
283   
284  3 return attachments;
285    }
286   
 
287  46 toggle protected AttachmentInfo storeAttachment(Document doc, String attachmentName, byte[] content) throws XWikiException
288    {
289  46 boolean alreadyExisting = false;
290   
291  46 XWikiDocument xwikiDocument =
292    Utils.getXWiki(componentManager).getDocument(doc.getDocumentReference(),
293    Utils.getXWikiContext(componentManager));
294  46 XWikiAttachment xwikiAttachment = xwikiDocument.getAttachment(attachmentName);
295  46 if (xwikiAttachment == null) {
296  43 xwikiAttachment = new XWikiAttachment();
297  43 xwikiDocument.getAttachmentList().add(xwikiAttachment);
298    } else {
299  3 alreadyExisting = true;
300    }
301   
302  46 InputStream inputStream = new ByteArrayInputStream(content);
303   
304  46 try {
305  46 xwikiAttachment.setContent(inputStream);
306    } catch(IOException e) {
307  0 throw new XWikiException(XWikiException.MODULE_XWIKI_STORE, XWikiException.ERROR_XWIKI_STORE_MISC,
308    String.format("Failed to store the content of attachment [%s] in document [%s].",
309    attachmentName, doc.getPrefixedFullName()), e);
310    }
311  46 xwikiAttachment.setAuthor(Utils.getXWikiUser(componentManager));
312  46 xwikiAttachment.setFilename(attachmentName);
313  46 xwikiAttachment.setDoc(xwikiDocument);
314   
315  46 Utils.getXWiki(componentManager).saveDocument(xwikiDocument, Utils.getXWikiContext(componentManager));
316   
317  46 URL url =
318    Utils
319    .getXWikiContext(componentManager)
320    .getURLFactory()
321    .createAttachmentURL(attachmentName, doc.getSpace(), doc.getName(), "download", null,
322    doc.getWiki(),
323    Utils.getXWikiContext(componentManager));
324  46 String attachmentXWikiAbsoluteUrl = url.toString();
325  46 String attachmentXWikiRelativeUrl =
326    Utils.getXWikiContext(componentManager).getURLFactory()
327    .getURL(url, Utils.getXWikiContext(componentManager));
328   
329  46 Attachment attachment =
330    DomainObjectFactory
331    .createAttachment(objectFactory, uriInfo.getBaseUri(), new com.xpn.xwiki.api.Attachment(
332    doc, xwikiAttachment, Utils.getXWikiContext(componentManager)),
333    attachmentXWikiRelativeUrl,
334    attachmentXWikiAbsoluteUrl, Utils.getXWikiApi(componentManager), false);
335   
336  46 return new AttachmentInfo(attachment, alreadyExisting);
337    }
338    }