Skip to contentPackage: Rights$Right
Rights$Right
Coverage
1: /*
2: * Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved.
3: *
4: * This program and the accompanying materials are made available under the
5: * terms of the Eclipse Public License v. 2.0, which is available at
6: * http://www.eclipse.org/legal/epl-2.0.
7: *
8: * This Source Code may also be made available under the following Secondary
9: * Licenses when the conditions for such availability set forth in the
10: * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11: * version 2 with the GNU Classpath Exception, which is available at
12: * https://www.gnu.org/software/classpath/license.html.
13: *
14: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15: */
16:
17: package org.eclipse.angus.mail.imap;
18:
19: import java.util.*;
20:
21: /**
22: * The Rights class represents the set of rights for an authentication
23: * identifier (for instance, a user or a group). <p>
24: *
25: * A right is represented by the <code>Rights.Right</code>
26: * inner class. <p>
27: *
28: * A set of standard rights are predefined (see RFC 2086). Most folder
29: * implementations are expected to support these rights. Some
30: * implementations may also support site-defined rights. <p>
31: *
32: * The following code sample illustrates how to examine your
33: * rights for a folder.
34: * <pre>
35: *
36: * Rights rights = folder.myRights();
37: *
38: * // Check if I can write this folder
39: * if (rights.contains(Rights.Right.WRITE))
40: *        System.out.println("Can write folder");
41: *
42: * // Now give Joe all my rights, except the ability to write the folder
43: * rights.remove(Rights.Right.WRITE);
44: * ACL acl = new ACL("joe", rights);
45: * folder.setACL(acl);
46: * </pre>
47: * <p>
48: *
49: * @author Bill Shannon
50: */
51:
52: public class Rights implements Cloneable {
53:
54: private boolean[] rights = new boolean[128];        // XXX
55:
56: /**
57: * This inner class represents an individual right. A set
58: * of standard rights objects are predefined here.
59: */
60: public static final class Right {
61:         private static Right[] cache = new Right[128];
62:
63:         // XXX - initialization order?
64:         /**
65:          * Lookup - mailbox is visible to LIST/LSUB commands.
66:          */
67:         public static final Right LOOKUP = getInstance('l');
68:
69:         /**
70:          * Read - SELECT the mailbox, perform CHECK, FETCH, PARTIAL,
71:          * SEARCH, COPY from mailbox
72:          */
73:         public static final Right READ = getInstance('r');
74:
75:         /**
76:          * Keep seen/unseen information across sessions - STORE \SEEN flag.
77:          */
78:         public static final Right KEEP_SEEN = getInstance('s');
79:
80:         /**
81:          * Write - STORE flags other than \SEEN and \DELETED.
82:          */
83:         public static final Right WRITE = getInstance('w');
84:
85:         /**
86:          * Insert - perform APPEND, COPY into mailbox.
87:          */
88:         public static final Right INSERT = getInstance('i');
89:
90:         /**
91:          * Post - send mail to submission address for mailbox,
92:          * not enforced by IMAP4 itself.
93:          */
94:         public static final Right POST = getInstance('p');
95:
96:         /**
97:          * Create - CREATE new sub-mailboxes in any implementation-defined
98:          * hierarchy, RENAME or DELETE mailbox.
99:          */
100:         public static final Right CREATE = getInstance('c');
101:
102:         /**
103:          * Delete - STORE \DELETED flag, perform EXPUNGE.
104:          */
105:         public static final Right DELETE = getInstance('d');
106:
107:         /**
108:          * Administer - perform SETACL.
109:          */
110:         public static final Right ADMINISTER = getInstance('a');
111:
112:         char right;        // the right represented by this Right object
113:
114:         /**
115:          * Private constructor used only by getInstance.
116:          */
117:         private Right(char right) {
118:•         if ((int)right >= 128)
119:                 throw new IllegalArgumentException("Right must be ASCII");
120:          this.right = right;
121:         }
122:
123:         /**
124:          * Get a Right object representing the specified character.
125:          * Characters are assigned per RFC 2086.
126:          *
127:          * @param        right        the character representing the right
128:          * @return                the Right object
129:          */
130:         public static synchronized Right getInstance(char right) {
131:•         if ((int)right >= 128)
132:                 throw new IllegalArgumentException("Right must be ASCII");
133:•         if (cache[(int)right] == null)
134:                 cache[(int)right] = new Right(right);
135:          return cache[(int)right];
136:         }
137:
138:         @Override
139:         public String toString() {
140:          return String.valueOf(right);
141:         }
142: }
143:
144:
145: /**
146: * Construct an empty Rights object.
147: */
148: public Rights() { }
149:
150: /**
151: * Construct a Rights object initialized with the given rights.
152: *
153: * @param rights        the rights for initialization
154: */
155: public Rights(Rights rights) {
156:         System.arraycopy(rights.rights, 0, this.rights, 0, this.rights.length);
157: }
158:
159: /**
160: * Construct a Rights object initialized with the given rights.
161: *
162: * @param rights        the rights for initialization
163: */
164: public Rights(String rights) {
165:         for (int i = 0; i < rights.length(); i++)
166:          add(Right.getInstance(rights.charAt(i)));
167: }
168:
169: /**
170: * Construct a Rights object initialized with the given right.
171: *
172: * @param right        the right for initialization
173: */
174: public Rights(Right right) {
175:         this.rights[(int)right.right] = true;
176: }
177:
178: /**
179: * Add the specified right to this Rights object.
180: *
181: * @param right        the right to add
182: */
183: public void add(Right right) {
184:         this.rights[(int)right.right] = true;
185: }
186:
187: /**
188: * Add all the rights in the given Rights object to this
189: * Rights object.
190: *
191: * @param rights        Rights object
192: */
193: public void add(Rights rights) {
194:         for (int i = 0; i < rights.rights.length; i++)
195:          if (rights.rights[i])
196:                 this.rights[i] = true;
197: }
198:
199: /**
200: * Remove the specified right from this Rights object.
201: *
202: * @param        right         the right to be removed
203: */
204: public void remove(Right right) {
205:         this.rights[(int)right.right] = false;
206: }
207:
208: /**
209: * Remove all rights in the given Rights object from this
210: * Rights object.
211: *
212: * @param        rights         the rights to be removed
213: */
214: public void remove(Rights rights) {
215:         for (int i = 0; i < rights.rights.length; i++)
216:          if (rights.rights[i])
217:                 this.rights[i] = false;
218: }
219:
220: /**
221: * Check whether the specified right is present in this Rights object.
222: *
223: * @param        right        the Right to check
224: * @return                 true of the given right is present, otherwise false.
225: */
226: public boolean contains(Right right) {
227:         return this.rights[(int)right.right];
228: }
229:
230: /**
231: * Check whether all the rights in the specified Rights object are
232: * present in this Rights object.
233: *
234: * @param        rights        the Rights to check
235: * @return        true if all rights in the given Rights object are present,
236: *                otherwise false.
237: */
238: public boolean contains(Rights rights) {
239:         for (int i = 0; i < rights.rights.length; i++)
240:          if (rights.rights[i] && !this.rights[i])
241:                 return false;
242:
243:         // If we've made it till here, return true
244:         return true;
245: }
246:
247: /**
248: * Check whether the two Rights objects are equal.
249: *
250: * @return        true if they're equal
251: */
252: @Override
253: public boolean equals(Object obj) {
254:         if (!(obj instanceof Rights))
255:          return false;
256:
257:         Rights rights = (Rights)obj;
258:
259:         for (int i = 0; i < rights.rights.length; i++)
260:          if (rights.rights[i] != this.rights[i])
261:                 return false;
262:
263:         return true;
264: }
265:
266: /**
267: * Compute a hash code for this Rights object.
268: *
269: * @return        the hash code
270: */
271: @Override
272: public int hashCode() {
273:         int hash = 0;
274:         for (int i = 0; i < this.rights.length; i++)
275:          if (this.rights[i])
276:                 hash++;
277:         return hash;
278: }
279:
280: /**
281: * Return all the rights in this Rights object. Returns
282: * an array of size zero if no rights are set.
283: *
284: * @return        array of Rights.Right objects representing rights
285: */
286: public Right[] getRights() {
287:         List<Right> v = new ArrayList<>();
288:         for (int i = 0; i < this.rights.length; i++)
289:          if (this.rights[i])
290:                 v.add(Right.getInstance((char)i));
291:         return v.toArray(new Right[v.size()]);
292: }
293:
294: /**
295: * Returns a clone of this Rights object.
296: */
297: @Override
298: public Object clone() {
299:         Rights r = null;
300:         try {
301:          r = (Rights)super.clone();
302:          r.rights = new boolean[128];
303:          System.arraycopy(this.rights, 0, r.rights, 0, this.rights.length);
304:         } catch (CloneNotSupportedException cex) {
305:          // ignore, can't happen
306:         }
307:         return r;
308: }
309:
310: @Override
311: public String toString() {
312:         StringBuilder sb = new StringBuilder();
313:         for (int i = 0; i < this.rights.length; i++)
314:          if (this.rights[i])
315:                 sb.append((char)i);
316:         return sb.toString();
317: }
318:
319: /*****
320: public static void main(String argv[]) throws Exception {
321:         // a new rights object
322:         Rights f1 = new Rights();
323:         f1.add(Rights.Right.READ);
324:         f1.add(Rights.Right.WRITE);
325:         f1.add(Rights.Right.CREATE);
326:         f1.add(Rights.Right.DELETE);
327:
328:         // check copy constructor
329:         Rights fc = new Rights(f1);
330:         if (f1.equals(fc) && fc.equals(f1))
331:          System.out.println("success");
332:         else
333:          System.out.println("fail");
334:
335:         // check clone
336:         fc = (Rights)f1.clone();
337:         if (f1.equals(fc) && fc.equals(f1))
338:          System.out.println("success");
339:         else
340:          System.out.println("fail");
341:
342:         // add a right and make sure it still works right
343:         f1.add(Rights.Right.ADMINISTER);
344:
345:         // shouldn't be equal here
346:         if (!f1.equals(fc) && !fc.equals(f1))
347:          System.out.println("success");
348:         else
349:          System.out.println("fail");
350:
351:         // check clone
352:         fc = (Rights)f1.clone();
353:         if (f1.equals(fc) && fc.equals(f1))
354:          System.out.println("success");
355:         else
356:          System.out.println("fail");
357:
358:         fc.add(Rights.Right.INSERT);
359:         if (!f1.equals(fc) && !fc.equals(f1))
360:          System.out.println("success");
361:         else
362:          System.out.println("fail");
363:
364:         // check copy constructor
365:         fc = new Rights(f1);
366:         if (f1.equals(fc) && fc.equals(f1))
367:          System.out.println("success");
368:         else
369:          System.out.println("fail");
370:
371:         // another new rights object
372:         Rights f2 = new Rights(Rights.Right.READ);
373:         f2.add(Rights.Right.WRITE);
374:
375:         if (f1.contains(Rights.Right.READ))
376:          System.out.println("success");
377:         else
378:          System.out.println("fail");
379:                 
380:         if (f1.contains(Rights.Right.WRITE))
381:          System.out.println("success");
382:         else
383:          System.out.println("fail");
384:
385:         if (f1.contains(Rights.Right.CREATE))
386:          System.out.println("success");
387:         else
388:          System.out.println("fail");
389:
390:         if (f1.contains(Rights.Right.DELETE))
391:          System.out.println("success");
392:         else
393:          System.out.println("fail");
394:
395:         if (f2.contains(Rights.Right.WRITE))
396:          System.out.println("success");
397:         else
398:          System.out.println("fail");
399:
400:
401:         System.out.println("----------------");
402:
403:         Right[] r = f1.getRights();
404:         for (int i = 0; i < r.length; i++)
405:          System.out.println(r[i]);
406:         System.out.println("----------------");
407:
408:         if (f1.contains(f2)) // this should be true
409:          System.out.println("success");
410:         else
411:          System.out.println("fail");
412:
413:         if (!f2.contains(f1)) // this should be false
414:          System.out.println("success");
415:         else
416:          System.out.println("fail");
417:
418:         Rights f3 = new Rights();
419:         f3.add(Rights.Right.READ);
420:         f3.add(Rights.Right.WRITE);
421:         f3.add(Rights.Right.CREATE);
422:         f3.add(Rights.Right.DELETE);
423:         f3.add(Rights.Right.ADMINISTER);
424:         f3.add(Rights.Right.LOOKUP);
425:
426:         f1.add(Rights.Right.LOOKUP);
427:
428:         if (f1.equals(f3))
429:          System.out.println("equals success");
430:         else
431:          System.out.println("fail");
432:         if (f3.equals(f1))
433:          System.out.println("equals success");
434:         else
435:          System.out.println("fail");
436:         System.out.println("f1 hash code " + f1.hashCode());
437:         System.out.println("f3 hash code " + f3.hashCode());
438:         if (f1.hashCode() == f3.hashCode())
439:          System.out.println("success");
440:         else
441:          System.out.println("fail");
442: }
443: ****/
444: }