001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036:
037: /*
038: * @(#)Rights.java 1.8 07/05/15
039: */
040:
041: package com.sun.mail.imap;
042:
043: import java.util.*;
044:
045: /**
046: * The Rights class represents the set of rights for an authentication
047: * identifier (for instance, a user or a group). <p>
048: *
049: * A right is represented by the <code>Rights.Right</code>
050: * inner class. <p>
051: *
052: * A set of standard rights are predefined (see RFC 2086). Most folder
053: * implementations are expected to support these rights. Some
054: * implementations may also support site-defined rights. <p>
055: *
056: * The following code sample illustrates how to examine your
057: * rights for a folder. <p>
058: * <pre>
059: *
060: * Rights rights = folder.myRights();
061: *
062: * // Check if I can write this folder
063: * if (rights.contains(Rights.Right.WRITE))
064: * System.out.println("Can write folder");
065: *
066: * // Now give Joe all my rights, except the ability to write the folder
067: * rights.remove(Rights.Right.WRITE);
068: * ACL acl = new ACL("joe", rights);
069: * folder.setACL(acl);
070: * </pre>
071: * <p>
072: *
073: * @author Bill Shannon
074: */
075:
076: public class Rights implements Cloneable {
077:
078: private boolean[] rights = new boolean[128]; // XXX
079:
080: /**
081: * This inner class represents an individual right. A set
082: * of standard rights objects are predefined here.
083: */
084: public static final class Right {
085: private static Right[] cache = new Right[128];
086:
087: // XXX - initialization order?
088: /**
089: * Lookup - mailbox is visible to LIST/LSUB commands.
090: */
091: public static final Right LOOKUP = getInstance('l');
092:
093: /**
094: * Read - SELECT the mailbox, perform CHECK, FETCH, PARTIAL,
095: * SEARCH, COPY from mailbox
096: */
097: public static final Right READ = getInstance('r');
098:
099: /**
100: * Keep seen/unseen information across sessions - STORE \SEEN flag.
101: */
102: public static final Right KEEP_SEEN = getInstance('s');
103:
104: /**
105: * Write - STORE flags other than \SEEN and \DELETED.
106: */
107: public static final Right WRITE = getInstance('w');
108:
109: /**
110: * Insert - perform APPEND, COPY into mailbox.
111: */
112: public static final Right INSERT = getInstance('i');
113:
114: /**
115: * Post - send mail to submission address for mailbox,
116: * not enforced by IMAP4 itself.
117: */
118: public static final Right POST = getInstance('p');
119:
120: /**
121: * Create - CREATE new sub-mailboxes in any implementation-defined
122: * hierarchy, RENAME or DELETE mailbox.
123: */
124: public static final Right CREATE = getInstance('c');
125:
126: /**
127: * Delete - STORE \DELETED flag, perform EXPUNGE.
128: */
129: public static final Right DELETE = getInstance('d');
130:
131: /**
132: * Administer - perform SETACL.
133: */
134: public static final Right ADMINISTER = getInstance('a');
135:
136: char right; // the right represented by this Right object
137:
138: /**
139: * Private constructor used only by getInstance.
140: */
141: private Right(char right) {
142: if ((int) right >= 128)
143: throw new IllegalArgumentException(
144: "Right must be ASCII");
145: this .right = right;
146: }
147:
148: /**
149: * Get a Right object representing the specified character.
150: * Characters are assigned per RFC 2086.
151: */
152: public static synchronized Right getInstance(char right) {
153: if ((int) right >= 128)
154: throw new IllegalArgumentException(
155: "Right must be ASCII");
156: if (cache[(int) right] == null)
157: cache[(int) right] = new Right(right);
158: return cache[(int) right];
159: }
160:
161: public String toString() {
162: return String.valueOf(right);
163: }
164: }
165:
166: /**
167: * Construct an empty Rights object.
168: */
169: public Rights() {
170: }
171:
172: /**
173: * Construct a Rights object initialized with the given rights.
174: *
175: * @param rights the rights for initialization
176: */
177: public Rights(Rights rights) {
178: System.arraycopy(rights.rights, 0, this .rights, 0,
179: this .rights.length);
180: }
181:
182: /**
183: * Construct a Rights object initialized with the given rights.
184: *
185: * @param rights the rights for initialization
186: */
187: public Rights(String rights) {
188: for (int i = 0; i < rights.length(); i++)
189: add(Right.getInstance(rights.charAt(i)));
190: }
191:
192: /**
193: * Construct a Rights object initialized with the given right.
194: *
195: * @param right the right for initialization
196: */
197: public Rights(Right right) {
198: this .rights[(int) right.right] = true;
199: }
200:
201: /**
202: * Add the specified right to this Rights object.
203: *
204: * @param right the right to add
205: */
206: public void add(Right right) {
207: this .rights[(int) right.right] = true;
208: }
209:
210: /**
211: * Add all the rights in the given Rights object to this
212: * Rights object.
213: *
214: * @param rights Rights object
215: */
216: public void add(Rights rights) {
217: for (int i = 0; i < rights.rights.length; i++)
218: if (rights.rights[i])
219: this .rights[i] = true;
220: }
221:
222: /**
223: * Remove the specified right from this Rights object.
224: *
225: * @param right the right to be removed
226: */
227: public void remove(Right right) {
228: this .rights[(int) right.right] = false;
229: }
230:
231: /**
232: * Remove all rights in the given Rights object from this
233: * Rights object.
234: *
235: * @param rights the rights to be removed
236: */
237: public void remove(Rights rights) {
238: for (int i = 0; i < rights.rights.length; i++)
239: if (rights.rights[i])
240: this .rights[i] = false;
241: }
242:
243: /**
244: * Check whether the specified right is present in this Rights object.
245: *
246: * @return true of the given right is present, otherwise false.
247: */
248: public boolean contains(Right right) {
249: return this .rights[(int) right.right];
250: }
251:
252: /**
253: * Check whether all the rights in the specified Rights object are
254: * present in this Rights object.
255: *
256: * @return true if all rights in the given Rights object are present,
257: * otherwise false.
258: */
259: public boolean contains(Rights rights) {
260: for (int i = 0; i < rights.rights.length; i++)
261: if (rights.rights[i] && !this .rights[i])
262: return false;
263:
264: // If we've made it till here, return true
265: return true;
266: }
267:
268: /**
269: * Check whether the two Rights objects are equal.
270: *
271: * @return true if they're equal
272: */
273: public boolean equals(Object obj) {
274: if (!(obj instanceof Rights))
275: return false;
276:
277: Rights rights = (Rights) obj;
278:
279: for (int i = 0; i < rights.rights.length; i++)
280: if (rights.rights[i] != this .rights[i])
281: return false;
282:
283: return true;
284: }
285:
286: /**
287: * Compute a hash code for this Rights object.
288: *
289: * @return the hash code
290: */
291: public int hashCode() {
292: int hash = 0;
293: for (int i = 0; i < this .rights.length; i++)
294: if (this .rights[i])
295: hash++;
296: return hash;
297: }
298:
299: /**
300: * Return all the rights in this Rights object. Returns
301: * an array of size zero if no rights are set.
302: *
303: * @return array of Rights.Right objects representing rights
304: */
305: public Right[] getRights() {
306: Vector v = new Vector();
307: for (int i = 0; i < this .rights.length; i++)
308: if (this .rights[i])
309: v.addElement(Right.getInstance((char) i));
310: Right[] rights = new Right[v.size()];
311: v.copyInto(rights);
312: return rights;
313: }
314:
315: /**
316: * Returns a clone of this Rights object.
317: */
318: public Object clone() {
319: Rights r = null;
320: try {
321: r = (Rights) super .clone();
322: r.rights = new boolean[128];
323: System.arraycopy(this .rights, 0, r.rights, 0,
324: this .rights.length);
325: } catch (CloneNotSupportedException cex) {
326: // ignore, can't happen
327: }
328: return r;
329: }
330:
331: public String toString() {
332: StringBuffer sb = new StringBuffer();
333: for (int i = 0; i < this .rights.length; i++)
334: if (this .rights[i])
335: sb.append((char) i);
336: return sb.toString();
337: }
338:
339: /*****
340: public static void main(String argv[]) throws Exception {
341: // a new rights object
342: Rights f1 = new Rights();
343: f1.add(Rights.Right.READ);
344: f1.add(Rights.Right.WRITE);
345: f1.add(Rights.Right.CREATE);
346: f1.add(Rights.Right.DELETE);
347:
348: // check copy constructor
349: Rights fc = new Rights(f1);
350: if (f1.equals(fc) && fc.equals(f1))
351: System.out.println("success");
352: else
353: System.out.println("fail");
354:
355: // check clone
356: fc = (Rights)f1.clone();
357: if (f1.equals(fc) && fc.equals(f1))
358: System.out.println("success");
359: else
360: System.out.println("fail");
361:
362: // add a right and make sure it still works right
363: f1.add(Rights.Right.ADMINISTER);
364:
365: // shouldn't be equal here
366: if (!f1.equals(fc) && !fc.equals(f1))
367: System.out.println("success");
368: else
369: System.out.println("fail");
370:
371: // check clone
372: fc = (Rights)f1.clone();
373: if (f1.equals(fc) && fc.equals(f1))
374: System.out.println("success");
375: else
376: System.out.println("fail");
377:
378: fc.add(Rights.Right.INSERT);
379: if (!f1.equals(fc) && !fc.equals(f1))
380: System.out.println("success");
381: else
382: System.out.println("fail");
383:
384: // check copy constructor
385: fc = new Rights(f1);
386: if (f1.equals(fc) && fc.equals(f1))
387: System.out.println("success");
388: else
389: System.out.println("fail");
390:
391: // another new rights object
392: Rights f2 = new Rights(Rights.Right.READ);
393: f2.add(Rights.Right.WRITE);
394:
395: if (f1.contains(Rights.Right.READ))
396: System.out.println("success");
397: else
398: System.out.println("fail");
399:
400: if (f1.contains(Rights.Right.WRITE))
401: System.out.println("success");
402: else
403: System.out.println("fail");
404:
405: if (f1.contains(Rights.Right.CREATE))
406: System.out.println("success");
407: else
408: System.out.println("fail");
409:
410: if (f1.contains(Rights.Right.DELETE))
411: System.out.println("success");
412: else
413: System.out.println("fail");
414:
415: if (f2.contains(Rights.Right.WRITE))
416: System.out.println("success");
417: else
418: System.out.println("fail");
419:
420:
421: System.out.println("----------------");
422:
423: Right[] r = f1.getRights();
424: for (int i = 0; i < r.length; i++)
425: System.out.println(r[i]);
426: System.out.println("----------------");
427:
428: if (f1.contains(f2)) // this should be true
429: System.out.println("success");
430: else
431: System.out.println("fail");
432:
433: if (!f2.contains(f1)) // this should be false
434: System.out.println("success");
435: else
436: System.out.println("fail");
437:
438: Rights f3 = new Rights();
439: f3.add(Rights.Right.READ);
440: f3.add(Rights.Right.WRITE);
441: f3.add(Rights.Right.CREATE);
442: f3.add(Rights.Right.DELETE);
443: f3.add(Rights.Right.ADMINISTER);
444: f3.add(Rights.Right.LOOKUP);
445:
446: f1.add(Rights.Right.LOOKUP);
447:
448: if (f1.equals(f3))
449: System.out.println("equals success");
450: else
451: System.out.println("fail");
452: if (f3.equals(f1))
453: System.out.println("equals success");
454: else
455: System.out.println("fail");
456: System.out.println("f1 hash code " + f1.hashCode());
457: System.out.println("f3 hash code " + f3.hashCode());
458: if (f1.hashCode() == f3.hashCode())
459: System.out.println("success");
460: else
461: System.out.println("fail");
462: }
463: ****/
464: }
|