1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
19 package org.apache.geronimo.javamail.store.imap;
20 import java.util.Comparator;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.Iterator;
24 import java.util.Map;
25 import java.util.Set;
26 import java.util.SortedSet;
27 import java.util.TreeSet;
28
29 /**
30 * Represents a set of rights associated with a user to manipulate the
31 * IMAP Store.
32 */
33 public class Rights implements Cloneable {
34
35 /**
36 * An individual right for IMAP Store manipulation.
37 */
38 public static final class Right {
39 // The set of created stores. The getInstance() method ensures
40 // that each right is a singleton object.
41 static private Map rights = new HashMap();
42
43 /**
44 * lookup (mailbox is visible to LIST/LSUB commands)
45 */
46 public static final Right LOOKUP = getInstance('l');
47 /**
48 * read (SELECT the mailbox, perform CHECK, FETCH, PARTIAL,
49 * SEARCH, COPY from mailbox)
50 */
51 public static final Right READ = getInstance('r');
52 /**
53 * keep seen/unseen information across sessions (STORE SEEN flag)
54 */
55 public static final Right KEEP_SEEN = getInstance('s');
56 /**
57 * write (STORE flags other than SEEN and DELETED)
58 */
59 public static final Right WRITE = getInstance('w');
60 /**
61 * insert (perform APPEND, COPY into mailbox)
62 */
63 public static final Right INSERT = getInstance('i');
64 /**
65 * post (send mail to submission address for mailbox,
66 * not enforced by IMAP4 itself)
67 */
68 public static final Right POST = getInstance('p');
69 /**
70 * create (CREATE new sub-mailboxes in any implementation-defined
71 * hierarchy)
72 */
73 public static final Right CREATE = getInstance('c');
74 /**
75 * delete (STORE DELETED flag, perform EXPUNGE)
76 */
77 public static final Right DELETE = getInstance('d');
78 /**
79 * administer (perform SETACL)
80 */
81 public static final Right ADMINISTER = getInstance('a');
82
83 // the actual right definition
84 String right;
85
86 /**
87 * Private constructor for an individual Right. Used by getInstance().
88 *
89 * @param right The String name of the right (a single character).
90 */
91 private Right(String right) {
92 this.right = right;
93 }
94
95 /**
96 * Get an instance for a right from the single character right value. The
97 * returned instance will be a singleton for that character value.
98 *
99 * @param right The right character value.
100 *
101 * @return A Right instance that's the mapping for the character value.
102 */
103 public static synchronized Right getInstance(char right) {
104 String name = String.valueOf(right);
105 Right instance = (Right)rights.get(name);
106 if (instance == null) {
107 instance = new Right(name);
108 rights.put(name, instance);
109 }
110 return instance;
111 }
112
113 /**
114 * Return the string value of the Right. The string value is the character
115 * used to create the Right with newInstance().
116 *
117 * @return The string representation of the Right.
118 */
119 public String toString() {
120 return right;
121 }
122 }
123
124 /**
125 * The set of Rights contained in this instance. This is a TreeSet so that
126 * we can create the string value more consistently.
127 */
128 private SortedSet rights = new TreeSet(new RightComparator());
129
130 /**
131 * Construct an empty set of Rights.
132 */
133 public Rights() {
134 }
135
136 /**
137 * Construct a Rights set from a single Right instance.
138 *
139 * @param right The source Right.
140 */
141 public Rights(Right right) {
142 rights.add(right);
143 }
144
145 /**
146 * Construct a set of rights from an existing Rights set. This will copy
147 * the rights values.
148 *
149 * @param list The source Rights instance.
150 */
151 public Rights(Rights list) {
152 add(list);
153 Rights[] otherRights = list.getRights();
154 for (int i = 0; i < otherRights.length; i++) {
155 rights.add(otherRights[i]);
156 }
157 }
158
159 /**
160 * Construct a Rights et from a character string. Each character in the
161 * string represents an individual Right.
162 *
163 * @param list The source set of rights.
164 */
165 public Rights(String list) {
166 for (int i = 0; i < list.length(); i++) {
167 rights.add(Right.getInstance(list.charAt(i)));
168 }
169 }
170
171 /**
172 * Add a single Right to the set.
173 *
174 * @param right The new Right. If the Rigtht is already part of the Set, this is a nop.
175 */
176 public void add(Right right) {
177 rights.add(right);
178 }
179
180 /**
181 * Merge a Rights set with this set. Duplicates are eliminated.
182 *
183 * @param list The source for the added Rights.
184 */
185 public void add(Rights list) {
186 Rights[] otherRights = list.getRights();
187 for (int i = 0; i < otherRights.length; i++) {
188 rights.add(otherRights[i]);
189 }
190 }
191
192 /**
193 * Clone a set of Rights.
194 */
195 public Object clone() {
196 return new Rights(this);
197 }
198
199 /**
200 * Test if a Rights set contains a given Right.
201 *
202 * @param right The Right instance to test.
203 *
204 * @return true if the Right exists in the Set, false otherwise.
205 */
206 public boolean contains(Right right) {
207 return rights.contains(right);
208 }
209
210 /**
211 * Test if this Rights set contains all of the Rights contained in another
212 * set.
213 *
214 * @param list The source Rights set for the test.
215 *
216 * @return true if all of the Rights in the source set exist in the target set.
217 */
218 public boolean contains(Rights list) {
219 return rights.containsAll(list.rights);
220 }
221
222 /**
223 * Test if two Rights sets are equivalent.
224 *
225 * @param list The source rights set.
226 *
227 * @return true if both Rigths sets contain the same Rights values.
228 */
229 public boolean equals(Rights list) {
230 return rights.equals(list.rights);
231 }
232
233 /**
234 * Get an array of Rights contained in the set.
235 *
236 * @return An array of Rights[] values.
237 */
238 public Rights[] getRights() {
239 Rights[] list = new Rights[rights.size()];
240 return (Rights[])rights.toArray(list);
241 }
242
243 /**
244 * Compute a hashCode for the Rights set.
245 *
246 * @return The computed hashCode.
247 */
248 public int hashCode() {
249 return rights.hashCode();
250 }
251
252 /**
253 * Remove a Right from the set.
254 *
255 * @param right The single Right to remove.
256 */
257 public void remove(Right right) {
258 rights.remove(right);
259 }
260
261 /**
262 * Remove a set of rights from the set.
263 *
264 * @param list The list of rights to be removed.
265 */
266 public void remove(Rights list) {
267 rights.removeAll(list.rights);
268 }
269
270 /**
271 * Return a string value for the Rights set. The string value is the
272 * concatenation of the single-character Rights names.
273 *
274 * @return The string representation of this Rights set.
275 */
276 public String toString() {
277 StringBuffer buff = new StringBuffer();
278 Iterator i = rights.iterator();
279 while (i.hasNext()) {
280 buff.append(i.next().toString());
281 }
282 return buff.toString();
283 }
284
285 class RightComparator implements Comparator {
286 /**
287 * Perform a sort comparison to order two Right objects.
288 * The sort is performed using the string value.
289 *
290 * @param o1 The left comparator
291 * @param o2 The right comparator.
292 *
293 * @return 0 if the two items have equal ordering, -1 if the
294 * left item is lower, 1 if the left item is greater.
295 */
296 public int compare(Object o1, Object o2) {
297 // compare on the string value
298 String left = o1.toString();
299 return left.compareTo(o2.toString());
300 }
301 }
302
303 }