1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.security.authorization

File RightSet.java

 

Coverage histogram

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

Code metrics

36
82
25
2
305
213
44
0.54
3.28
12.5
1.76

Classes

Class Line # Actions
RightSet 34 71 0% 38 14
0.8870967688.7%
RightSet.RightIterator 85 11 0% 6 0
1.0100%
 

Contributing tests

This file is covered by 61 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 org.xwiki.security.authorization;
21   
22    import java.util.AbstractSet;
23    import java.util.Collection;
24    import java.util.Collections;
25    import java.util.Iterator;
26    import java.util.NoSuchElementException;
27   
28    /**
29    * Optimized set of {@link Right}.
30    *
31    * @version $Id: b2b7e2a8e3c0c9fc879f79db60c83368cd739e15 $
32    * @since 4.0M2
33    */
 
34    public class RightSet extends AbstractSet<Right> implements Cloneable, java.io.Serializable
35    {
36    /** Serialization identifier. */
37    private static final long serialVersionUID = 1L;
38   
39    /** Bit vector representation to store the set. */
40    private long rights;
41   
42    /** Default constructor. */
 
43  33346 toggle public RightSet()
44    {
45  33347 if (Right.size() > 64) {
46  0 throw new IllegalStateException();
47    }
48    }
49   
50    /**
51    * Create a new initialized set.
52    *
53    * @param rights a collection of {@code Right} object to initialize the set
54    */
 
55  303 toggle public RightSet(Collection<? extends Right> rights)
56    {
57  303 if (Right.size() > 64) {
58  0 throw new IllegalStateException();
59    }
60  303 this.addAll(rights);
61    }
62   
63    /**
64    * Create a new initialized set.
65    * @param rights the rights you want in the set
66    */
 
67  444 toggle public RightSet(Right... rights)
68    {
69  444 if (Right.size() > 64) {
70  0 throw new IllegalStateException();
71    }
72   
73  444 Collections.addAll(this, rights);
74    }
75   
 
76  24054 toggle @Override
77    public Iterator<Right> iterator()
78    {
79  24054 return new RightIterator();
80    }
81   
82    /**
83    * Private iterator for this set.
84    */
 
85    private class RightIterator implements Iterator<Right>
86    {
87   
88    /** Current index in the set, using a bit mask of remaining rights. */
89    private long index;
90   
91    /** Last element returned, using a single bit mask of current element. */
92    private long lastIndex;
93   
94    /** Default constructor. */
 
95  24056 toggle RightIterator()
96    {
97  24056 index = rights;
98    }
99   
 
100  145774 toggle @Override
101    public boolean hasNext()
102    {
103  145778 return index != 0;
104    }
105   
 
106  122456 toggle @Override
107    public Right next()
108    {
109  122457 if (index == 0) {
110  39 throw new NoSuchElementException();
111    }
112  122419 lastIndex = index & -index;
113  122420 index -= lastIndex;
114  122421 return Right.get(Long.numberOfTrailingZeros(lastIndex));
115    }
116   
 
117  1238 toggle @Override
118    public void remove()
119    {
120  1238 if (lastIndex == 0) {
121  789 throw new IllegalStateException();
122    }
123  449 rights -= lastIndex;
124  449 lastIndex = 0;
125    }
126    }
127   
 
128  489 toggle @Override
129    public boolean equals(Object o)
130    {
131  489 if (!(o instanceof RightSet)) {
132  21 return super.equals(o);
133    }
134   
135  468 return ((RightSet) o).rights == rights;
136    }
137   
 
138  330 toggle @Override
139    public int hashCode()
140    {
141  330 return new Long(rights).hashCode();
142    }
143   
 
144  21 toggle @Override
145    public boolean removeAll(Collection<?> objects)
146    {
147  21 if (!(objects instanceof RightSet)) {
148  21 return super.removeAll(objects);
149    }
150  0 long old = rights;
151  0 rights &= ~((RightSet) objects).rights;
152  0 return rights != old;
153    }
154   
 
155  54720 toggle @Override
156    public boolean add(Right right)
157    {
158  54720 long old = rights;
159  54720 rights |= (1L << right.ordinal());
160  54721 return rights != old;
161    }
162   
 
163  1704 toggle @Override
164    public boolean addAll(Collection<? extends Right> rights)
165    {
166  1705 if (!(rights instanceof RightSet)) {
167  19 return super.addAll(rights);
168    }
169   
170  1685 long old = this.rights;
171  1685 this.rights |= ((RightSet) rights).rights;
172  1685 return this.rights != old;
173    }
174   
 
175  3 toggle @Override
176    public void clear()
177    {
178  3 rights = 0;
179    }
180   
 
181  380906 toggle @Override
182    public boolean contains(Object o)
183    {
184  380914 return o != null && o instanceof Right && (rights & (1L << ((Right) o).ordinal())) != 0;
185    }
186   
 
187  30 toggle @Override
188    public boolean containsAll(Collection<?> objects)
189    {
190  30 if (!(objects instanceof RightSet)) {
191  27 return super.containsAll(objects);
192    }
193  3 return (((RightSet) objects).rights & ~rights) == 0;
194    }
195   
 
196  37611 toggle @Override
197    public boolean remove(Object o)
198    {
199  37612 if (o == null || !(o instanceof Right)) {
200  12 return false;
201    }
202  37600 long old = rights;
203  37600 rights &= ~(1L << ((Right) o).ordinal());
204  37600 return rights != old;
205    }
206   
 
207  75789 toggle @Override
208    public boolean isEmpty()
209    {
210  75789 return rights == 0;
211    }
212   
 
213  22 toggle @Override
214    public boolean retainAll(Collection<?> objects)
215    {
216  22 if (!(objects instanceof RightSet)) {
217  22 return super.retainAll(objects);
218    }
219  0 long old = rights;
220  0 rights &= ((RightSet) objects).rights;
221  0 return rights != old;
222    }
223   
 
224  1163 toggle @Override
225    public int size()
226    {
227    // return Long.bitCount(rights);
228    //
229    // Would be easier and probably faster, but some versions of the Oracle/Sun implementation may have an issue
230    // with Long.bitCount(), see:
231    // [Java 6] Wrong results from basic comparisons after calls to Long.bitCount(long) (pmd : XPathRule_1339015068)
232    // See Bug ID : 7063674
233    // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7063674
234    //
235    // So we have reimplemented it based on public domain code snippets published in Bit Twiddling Hacks
236    // by Sean Eron Anderson (see http://www-graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallelw)
237  1163 long v = rights - ((rights >>> 1) & 0x5555555555555555L);
238  1163 v = (v & 0x3333333333333333L) + ((v >>> 2) & 0x3333333333333333L);
239  1163 return (int) (((v + (v >> 4) & 0x0F0F0F0F0F0F0F0FL) * 0x0101010101010101L) >>> 56);
240    }
241   
 
242  6 toggle @Override
243    public Object[] toArray()
244    {
245  6 return fillArray(new Object[size()]);
246    }
247   
 
248  30 toggle @Override
249    @SuppressWarnings("unchecked")
250    public <T> T[] toArray(T[] ts)
251    {
252  30 T[] a = ts;
253  30 int size = size();
254  30 if (a.length < size) {
255  11 a = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);
256    }
257  30 if (a.length > size) {
258  6 a[size] = null;
259    }
260  30 return (T[]) fillArray(a);
261    }
262   
263    /**
264    * Fill array ts that should have the appropriate size with the {@code Right} in this set.
265    * @param ts an array properly sized to receive this set
266    * @return an array representing this set
267    */
 
268  36 toggle private Object[] fillArray(Object[] ts)
269    {
270  36 int j = 0;
271  446 for (int i = 0; i < Right.size(); i++) {
272  412 if ((rights & (1 << i)) > 0) {
273  101 ts[j++] = Right.get(i);
274    }
275    }
276  34 return ts;
277    }
278   
 
279  6 toggle @Override
280    public String toString()
281    {
282  6 StringBuilder sb = new StringBuilder("[");
283  6 boolean first = true;
284  78 for (int i = 0; i < Right.size(); i++) {
285  72 if ((rights & (1 << i)) > 0) {
286  13 if (first) {
287  5 first = false;
288    } else {
289  8 sb.append(", ");
290    }
291  13 sb.append(Right.get(i).getName());
292    }
293    }
294  6 sb.append("]");
295  6 return sb.toString();
296    }
297   
 
298  4938 toggle @Override
299    public RightSet clone() throws CloneNotSupportedException
300    {
301  4938 RightSet clone = (RightSet) super.clone();
302  4938 clone.rights = rights;
303  4938 return clone;
304    }
305    }