001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018
019 package org.apache.geronimo.javamail.store.imap;
020 import java.util.Comparator;
021 import java.util.HashMap;
022 import java.util.HashSet;
023 import java.util.Iterator;
024 import java.util.Map;
025 import java.util.Set;
026 import java.util.SortedSet;
027 import java.util.TreeSet;
028
029 /**
030 * Represents a set of rights associated with a user to manipulate the
031 * IMAP Store.
032 */
033 public class Rights implements Cloneable {
034
035 /**
036 * An individual right for IMAP Store manipulation.
037 */
038 public static final class Right {
039 // The set of created stores. The getInstance() method ensures
040 // that each right is a singleton object.
041 static private Map rights = new HashMap();
042
043 /**
044 * lookup (mailbox is visible to LIST/LSUB commands)
045 */
046 public static final Right LOOKUP = getInstance('l');
047 /**
048 * read (SELECT the mailbox, perform CHECK, FETCH, PARTIAL,
049 * SEARCH, COPY from mailbox)
050 */
051 public static final Right READ = getInstance('r');
052 /**
053 * keep seen/unseen information across sessions (STORE SEEN flag)
054 */
055 public static final Right KEEP_SEEN = getInstance('s');
056 /**
057 * write (STORE flags other than SEEN and DELETED)
058 */
059 public static final Right WRITE = getInstance('w');
060 /**
061 * insert (perform APPEND, COPY into mailbox)
062 */
063 public static final Right INSERT = getInstance('i');
064 /**
065 * post (send mail to submission address for mailbox,
066 * not enforced by IMAP4 itself)
067 */
068 public static final Right POST = getInstance('p');
069 /**
070 * create (CREATE new sub-mailboxes in any implementation-defined
071 * hierarchy)
072 */
073 public static final Right CREATE = getInstance('c');
074 /**
075 * delete (STORE DELETED flag, perform EXPUNGE)
076 */
077 public static final Right DELETE = getInstance('d');
078 /**
079 * administer (perform SETACL)
080 */
081 public static final Right ADMINISTER = getInstance('a');
082
083 // the actual right definition
084 String right;
085
086 /**
087 * Private constructor for an individual Right. Used by getInstance().
088 *
089 * @param right The String name of the right (a single character).
090 */
091 private Right(String right) {
092 this.right = right;
093 }
094
095 /**
096 * Get an instance for a right from the single character right value. The
097 * returned instance will be a singleton for that character value.
098 *
099 * @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 }