1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package com.xpn.xwiki.internal.doc

File XWikiAttachmentList.java

 

Coverage histogram

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

Code metrics

32
72
17
1
300
170
33
0.46
4.24
17
1.94

Classes

Class Line # Actions
XWikiAttachmentList 41 72 0% 33 21
0.826446382.6%
 

Contributing tests

This file is covered by 343 tests. .

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.internal.doc;
21   
22    import java.util.ArrayList;
23    import java.util.Collection;
24    import java.util.List;
25    import java.util.Map;
26    import java.util.concurrent.ConcurrentSkipListMap;
27    import java.util.concurrent.CopyOnWriteArrayList;
28   
29    import org.apache.commons.collections4.list.AbstractListDecorator;
30   
31    import com.xpn.xwiki.doc.XWikiAttachment;
32    import com.xpn.xwiki.doc.XWikiAttachment.AttachmentContainer;
33    import com.xpn.xwiki.doc.XWikiDocument;
34   
35    /**
36    * AttachmentList that holds elements in order of filename.
37    *
38    * @version $Id: 7f6420af6e678c57d968f480080e32cbf8eb4405 $
39    * @since 10.1RC1
40    */
 
41    public class XWikiAttachmentList extends AbstractListDecorator<XWikiAttachment> implements AttachmentContainer
42    {
43    private final Map<String, XWikiAttachment> map = new ConcurrentSkipListMap<>();
44   
45    /**
46    * Retro compatibility for very bad old code.
47    */
48    private final List<XWikiAttachment> emptyNameAttachments = new CopyOnWriteArrayList<>();
49   
50    private final XWikiDocument document;
51   
52    /**
53    * Initializes the map.
54    *
55    * @param document the document where this attachment is located
56    */
 
57  25244803 toggle public XWikiAttachmentList(XWikiDocument document)
58    {
59  25235934 super(new ArrayList<XWikiAttachment>());
60   
61  25246734 this.document = document;
62    }
63   
64    /**
65    * Adds attachment to the list in order of filename.
66    *
67    * @param attachment XWikiAttachment to add to the list
68    */
 
69  54 toggle @Override
70    public boolean add(XWikiAttachment attachment)
71    {
72  54 XWikiAttachment set = set(attachment);
73   
74  54 return set != attachment;
75    }
76   
77    /**
78    * Adds attachment to the list in order of filename.
79    *
80    * @param index index is ignored as list is reordered based on filename
81    * @param attachment XWikiAttachment to add to the list
82    */
 
83  1 toggle @Override
84    public void add(int index, XWikiAttachment attachment)
85    {
86  1 add(attachment);
87    }
88   
 
89  241569 toggle @Override
90    public void clear()
91    {
92  241575 this.map.clear();
93   
94  241576 updateList();
95    }
96   
97    /**
98    * Adds all attachments to the list in order of filename.
99    *
100    * @param c Collection that contains XWikiAttachment objects
101    */
 
102  5 toggle @Override
103    public boolean addAll(Collection<? extends XWikiAttachment> c)
104    {
105  5 boolean changed = false;
106  5 for (XWikiAttachment x : c) {
107  13 XWikiAttachment put = this.map.put(x.getFilename(), x);
108  13 if (put != x) {
109  13 changed = true;
110  13 added(x);
111    }
112    }
113   
114  5 if (changed) {
115  5 updateList();
116    }
117   
118  5 return changed;
119    }
120   
121    /**
122    * Adds all attachments to the list in order of filename.
123    *
124    * @param index index is ignored as list is reordered based on filename
125    * @param c Collection that contains XWikiAttachment objects
126    */
 
127  1 toggle @Override
128    public boolean addAll(int index, Collection<? extends XWikiAttachment> c)
129    {
130  1 return addAll(c);
131    }
132   
 
133  3 toggle @Override
134    public XWikiAttachment remove(int index)
135    {
136  3 XWikiAttachment removedAttachment = this.map.remove(this.decorated().get(index).getFilename());
137  3 if (removedAttachment != null) {
138  3 updateList();
139    }
140   
141  3 return removedAttachment;
142    }
143   
144    /**
145    * Removes XWikiAttachment.
146    *
147    * @param attachment XWikiAttachment to remove.
148    * @return true unless the attachment is not found
149    */
 
150  14 toggle @Override
151    public boolean remove(Object attachment)
152    {
153  14 XWikiAttachment xwikiAttachment = (XWikiAttachment) attachment;
154  14 if (xwikiAttachment != null) {
155  14 if (xwikiAttachment.getFilename() != null) {
156  14 if (this.map.remove(xwikiAttachment.getFilename()) != null) {
157  13 updateList();
158   
159  13 return true;
160    }
161  0 } else if (this.emptyNameAttachments.remove(xwikiAttachment)) {
162  0 updateList();
163   
164  0 return true;
165    }
166    }
167   
168  1 return false;
169    }
170   
171    /**
172    * Adds or replaces attachment with the same filename as the parameter.
173    *
174    * @param attachment the attachment to add to the list
175    * @return the attachment that was previously matched to the same filename or null if no attachment was matched to
176    * it
177    */
 
178  224528 toggle public XWikiAttachment set(XWikiAttachment attachment)
179    {
180  224530 XWikiAttachment previous;
181   
182  224530 if (attachment.getFilename() != null) {
183  224528 previous = this.map.put(attachment.getFilename(), attachment);
184  224530 if (previous != attachment) {
185  224529 added(attachment);
186  224527 updateList();
187    }
188    } else {
189  0 this.emptyNameAttachments.add(attachment);
190   
191  0 previous = null;
192    }
193   
194  224530 return previous;
195    }
196   
197    /**
198    * Adds or replaces attachment with the same filename as the parameter.
199    *
200    * @param index this parameter is not used but is needed to override the method
201    * @param attachment the attachment to add to the list
202    * @return the attachment that was previously matched to the same filename or null if no attachment was matched to
203    * it
204    */
 
205  2 toggle @Override
206    public XWikiAttachment set(int index, XWikiAttachment attachment)
207    {
208  2 return set(attachment);
209    }
210   
211    /**
212    * @param filename the filename of the attachment to be returned.
213    * @return attachment with the given filename or null if not found.
214    */
 
215  984833 toggle public XWikiAttachment getByFilename(String filename)
216    {
217    // Null key is forbidden in ConcurrentSkipListMap
218  985421 return filename != null ? this.map.get(filename) : null;
219    }
220   
 
221  1 toggle @Override
222    public boolean removeAll(Collection<?> c)
223    {
224  1 boolean changed = false;
225  1 for (XWikiAttachment x : (Collection<? extends XWikiAttachment>) c) {
226  3 if (this.map.get(x.getFilename()) == x) {
227  3 this.map.remove(x.getFilename());
228  3 changed = true;
229    }
230    }
231  1 if (changed) {
232  1 updateList();
233    }
234   
235  1 return changed;
236    }
237   
 
238  1 toggle @Override
239    public boolean retainAll(Collection<?> c)
240    {
241  1 boolean changed = false;
242  1 Collection<XWikiAttachment> values = this.map.values();
243  1 for (XWikiAttachment x : values) {
244  4 if (!c.contains(x)) {
245  1 this.map.remove(x.getFilename());
246  1 changed = true;
247    }
248    }
249   
250  1 if (changed) {
251  1 updateList();
252    }
253   
254  1 return changed;
255    }
256   
257    /**
258    * Sets MetaDataDirty to true and resets the list with the values in the map.
259    */
 
260  466111 toggle private void updateList()
261    {
262  466115 this.document.setMetaDataDirty(true);
263   
264  466110 List<XWikiAttachment> list = new ArrayList<>(this.map.values());
265  466126 list.addAll(this.emptyNameAttachments);
266   
267  466121 this.setCollection(list);
268    }
269   
270    /**
271    * @param element XWikiAttachment that was added to the list
272    */
 
273  224541 toggle protected void added(XWikiAttachment element)
274    {
275  224542 element.setDoc(this.document);
276  224541 element.setAttachmentContainer(this);
277    }
278   
 
279  0 toggle protected void removed(XWikiAttachment element)
280    {
281  0 element.setAttachmentContainer(null);
282    }
283   
 
284  4 toggle @Override
285    public void onAttachmentNameModified(String previousAttachmentName, XWikiAttachment attachment)
286    {
287    // Remove the attachment from the previous location
288  4 boolean removed;
289  4 if (previousAttachmentName != null) {
290  4 removed = this.map.remove(previousAttachmentName) == attachment;
291    } else {
292  0 removed = this.emptyNameAttachments.remove(attachment);
293    }
294   
295  4 if (removed) {
296    // Add in the right place
297  4 set(attachment);
298    }
299    }
300    }